前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ffmpeg h264解码器提取

ffmpeg h264解码器提取

作者头像
全栈程序员站长
发布2022-07-04 09:21:11
9860
发布2022-07-04 09:21:11
举报
文章被收录于专栏:全栈程序员必看

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

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 codec\n”);

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 %d\n”, frame);

exit(1);

}

if (got_picture)

{

printf(“saving frame %3d\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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档