ffmpeg h264解码器提取

ffmpeg h264解码器提取ffmpeg包含了很多的音视频解码器,本文试图通过对ffmpeg的简单分析提取h264解码器.使用ffmpeg解码可以参考ffmpeg源码下的doc/examples/decoding_encoding.c 1.首先设置解码器参数(avcodec_find_decoder(CODEC_ID_H264)将decode函数指针为h264_decoder,即

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

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.net/148844.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 如何从tushare获取股票历史数据写入自己的MySQL数据库[通俗易懂]

    如何从tushare获取股票历史数据写入自己的MySQL数据库[通俗易懂]如何从tushare获取股票历史数据写入自己的MySQL数据库点击https://tushare.pro/register?reg=414428,免费注册后,即可获取tushare的token,就可以下载金融数据了。1.tushare推荐方法如果你需要读取全部股票的历史数据,tushare给的建议是按“天”获取。因为tushareapi限制一次获取最高5000条记录,而A股市场目前有3000多只股票,提取一次数据不会超过api的限制记录数。代码如下:importtus

    2022年6月24日
    97
  • 电工电子电力拖动及自动化技术考核实训台QY-DG800D[通俗易懂]

    电工电子电力拖动及自动化技术考核实训台QY-DG800D[通俗易懂]一、产品简介QY-DG800D高性能电工电子电拖及自动化技术实训与考核装置是针对我国高等院校、职业技术教育的需求而开发的综合性实训考核装置。装置融合了电工、电子、电力拖动、PLC、变频器等实训内容,配备多块可自由组合的实训挂箱,适用各类职业院校、中专、技校电工、电子、电拖、机电一体化、自动化等专业的教学和从事相关专业的技术人员实训考核。二、产品特点装置实训屏上380V交流输出处设有单片机全程监控的一套过流保护装置,相间、线间直接短路或过载,电流超过设定值,系统即告警并切断总电源,确保设备安全.

    2022年6月6日
    38
  • 原创 子网划分的讲解 例题加思路

    原创 子网划分的讲解 例题加思路转载于:https://www.cnblogs.com/dsab/p/7425630.html

    2022年6月27日
    24
  • 基于 SpringBoot + Vue 的商城系统附带小程序源码

    简介 又一个小商场系统,Spring Boot后端 + Vue管理员前端 + 微信小程序用户前端 + Vue用户移动端。 项目架构 技术栈 Spring Boo…

    2021年6月23日
    110
  • Matlab中lsim函数使用

    Matlab中lsim函数使用lsim函数:lsim函数是针对线性时不变模型,给定任意输入,得到任意输出。lsim函数表示任意输入函数的响应,连续系统对任意输入函数的响应可以利用lsim函数求取。语法(常用):1.分子分母形式lsim(num,den,u,t)2.传递函数形式lsim(sys,u,t)3.状态空间形式lsim(A,B,C,D,u,t)其中,u为由给定输入序列构成的矩阵,它的每列对应一个输入,每行对应一个新的时间点,其行数与时间t的长度相等,其它的用法与step函数相同。…

    2022年7月17日
    105
  • 零基础学Java(2)数据类型与变量

    零基础学Java(2)数据类型与变量前言Java是一种强类型语言。这就意味着必须为每一个变量声明一种类型。在Java中,一共8种基本类型,其中有4种整型、2种浮点型、1种字符串类型char(用于表示Unicode编码的代码单元)和1种

    2022年7月29日
    7

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号