Advertisement
Guest User

Untitled

a guest
Oct 16th, 2013
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.79 KB | None | 0 0
  1. #define MAX_FRAME_SIZE                          2097152 // 2MB
  2.  
  3. #ifdef X_DECODER
  4.     #define CODEC_DECODER                       CODEC_ID_H264
  5.  
  6.     #define YUV_FORMAT_SWSCALE      PIX_FMT_YUV420P
  7.     #define SCALING_ALGORITHM                       SWS_FAST_BILINEAR
  8.     #define YUV_FORMAT_SWSCALE                      PIX_FMT_YUV420P
  9.     #define RGB_FORMAT                              PIX_FMT_RGB24
  10. #endif
  11.  
  12. codec264::codec264(void)
  13. :codec("codec264")
  14. {
  15.     mpByteArray = NULL;
  16.     mvByteArrayCreatedByThisObject = true;
  17.  
  18.     Framebuffersize = 0;
  19.     Framebuffer = (uint8_t *) malloc(MAX_FRAME_SIZE);
  20.     if (Framebuffer == NULL)
  21.     {
  22.         gpLogErr("H264: Error in memory allocation-Framebuffer.");
  23.         return;
  24.     }
  25.  
  26.     #ifdef X_DECODER
  27.         codec = NULL;
  28.         av_pic = NULL;
  29.         avFrameRGB = NULL;
  30.         c1 = NULL;
  31.         if(!smvAvCodecInitialized)
  32.         {
  33.             avcodec_register_all();
  34.             smvAvCodecInitialized = true;
  35.         }
  36.         convertCtxDec = NULL;
  37.         mvDecoderInitialized=false;
  38.         videobps=0;
  39.         InitializedWidth = -1;
  40.         InitializedHeight = -1;
  41.     #endif
  42. }
  43.  
  44. codec264::~codec264()
  45. {
  46.     if(Framebuffer)
  47.         free(Framebuffer);
  48.     if(mvByteArrayCreatedByThisObject)
  49.         delete (mpByteArray);
  50.     #ifdef X_DECODER
  51.     mpDeinitDecoder();
  52.     #endif
  53. }
  54.  
  55. void codec264::mpSetByteArray(QByteArray *apByteArray)
  56. {
  57.     if(mvByteArrayCreatedByThisObject&&mpByteArray)
  58.     {
  59.         delete (mpByteArray);
  60.         mpByteArray = NULL;
  61.     }
  62.     mpByteArray = apByteArray;
  63.     if(mpByteArray)
  64.         mvByteArrayCreatedByThisObject = false;
  65.     else
  66.     {
  67.         mpByteArray = new QByteArray();
  68.         mvByteArrayCreatedByThisObject = true;
  69.     }
  70. }
  71.  
  72. const QByteArray *codec264::mfGetByteArray(void) const
  73. {
  74.     return (mpByteArray);
  75. }
  76.  
  77. #ifdef X_DECODER
  78. void codec264::mpInitDecoder(int aWidth, int aHeight)
  79. {
  80.     mpDeinitDecoder();
  81.  
  82.     InitializedWidth = aWidth;
  83.     InitializedHeight = aHeight;
  84.  
  85.     avFrameRGB= avcodec_alloc_frame();
  86.     if(avFrameRGB == NULL)
  87.     {
  88.         mpDeinitDecoder();
  89.         gpLogDebug("H264: Memory for RGB picture could not be allocated.");
  90.         return;
  91.     }
  92.  
  93.     convertCtxDec = sws_getContext(aWidth, aHeight, YUV_FORMAT_SWSCALE, aWidth, aHeight, PIX_FMT_RGB32, SCALING_ALGORITHM, NULL, NULL, NULL);
  94.     if (convertCtxDec == NULL)
  95.     {
  96.         gpLogDebug("H264: Swscale could not get the context.");
  97.         mpDeinitDecoder();
  98.         return;
  99.     }
  100.  
  101.     av_pic = avcodec_alloc_frame();
  102.     if(av_pic == NULL)
  103.     {
  104.         gpLogDebug("H264: Memory for YUV picture could not be allocated.");
  105.         mpDeinitDecoder();
  106.         return;
  107.     }
  108.  
  109.     codec = avcodec_find_decoder(CODEC_DECODER);
  110.     if (!codec)
  111.     {
  112.         gpLogDebug("H264: Codec not found.");
  113.         mpDeinitDecoder();
  114.         return;
  115.     }
  116.  
  117.     c1 = avcodec_alloc_context3(codec);
  118.     if(c1 == NULL)
  119.     {
  120.         gpLogDebug("H264: avcodec_alloc_context3 failed.");
  121.         mpDeinitDecoder();
  122.         return;
  123.     }
  124.  
  125.     c1->width = aWidth;
  126.     c1->height = aHeight;
  127.     c1->codec_id = CODEC_DECODER;
  128.     c1->codec_type = AVMEDIA_TYPE_VIDEO;
  129.  
  130.  
  131.     /* open it */
  132.     QMutexLocker locker(&smvCodecOpenCloseMutex);
  133.     if (avcodec_open2(c1, codec, NULL) < 0)
  134.     {
  135.         mpDeinitDecoder();
  136.         gpLogDebug("H264: Could not open the codec.");
  137.         return;
  138.     }
  139.  
  140.     mvDecoderInitialized = true;
  141. }
  142.  
  143. void codec264::mpDeinitDecoder(void)
  144. {
  145.     if(avFrameRGB)
  146.     {
  147.         avcodec_free_frame(&avFrameRGB);
  148.         avFrameRGB = NULL;
  149.     }
  150.     if(av_pic)
  151.     {
  152.         avcodec_free_frame(&av_pic);
  153.         av_pic = NULL;
  154.     }
  155.     if(convertCtxDec)
  156.     {
  157.         sws_freeContext(convertCtxDec);
  158.         convertCtxDec = NULL;
  159.     }
  160.     if(c1)
  161.     {
  162.         QMutexLocker locker(&smvCodecOpenCloseMutex);
  163.         int ret = avcodec_close(c1);
  164.         if(ret!=0)
  165.         {
  166.             gpLogWarning(QString("Error %1 in avcodec_close.").arg(ret));
  167.         }
  168.         av_free(c1);
  169.         c1 = NULL;
  170.     }
  171.     mvDecoderInitialized = false;
  172. }
  173.  
  174. void codec264::mpDecodeNewFrame(QByteArray *apDataBlock, QImage *apImage, QRegion &avDiffRegions, QRegion aMask)
  175. {
  176.     quint64 dataSize(0);
  177.     QDataStream inStream(apDataBlock, QIODevice::ReadOnly);
  178.  
  179.     // Read timestamp.
  180.     inStream >> mvTimeStamp;
  181.  
  182.     // Read size.
  183.     inStream >> mvSize[0];
  184.     inStream >> mvSize[1];
  185.  
  186.     // Resize apImage if needed.
  187.     if((apImage->width()!=mvSize[0])||(apImage->height()!=mvSize[1]))
  188.     {
  189.         (*apImage) = QImage(mvSize[0], mvSize[1], QImage::Format_RGB32);
  190.         apImage->fill(Qt::black);
  191.     }
  192.  
  193.     inStream >> dataSize;
  194.  
  195.     memset(Framebuffer+dataSize, 0, FF_INPUT_BUFFER_PADDING_SIZE);
  196.     inStream.readRawData((char *)Framebuffer, dataSize);
  197.  
  198.     if(((apImage->width()!=mvSize[0])||(apImage->height()!=mvSize[1]))&&((0!=apImage->width())||(0!=apImage->height())))
  199.         mpDeinitDecoder();
  200.  
  201.     if(InitializedWidth != mvSize[0] || InitializedHeight != mvSize[1])
  202.         mpDeinitDecoder();
  203.  
  204.     if(!mvDecoderInitialized)
  205.         mpInitDecoder(mvSize[0], mvSize[1]);
  206.  
  207.     decoderDecodeFrame(Framebuffer, apImage, dataSize, mvSize[0], mvSize[1]);
  208. }
  209.  
  210. //Return 1 if the frame is fully decoded and decoded without error, else 0
  211. int codec264::decoderDecodeFrame(uint8_t* buffer, QImage *apImage, int buffersize, qint16 aWidth, qint16 aHeight)
  212. {
  213.     int got_picture = 0, lenDecoded;
  214.  
  215.     av_init_packet(&pkt);
  216.  
  217.     pkt.data=buffer;
  218.     pkt.size=buffersize;    
  219.  
  220.     lenDecoded = avcodec_decode_video2(c1, av_pic, &got_picture, &pkt);
  221.  
  222.     if (lenDecoded < 0)
  223.     {
  224.         gpLogDebug("H264: Error while decoding frame");
  225.         av_free_packet(&pkt);
  226.         return 0;
  227.     }
  228.  
  229.     if (got_picture)
  230.     {
  231.         mpYUV420toRGB32(apImage, av_pic, aWidth, aHeight);
  232.         av_free_packet(&pkt);
  233.         return 1;
  234.     }
  235.     gpLogWarning("[codec264::decoderDecodeFrame] lenDecoded>=0 && !got_picture");
  236.     av_free_packet(&pkt);
  237.     return 0;
  238. }
  239.  
  240. void codec264::mpYUV420toRGB32(QImage *apImage, AVFrame *decodedpic,qint16 aWidth, qint16 aHeight)
  241. {
  242.     int rtControl;
  243.     rtControl = avpicture_fill((AVPicture *)avFrameRGB, apImage->constBits(), PIX_FMT_RGB32, aWidth, aHeight);
  244.     if(rtControl <0)
  245.     {
  246.         gpLogDebug("H264: Problem occured during avpicture_fill.");
  247.         return;
  248.     }
  249.  
  250.     convertCtxDec = sws_getCachedContext(convertCtxDec, decodedpic->width, decodedpic->height, PIX_FMT_YUV420P, aWidth, aHeight, PIX_FMT_RGB32, SCALING_ALGORITHM, NULL, NULL, NULL);
  251.  
  252.     rtControl = sws_scale(convertCtxDec, decodedpic->data, decodedpic->linesize, 0, aHeight, avFrameRGB->data, avFrameRGB->linesize);
  253.     if(rtControl == 0)
  254.     {
  255.         gpLogDebug("H264: Problem occured during swscale.");
  256.         return;
  257.     }
  258. }
  259. #endif
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement