Guest User

Decoder Example

a guest
Nov 24th, 2016
103
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.21 KB | None | 0 0
  1. #include "VideoDecoderSimple.h"
  2.  
  3. CVideoDecoderSimple::CVideoDecoderSimple(AVCodecID decoder)
  4. {
  5.     avcodec_register_all();
  6.     av_register_all();
  7.     av_log_set_level(AV_LOG_DEBUG);
  8.  
  9.     m_pCodec = avcodec_find_decoder(decoder);
  10.     m_pCodecCtx = avcodec_alloc_context3(m_pCodec);
  11.  
  12.     if (m_pCodecCtx)
  13.     {
  14.         if (m_pCodec->capabilities & CODEC_CAP_TRUNCATED)
  15.             m_pCodecCtx->flags |= CODEC_FLAG_TRUNCATED;
  16.  
  17.         m_pCodecCtx->thread_count = 4;
  18.         m_pCodecCtx->thread_type = FF_THREAD_FRAME;
  19.     }
  20.  
  21.     avcodec_open2(m_pCodecCtx, m_pCodec, 0);
  22.     m_pFrameDecoded = av_frame_alloc();
  23.  
  24.     frameDecoded = false;
  25. }
  26.  
  27. CVideoDecoderSimple::~CVideoDecoderSimple()
  28. {
  29.     av_free(m_pFrameDecoded);
  30.     avcodec_close(m_pCodecCtx);
  31.  
  32.     avformat_network_deinit();
  33. }
  34.  
  35. bool CVideoDecoderSimple::DecodeStreamData(unsigned char * pData, size_t sz)
  36. {
  37.     AVPacket        packet;
  38.     av_init_packet(&packet);
  39.  
  40.     packet.data = pData;
  41.     packet.size = (int)sz;
  42.     int framefinished = 0;
  43.     avcodec_send_packet(m_pCodecCtx, &packet);
  44.     if (avcodec_receive_frame(m_pCodecCtx, m_pFrameDecoded) == 0)
  45.     {
  46.         frameDecoded = true;
  47.  
  48.         ConvertToRGBA();
  49.  
  50.         return true;
  51.     }
  52.  
  53.     return false;
  54. }
  55.  
  56. void CVideoDecoderSimple::ConvertToRGBA()
  57. {
  58.     AVPixelFormat destinationFormat = AV_PIX_FMT_RGBA;
  59. //  AVPixelFormat sourceFormat = AV_PIX_FMT_YUV420P; //AV_PIX_FMT_NV12;
  60.                                                      //     LOG_DEBUG("Converting Frame!");
  61.  
  62.     if (this->imageConvertContext == NULL)
  63.     {
  64.         //      LOG_DEBUG("Reset image convert context");
  65.         // Allocate pictures and buffers for conversion
  66.         this->imageConvertContext = sws_getContext(
  67.             m_pCodecCtx->width,
  68.             m_pCodecCtx->height,
  69.             m_pCodecCtx->pix_fmt,
  70.             m_pCodecCtx->width,
  71.             m_pCodecCtx->height,
  72.             destinationFormat,
  73.             SWS_BICUBIC,
  74.             NULL, NULL, NULL);
  75.     }
  76.  
  77.     // NOTICE: It is generally not a good practice to allocate on demand instead on initialization.
  78.     // It this case the edge cases demand it (what happens if width==0 on the first packet?)
  79.     if (this->m_pRGBAFrame == NULL)
  80.     {
  81.         //      LOG_DEBUG("Reset converted pic");
  82.         int size_rgba = av_image_get_buffer_size(destinationFormat, m_pCodecCtx->width, m_pCodecCtx->height, 32);
  83.         this->m_pRGBAFrameBuffer= (uint8_t*)(av_malloc(size_rgba));
  84.         this->m_pRGBAFrame = av_frame_alloc();
  85.         //      avpicture_fill((AVPicture*)convertedPic, convertedPicBuffer, destinationFormat, width, height);
  86.         av_image_fill_arrays(
  87.             this->m_pRGBAFrame->data,
  88.             this->m_pRGBAFrame->linesize,
  89.             this->m_pRGBAFrameBuffer,
  90.             destinationFormat,
  91.             this->m_pCodecCtx->width,
  92.             this->m_pCodecCtx->height,
  93.             32);
  94.     }
  95.  
  96.     // This is the conversion. We could scale here if we wanted to
  97.     sws_scale(imageConvertContext, this->m_pFrameDecoded->data, m_pFrameDecoded->linesize, 0, m_pCodecCtx->height, m_pRGBAFrame->data, m_pRGBAFrame->linesize);
  98.     m_pRGBAFrame->width = this->m_pCodecCtx->width;
  99.     m_pRGBAFrame->height = this->m_pCodecCtx->height;
  100.  
  101. }
  102.  
  103. void CVideoDecoderSimple::GetLastFrame(unsigned char** frame, unsigned int* width, unsigned int* height)
  104. {
  105.     if (frameDecoded)
  106.     {
  107.         //*frame = m_pFrameDecoded->data[0];
  108.         *frame = m_pRGBAFrame->data[0];
  109.         *width = m_pRGBAFrame->width;
  110.         *height = m_pRGBAFrame->height;
  111.         frameDecoded = false;
  112.     }
  113.     else
  114.     {
  115.         *frame = NULL;
  116.         *width = 0;
  117.         *height = 0;
  118.     }
  119. }
Add Comment
Please, Sign In to add comment