Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "VideoDecoderSimple.h"
- CVideoDecoderSimple::CVideoDecoderSimple(AVCodecID decoder)
- {
- avcodec_register_all();
- av_register_all();
- av_log_set_level(AV_LOG_DEBUG);
- m_pCodec = avcodec_find_decoder(decoder);
- m_pCodecCtx = avcodec_alloc_context3(m_pCodec);
- if (m_pCodecCtx)
- {
- if (m_pCodec->capabilities & CODEC_CAP_TRUNCATED)
- m_pCodecCtx->flags |= CODEC_FLAG_TRUNCATED;
- m_pCodecCtx->thread_count = 4;
- m_pCodecCtx->thread_type = FF_THREAD_FRAME;
- }
- avcodec_open2(m_pCodecCtx, m_pCodec, 0);
- m_pFrameDecoded = av_frame_alloc();
- frameDecoded = false;
- }
- CVideoDecoderSimple::~CVideoDecoderSimple()
- {
- av_free(m_pFrameDecoded);
- avcodec_close(m_pCodecCtx);
- avformat_network_deinit();
- }
- bool CVideoDecoderSimple::DecodeStreamData(unsigned char * pData, size_t sz)
- {
- AVPacket packet;
- av_init_packet(&packet);
- packet.data = pData;
- packet.size = (int)sz;
- int framefinished = 0;
- avcodec_send_packet(m_pCodecCtx, &packet);
- if (avcodec_receive_frame(m_pCodecCtx, m_pFrameDecoded) == 0)
- {
- frameDecoded = true;
- ConvertToRGBA();
- return true;
- }
- return false;
- }
- void CVideoDecoderSimple::ConvertToRGBA()
- {
- AVPixelFormat destinationFormat = AV_PIX_FMT_RGBA;
- // AVPixelFormat sourceFormat = AV_PIX_FMT_YUV420P; //AV_PIX_FMT_NV12;
- // LOG_DEBUG("Converting Frame!");
- if (this->imageConvertContext == NULL)
- {
- // LOG_DEBUG("Reset image convert context");
- // Allocate pictures and buffers for conversion
- this->imageConvertContext = sws_getContext(
- m_pCodecCtx->width,
- m_pCodecCtx->height,
- m_pCodecCtx->pix_fmt,
- m_pCodecCtx->width,
- m_pCodecCtx->height,
- destinationFormat,
- SWS_BICUBIC,
- NULL, NULL, NULL);
- }
- // NOTICE: It is generally not a good practice to allocate on demand instead on initialization.
- // It this case the edge cases demand it (what happens if width==0 on the first packet?)
- if (this->m_pRGBAFrame == NULL)
- {
- // LOG_DEBUG("Reset converted pic");
- int size_rgba = av_image_get_buffer_size(destinationFormat, m_pCodecCtx->width, m_pCodecCtx->height, 32);
- this->m_pRGBAFrameBuffer= (uint8_t*)(av_malloc(size_rgba));
- this->m_pRGBAFrame = av_frame_alloc();
- // avpicture_fill((AVPicture*)convertedPic, convertedPicBuffer, destinationFormat, width, height);
- av_image_fill_arrays(
- this->m_pRGBAFrame->data,
- this->m_pRGBAFrame->linesize,
- this->m_pRGBAFrameBuffer,
- destinationFormat,
- this->m_pCodecCtx->width,
- this->m_pCodecCtx->height,
- 32);
- }
- // This is the conversion. We could scale here if we wanted to
- sws_scale(imageConvertContext, this->m_pFrameDecoded->data, m_pFrameDecoded->linesize, 0, m_pCodecCtx->height, m_pRGBAFrame->data, m_pRGBAFrame->linesize);
- m_pRGBAFrame->width = this->m_pCodecCtx->width;
- m_pRGBAFrame->height = this->m_pCodecCtx->height;
- }
- void CVideoDecoderSimple::GetLastFrame(unsigned char** frame, unsigned int* width, unsigned int* height)
- {
- if (frameDecoded)
- {
- //*frame = m_pFrameDecoded->data[0];
- *frame = m_pRGBAFrame->data[0];
- *width = m_pRGBAFrame->width;
- *height = m_pRGBAFrame->height;
- frameDecoded = false;
- }
- else
- {
- *frame = NULL;
- *width = 0;
- *height = 0;
- }
- }
Add Comment
Please, Sign In to add comment