利用ffmpeg将H264解码为RGB

由于公司买到了一个不提供解码器的设备,我不得已还要做解码的工作。在网上找了一圈,

利用H264解码分为几个步骤:

注意一点在添加头文件的时候要添加extern "C",不然会出现错误

extern "C"{#include <avcodec.h>#include <avformat.h>#include <avutil.h>#include <swscale.h>};

这里申明了几个全局变量

AVCodec*pCodec = NULL;AVCodecContext *pCodecCtx = NULL;SwsContext*img_convert_ctx = NULL;AVFrame*pFrame = NULL;AVFrame*pFrameRGB = NULL;

1.初始化

int H264_Init(void){/* must be called before using avcodec lib*/avcodec_init();/* register all the codecs */avcodec_register_all();/* find the h264 video decoder */pCodec = avcodec_find_decoder(CODEC_ID_H264);if (!pCodec) {fprintf(stderr, "codec not found\n");}pCodecCtx = avcodec_alloc_context();/* open the coderc */if (avcodec_open(pCodecCtx, pCodec) < 0) {fprintf(stderr, "could not open codec\n");}// Allocate video framepFrame = avcodec_alloc_frame();if(pFrame == NULL)return -1;// Allocate an AVFrame structurepFrameRGB=avcodec_alloc_frame();if(pFrameRGB == NULL)return -1;return 0;}

在最早使用的时候没有使用全局变量,初始化中也就只有init和regisger这两个函数,而这样做的下场是,非关键帧全部无法解码,只有关键帧才有办法解码。

2.解码

解码的时候avcodec_decode_video函数是进行解码操作,在外部定义outputbuf的大小时,pixes*3,outsize是返回的outputbuf的size,值也是pixes*3。

在解码的时候这几句话的意义是将YUV420P的数据倒置。在原先使用中,,发现解出来的图像居然是中心旋转图,后面在网上找了些办法,觉得这个比较实用。解码实时是很重要的,图像转化完之后也可以讲RGB图再次转化,那样也能成为一个正的图,但是那样效率就明显低了。

pFrame->data[0] += pFrame->linesize[0] * (pCodecCtx->height-1);pFrame->linesize[0] *= -1;pFrame->data[1] += pFrame->linesize[1] * (pCodecCtx->height/2 – 1);;pFrame->linesize[1] *= -1;pFrame->data[2] += pFrame->linesize[2] * (pCodecCtx->height/2 – 1);;pFrame->linesize[2] *= -1;

int H264_2_RGB(unsigned char *inputbuf, int frame_size, unsigned char *outputbuf, unsigned int*outsize){intdecode_size;intnumBytes;intav_result;uint8_t*buffer = NULL;printf("Video decoding\n");av_result = avcodec_decode_video(pCodecCtx, pFrame, &decode_size, inputbuf, frame_size);if (av_result < 0){fprintf(stderr, "decode failed: inputbuf = 0x%x , input_framesize = %d\n", inputbuf, frame_size);return -1;}// Determine required buffer size and allocate buffernumBytes=avpicture_get_size(PIX_FMT_BGR24, pCodecCtx->width,pCodecCtx->height);buffer = (uint8_t*)malloc(numBytes * sizeof(uint8_t));// Assign appropriate parts of buffer to image planes in pFrameRGBavpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_BGR24,pCodecCtx->width, pCodecCtx->height);img_convert_ctx = sws_getCachedContext(img_convert_ctx,pCodecCtx->width,pCodecCtx->height,//PIX_FMT_YUV420P,pCodecCtx->width,pCodecCtx->height,pCodecCtx->pix_fmt,pCodecCtx->pix_fmt,pCodecCtx->width,pCodecCtx->height,PIX_FMT_RGB24 ,SWS_X ,NULL,NULL,NULL) ;if (img_convert_ctx == NULL) {printf("can’t init convert context!\n") ;return -1;}pFrame->data[0] += pFrame->linesize[0] * (pCodecCtx->height-1);pFrame->linesize[0] *= -1;pFrame->data[1] += pFrame->linesize[1] * (pCodecCtx->height/2 – 1);;pFrame->linesize[1] *= -1;pFrame->data[2] += pFrame->linesize[2] * (pCodecCtx->height/2 – 1);;pFrame->linesize[2] *= -1;sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize,0, 0 – pCodecCtx->width, pFrameRGB->data, pFrameRGB->linesize);if (decode_size){*outsize = pCodecCtx->width * pCodecCtx->height * 3;memcpy(outputbuf, pFrameRGB->data[0], *outsize);}free(buffer);return 0;}

3. 释放资源

资源的回收。

void H264_Release(void){avcodec_close(pCodecCtx);av_free(pCodecCtx);av_free(pFrame);av_free(pFrameRGB);}

版权声明:本文为博主原创文章,未经博主允许不得转载。

哪里会顾得上这些。等到时间将矛盾一层层降解为流言是非误解过结

利用ffmpeg将H264解码为RGB

相关文章:

你感兴趣的文章:

标签云: