H264探测过程用到的几个函数原型

来源:互联网 发布:网络教育统考成绩时间 编辑:程序博客网 时间:2024/05/17 09:15

转自:

一、h264_demuxer过程中用到的几个函数

ffmpeg h264探测输入格式:

调用av_open_input_file(&pFormatCtx,is->filename,NULL,0,NULL)函数打开输入的文件.


1.分析一下函数原型:intav_open_input_file(AVFormatContext**ic_ptr,// 输出参数: 格式上下文                       constchar*filename,// 文件名                       AVInputFormat*fmt,// 输入的格式, 为NULL, 即未知                       intbuf_size,// 缓冲的大小, 为0                       AVFormatParameters*ap);// 格式的参数, 为NULL2.初始化探测数据:    AVProbeData probe_data,*pd=&probe_data;    pd->filename="";    if(filename)        pd->filename=filename;    pd->buf=NULL;    pd->buf_size=0;3.探测输入的格式:    if(!fmt){// fmt == NULL, 成立        fmt=av_probe_input_format(pd,0);    }    进入av_probe_input_format函数:AVInputFormat*av_probe_input_format(AVProbeData*pd,intis_opened){    intscore=0;    returnav_probe_input_format2(pd,is_opened,&score);}    进入av_probe_input_format2函数:AVInputFormat*av_probe_input_format2(AVProbeData*pd,intis_opened,int*score_max){    AVInputFormat*fmt1,*fmt;    intscore;    fmt=NULL;    for(fmt1=first_iformat;fmt1!=NULL;fmt1=fmt1->next){        if(!is_opened==!(fmt1->flags&AVFMT_NOFILE))// is_opened == 0, fmt1->flags 没有设置 AVFMT_NOFILE 标志时成立            continue;    /* 省略部分代码 */}    见libavformat/raw.c文件:AVInputFormat h264_demuxer={    "h264",    NULL_IF_CONFIG_SMALL("raw H.264 video format"),    0,    h264_probe,    video_read_header,    ff_raw_read_partial_packet,    .flags=AVFMT_GENERIC_INDEX,    .extensions="h26l,h264,264",//FIXME remove after writing mpeg4_probe    .value=CODEC_ID_H264,};    由于 h264_demuxer.flags==AVFMT_GENERIC_INDEX,所以上面成立,continue,返回的 AVInputFormat 指针为NULL, 探测不成功.AVInputFormat h264_demuxer= {    "h264",    NULL_IF_CONFIG_SMALL("raw H.264 video format"),    0,    h264_probe,    video_read_header,    ff_raw_read_partial_packet,    .flags=AVFMT_GENERIC_INDEX,    .extensions= "h26l,h264,264", //FIXME remove after writing mpeg4_probe    .value=CODEC_ID_H264,}; 总结:H264文件的基本过程。//av_open_input_file、av_probe_input_format(h264_probe)、video_read_header、 ff_raw_read_partial_packet
二、H.264_probe函数的过程:
static int h264_probe(AVProbeData *p){    uint32_t code= -1;    int sps=0, pps=0, idr=0, res=0, sli=0;    int i;    for(i=0; i<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[32]={                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)                res++;            switch(type){            case     1:   sli++; break;            case     5:   idr++; break;            case     7:                if(p->buf[i+2]&0x0F)                    return 0;                sps++;                break;            case     8:   pps++; break;            }        }    }    if(sps && pps && (idr||sli>3) && res<(sps+pps+idr))        return AVPROBE_SCORE_MAX/2+1; // +1 for .mpg    return 0;}#endif2、video_read_header()函数static int video_read_header(AVFormatContext *s,                             AVFormatParameters *ap){    AVStream *st;    st = av_new_stream(s, 0);    if (!st)        return AVERROR(ENOMEM);    st->codec->codec_type = CODEC_TYPE_VIDEO;    st->codec->codec_id = s->iformat->value;    st->need_parsing = AVSTREAM_PARSE_FULL;    /* for MJPEG, specify frame rate */    /* for MPEG-4 specify it, too (most MPEG-4 streams do not have the fixed_vop_rate set ...)*/    if (ap->time_base.num) {        st->codec->time_base= ap->time_base;    } else if ( st->codec->codec_id == CODEC_ID_MJPEG ||                st->codec->codec_id == CODEC_ID_MPEG4 ||                st->codec->codec_id == CODEC_ID_DIRAC ||                st->codec->codec_id == CODEC_ID_H264) {        st->codec->time_base= (AVRational){1,25};    }    av_set_pts_info(st, 64, 1, 1200000);    return 0;}#endif3、int ff_raw_read_partial_packet(AVFormatContext *s, AVPacket *pkt){    int ret, size;    size = RAW_PACKET_SIZE;    if (av_new_packet(pkt, size) < 0)        return AVERROR(EIO);    pkt->pos= url_ftell(s->pb);    pkt->stream_index = 0;    ret = get_partial_buffer(s->pb, pkt->data, size);    if (ret <= 0) {        av_free_packet(pkt);        return AVERROR(EIO);    }    pkt->size = ret;    return ret;}#endif 


原创粉丝点击