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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 线程用户态和内核态

    线程用户态和内核态(1)用户态和内核态的概念?—>内核态:CPU可以访问内存所有数据,包括外围设备,例如硬盘,网卡.CPU也可以将自己从一个程序切换到另一个程序—>用户态:只能受限的访问内存,且不允许访问外围设备.占用CPU的能力被剥夺,CPU资源可以被其他程序获取(2)为什么需要用户态和内核态?—>由于需要限制不同的程序之间的访问能力,防止他们获取别的程序的内存数据,…

    2022年10月26日
  • HibernateTemplate的使用方法

    HibernateTemplate的使用方法HibernateTemplate的使用方法

    2022年6月22日
  • leetcode链表问题_链表面试题

    leetcode链表问题_链表面试题给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。示例 1:输入:head = [1,2,3,4,5], left = 2, right = 4输出:[1,4,3,2,5]示例 2:输入:head = [5], left = 1, right = 1输出:[5] 提示:链表中节点数目为 n1 <= n <= 500-500

    2022年8月9日
  • 基于Docker运行弹性集群的五个关键点之:运行高可用模式

    基于Docker运行弹性集群的五个关键点之:运行高可用模式

    2022年2月22日
  • 数据库优化分库分表_数据库分库分表的好处

    数据库优化分库分表_数据库分库分表的好处一.数据切分关系型数据库本身比较容易成为系统瓶颈,单机存储容量、连接数、处理能力都有限。当单表的数据量达到1000W或100G以后,由于查询维度较多,即使添加从库、优化索引,做很多操作时性能仍下降严重。此时就要考虑对其进行切分了,切分的目的就在于减少数据库的负担,缩短查询时间。数据库分布式核心内容无非就是数据切分(Sharding),以及切分后对数据的定位、整合。数据切分就是将数据分散存储到多个数据库中,使得单一数据库中的数据量变小,通过扩充主机的数量缓解单一数据库的性能问题,从而达到提升数据库操作性

    2022年9月20日

发表回复

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

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