ffmpeg h264解码器提取

2022-07-04 09:21:11 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

ffmpeg包含了很多的音视频解码器,本文试图通过对ffmpeg的简单分析提取h264解码器.

使用ffmpeg解码可以参考ffmpeg源码下的doc/examples/decoding_encoding.c

1.首先设置解码器参数( avcodec_find_decoder(CODEC_ID_H264)

将decode函数指针为 h264_decoder, 即

AVCodec ff_h264_decoder = {

.name = “h264”,

.type = AVMEDIA_TYPE_VIDEO,

.id = CODEC_ID_H264,

.priv_data_size = sizeof(H264Context),

.init = ff_h264_decode_init,

.close = ff_h264_decode_end,

.decode = decode_frame,

.capabilities = /*CODEC_CAP_DRAW_HORIZ_BAND |*/ CODEC_CAP_DR1 | CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS | CODEC_CAP_FRAME_THREADS,

.flush= flush_dpb,

.long_name = NULL_IF_CONFIG_SMALL(“H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10”),

.init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),

.update_thread_context = ONLY_IF_THREADS_ENABLED(decode_update_thread_context),

.profiles = NULL_IF_CONFIG_SMALL(profiles),

.priv_class = &h264_class,};

2.调用avcodec_decode_video() 函数进行解码

avcodec_decode_video通过调avctx->codec->decode函数来完成具体解码器的调用

其中 avctx为 AVCodecContext类型,codec为AVCodec类型,decode为一个函数指针,

所以真正进行解码的函数为h264.c中的 decode_frame

根据以上分析提取264解码器:

extern AVCodec ff_h264_decoder;//在h264.c中定义

AVCodec *codec = &ff_h264_decoder;//

AVCodecContext *avctx= NULL;//AVCodecContext在AVCodec.c中定义

AVFrame *picture;

DSPContext dsp;

H264Context *h; //h264.h中定义

MpegEncContext *s //Mpegvideo.h中定义

void decode_init()

{

avcodec_init();

avctx= avcodec_alloc_context();

picture= avcodec_alloc_frame();

if(codec->capabilities&CODEC_CAP_TRUNCATED)

c->flags|= CODEC_FLAG_TRUNCATED;

if (avcodec_open(c, codec) < 0) {

fprintf(stderr, “could not open codecn”);

exit(1);

}

//H264Context *h = c->priv_data; //这两行为ff_h264_decode_init的头两行

//MpegEncContext *s = &h->s;

s->dsp.idct_permutation_type =1;

ff_h264_decode_init(&avctx)

dsputil_init(&dsp, avctx);

}

void decode(unsigned char* buf,int buf_size)

{

int size=buf_size;

unsigned char* inbuf_ptr=buf;

//tips for buf: set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams)

//#define INBUF_SIZE 4096

//#define FF_INPUT_BUFFER_PADDING_SIZE 16

//uint8_t inbuf[INBUF_SIZE FF_INPUT_BUFFER_PADDING_SIZE], *inbuf_ptr;

//memset(inbuf INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);

//size = fread(inbuf, 1, INBUF_SIZE, fin);

//inbuf_ptr = inbuf;

int len=0,got_picture=0;

while (size> 0)

{

len = decode_frame(avctx, picture, &got_picture,inbuf_ptr, size);

if (len < 0)

{

fprintf(stderr, “Error while decoding frame %dn”, frame);

exit(1);

}

if (got_picture)

{

printf(“saving frame =n”, frame);

fflush(stdout);

//data

frame ;

}

size -= len;

inbuf_ptr = len;

}

len = avcodec_decode_video(c, picture, &got_picture,

inbuf_ptr, 0);

if (got_picture)

{

//

}

}

void decode_end()

{

avcodec_close(c);

av_free(c);

av_free(picture);

//int ff_h264_decode_end(avctx)

}

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/148844.html原文链接:https://javaforall.cn

0 人点赞