博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
FFmpeg h264_probe函数剖析
阅读量:6437 次
发布时间:2019-06-23

本文共 2755 字,大约阅读时间需要 9 分钟。

函数调用

avformat_open_input
s->iformat->read_header(s)

函数说明

/**

  • Read the format header and initialize the AVFormatContext
  • structure. Return 0 if OK. 'avformat_new_stream' should be
  • called to create new streams.
    /
    int (
    read_header)(struct AVFormatContext *);

从read_header函数调用,去探测h264的码流格式,流程是怎么样的有待研究

代码说明
static int h264_probe(AVProbeData *p)
{
uint32_t code = -1;
int sps = 0, pps = 0, idr = 0, res = 0, sli = 0;
int i, ret;
int pps_ids[MAX_PPS_COUNT+1] = {0};
int sps_ids[MAX_SPS_COUNT+1] = {0};
unsigned pps_id, sps_id;
GetBitContext gb;

for (i = 0; i + 2 < p->buf_size; i++) {    code = (code << 8) + p->buf[i];    if ((code & 0xffffff00) == 0x100) {        int ref_idc = (code >> 5) & 3;        int type    = code & 0x1F;        static const int8_t ref_zero[] = {             2,  0,  0,  0,  0, -1,  1, -1,            -1,  1,  1,  1,  1, -1,  2,  2,             2,  2,  2,  0,  2,  2,  2,  2,             2,  2,  2,  2,  2,  2,  2,  2        };        if (code & 0x80) // forbidden_bit            return 0;        if (ref_zero[type] == 1 && ref_idc)            return 0;        if (ref_zero[type] == -1 && !ref_idc)            return 0;        if (ref_zero[type] == 2) {            if (!(code == 0x100 && !p->buf[i + 1] && !p->buf[i + 2]))                res++;        }        ret = init_get_bits8(&gb, p->buf + i + 1, p->buf_size - i - 1);        if (ret < 0)            return 0;        switch (type) {        case 1:        case 5:            get_ue_golomb_long(&gb);            if (get_ue_golomb_long(&gb) > 9U)                return 0;            pps_id = get_ue_golomb_long(&gb);            if (pps_id > MAX_PPS_COUNT)                return 0;            if (!pps_ids[pps_id])                break;            if (type == 1)                sli++;            else                idr++;            break;        case 7:            skip_bits(&gb, 14);            if (get_bits(&gb, 2))                return 0;            skip_bits(&gb, 8);            sps_id = get_ue_golomb_long(&gb);            if (sps_id > MAX_SPS_COUNT)                return 0;            sps_ids[sps_id] = 1;            sps++;            break;        case 8:            pps_id = get_ue_golomb_long(&gb);            if (pps_id > MAX_PPS_COUNT)                return 0;            sps_id = get_ue_golomb_long(&gb);            if (sps_id > MAX_SPS_COUNT)                return 0;            if (!sps_ids[sps_id])                break;            pps_ids[pps_id] = 1;            pps++;            break;        }    }}ff_tlog(NULL, "sps:%d pps:%d idr:%d sli:%d res:%d\n", sps, pps, idr, sli, res);if (sps && pps && (idr || sli > 3) && res < (sps + pps + idr))    return AVPROBE_SCORE_EXTENSION + 1;  // 1 more than .mpgreturn 0;

}

参考

转载于:https://blog.51cto.com/fengyuzaitu/2043501

你可能感兴趣的文章
微信开发者工具 快捷键
查看>>
monkey测试===修改adb的默认端口
查看>>
AsyncTask和Handler处理异步消息
查看>>
Scheme 中的 pair 和 list 简述
查看>>
iOS AVAssetExportSession 视频剪切、合并、压缩
查看>>
我收藏的技术知识图(每张都是大图)
查看>>
Spring Boot制作启动图案
查看>>
《Linux内核设计与实现》读书笔记(十一)- 定时器和时间管理
查看>>
hdu Oil Deposits
查看>>
彻底理解javascript中的this指针
查看>>
SAS去空格
查看>>
Spring Cloud构建微服务架构(二)服务消费者
查看>>
这些老外的开源技术养活了一票国产软件
查看>>
Maven实战(六)--- dependencies与dependencyManagement的区别
查看>>
创业者应该有的5个正常心态(转)
查看>>
php模式设计之 注册树模式
查看>>
【Android UI设计与开发】3.引导界面(三)实现应用程序只启动一次引导界面
查看>>
_ENV和_G
查看>>
别做操之过急的”无效将军”,做实实在在的”日拱一卒” 纵使一年不将军,不可一日不拱卒...
查看>>
Oracle Grid Infrastructure: Understanding Split-Brain Node Eviction (文档 ID 1546004.1)
查看>>