Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define MAX_FRAME_SIZE 2097152 // 2MB
- #ifdef X_DECODER
- #define CODEC_DECODER CODEC_ID_H264
- #define YUV_FORMAT_SWSCALE PIX_FMT_YUV420P
- #define SCALING_ALGORITHM SWS_FAST_BILINEAR
- #define YUV_FORMAT_SWSCALE PIX_FMT_YUV420P
- #define RGB_FORMAT PIX_FMT_RGB24
- #endif
- codec264::codec264(void)
- :codec("codec264")
- {
- mpByteArray = NULL;
- mvByteArrayCreatedByThisObject = true;
- Framebuffersize = 0;
- Framebuffer = (uint8_t *) malloc(MAX_FRAME_SIZE);
- if (Framebuffer == NULL)
- {
- gpLogErr("H264: Error in memory allocation-Framebuffer.");
- return;
- }
- #ifdef X_DECODER
- codec = NULL;
- av_pic = NULL;
- avFrameRGB = NULL;
- c1 = NULL;
- if(!smvAvCodecInitialized)
- {
- avcodec_register_all();
- smvAvCodecInitialized = true;
- }
- convertCtxDec = NULL;
- mvDecoderInitialized=false;
- videobps=0;
- InitializedWidth = -1;
- InitializedHeight = -1;
- #endif
- }
- codec264::~codec264()
- {
- if(Framebuffer)
- free(Framebuffer);
- if(mvByteArrayCreatedByThisObject)
- delete (mpByteArray);
- #ifdef X_DECODER
- mpDeinitDecoder();
- #endif
- }
- void codec264::mpSetByteArray(QByteArray *apByteArray)
- {
- if(mvByteArrayCreatedByThisObject&&mpByteArray)
- {
- delete (mpByteArray);
- mpByteArray = NULL;
- }
- mpByteArray = apByteArray;
- if(mpByteArray)
- mvByteArrayCreatedByThisObject = false;
- else
- {
- mpByteArray = new QByteArray();
- mvByteArrayCreatedByThisObject = true;
- }
- }
- const QByteArray *codec264::mfGetByteArray(void) const
- {
- return (mpByteArray);
- }
- #ifdef X_DECODER
- void codec264::mpInitDecoder(int aWidth, int aHeight)
- {
- mpDeinitDecoder();
- InitializedWidth = aWidth;
- InitializedHeight = aHeight;
- avFrameRGB= avcodec_alloc_frame();
- if(avFrameRGB == NULL)
- {
- mpDeinitDecoder();
- gpLogDebug("H264: Memory for RGB picture could not be allocated.");
- return;
- }
- convertCtxDec = sws_getContext(aWidth, aHeight, YUV_FORMAT_SWSCALE, aWidth, aHeight, PIX_FMT_RGB32, SCALING_ALGORITHM, NULL, NULL, NULL);
- if (convertCtxDec == NULL)
- {
- gpLogDebug("H264: Swscale could not get the context.");
- mpDeinitDecoder();
- return;
- }
- av_pic = avcodec_alloc_frame();
- if(av_pic == NULL)
- {
- gpLogDebug("H264: Memory for YUV picture could not be allocated.");
- mpDeinitDecoder();
- return;
- }
- codec = avcodec_find_decoder(CODEC_DECODER);
- if (!codec)
- {
- gpLogDebug("H264: Codec not found.");
- mpDeinitDecoder();
- return;
- }
- c1 = avcodec_alloc_context3(codec);
- if(c1 == NULL)
- {
- gpLogDebug("H264: avcodec_alloc_context3 failed.");
- mpDeinitDecoder();
- return;
- }
- c1->width = aWidth;
- c1->height = aHeight;
- c1->codec_id = CODEC_DECODER;
- c1->codec_type = AVMEDIA_TYPE_VIDEO;
- /* open it */
- QMutexLocker locker(&smvCodecOpenCloseMutex);
- if (avcodec_open2(c1, codec, NULL) < 0)
- {
- mpDeinitDecoder();
- gpLogDebug("H264: Could not open the codec.");
- return;
- }
- mvDecoderInitialized = true;
- }
- void codec264::mpDeinitDecoder(void)
- {
- if(avFrameRGB)
- {
- avcodec_free_frame(&avFrameRGB);
- avFrameRGB = NULL;
- }
- if(av_pic)
- {
- avcodec_free_frame(&av_pic);
- av_pic = NULL;
- }
- if(convertCtxDec)
- {
- sws_freeContext(convertCtxDec);
- convertCtxDec = NULL;
- }
- if(c1)
- {
- QMutexLocker locker(&smvCodecOpenCloseMutex);
- int ret = avcodec_close(c1);
- if(ret!=0)
- {
- gpLogWarning(QString("Error %1 in avcodec_close.").arg(ret));
- }
- av_free(c1);
- c1 = NULL;
- }
- mvDecoderInitialized = false;
- }
- void codec264::mpDecodeNewFrame(QByteArray *apDataBlock, QImage *apImage, QRegion &avDiffRegions, QRegion aMask)
- {
- quint64 dataSize(0);
- QDataStream inStream(apDataBlock, QIODevice::ReadOnly);
- // Read timestamp.
- inStream >> mvTimeStamp;
- // Read size.
- inStream >> mvSize[0];
- inStream >> mvSize[1];
- // Resize apImage if needed.
- if((apImage->width()!=mvSize[0])||(apImage->height()!=mvSize[1]))
- {
- (*apImage) = QImage(mvSize[0], mvSize[1], QImage::Format_RGB32);
- apImage->fill(Qt::black);
- }
- inStream >> dataSize;
- memset(Framebuffer+dataSize, 0, FF_INPUT_BUFFER_PADDING_SIZE);
- inStream.readRawData((char *)Framebuffer, dataSize);
- if(((apImage->width()!=mvSize[0])||(apImage->height()!=mvSize[1]))&&((0!=apImage->width())||(0!=apImage->height())))
- mpDeinitDecoder();
- if(InitializedWidth != mvSize[0] || InitializedHeight != mvSize[1])
- mpDeinitDecoder();
- if(!mvDecoderInitialized)
- mpInitDecoder(mvSize[0], mvSize[1]);
- decoderDecodeFrame(Framebuffer, apImage, dataSize, mvSize[0], mvSize[1]);
- }
- //Return 1 if the frame is fully decoded and decoded without error, else 0
- int codec264::decoderDecodeFrame(uint8_t* buffer, QImage *apImage, int buffersize, qint16 aWidth, qint16 aHeight)
- {
- int got_picture = 0, lenDecoded;
- av_init_packet(&pkt);
- pkt.data=buffer;
- pkt.size=buffersize;
- lenDecoded = avcodec_decode_video2(c1, av_pic, &got_picture, &pkt);
- if (lenDecoded < 0)
- {
- gpLogDebug("H264: Error while decoding frame");
- av_free_packet(&pkt);
- return 0;
- }
- if (got_picture)
- {
- mpYUV420toRGB32(apImage, av_pic, aWidth, aHeight);
- av_free_packet(&pkt);
- return 1;
- }
- gpLogWarning("[codec264::decoderDecodeFrame] lenDecoded>=0 && !got_picture");
- av_free_packet(&pkt);
- return 0;
- }
- void codec264::mpYUV420toRGB32(QImage *apImage, AVFrame *decodedpic,qint16 aWidth, qint16 aHeight)
- {
- int rtControl;
- rtControl = avpicture_fill((AVPicture *)avFrameRGB, apImage->constBits(), PIX_FMT_RGB32, aWidth, aHeight);
- if(rtControl <0)
- {
- gpLogDebug("H264: Problem occured during avpicture_fill.");
- return;
- }
- convertCtxDec = sws_getCachedContext(convertCtxDec, decodedpic->width, decodedpic->height, PIX_FMT_YUV420P, aWidth, aHeight, PIX_FMT_RGB32, SCALING_ALGORITHM, NULL, NULL, NULL);
- rtControl = sws_scale(convertCtxDec, decodedpic->data, decodedpic->linesize, 0, aHeight, avFrameRGB->data, avFrameRGB->linesize);
- if(rtControl == 0)
- {
- gpLogDebug("H264: Problem occured during swscale.");
- return;
- }
- }
- #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement