• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            Khan's Notebook GCC/GNU/Linux Delphi/Window Java/Anywhere

            路漫漫,長(zhǎng)修遠(yuǎn),我們不能沒有錢
            隨筆 - 173, 文章 - 0, 評(píng)論 - 257, 引用 - 0
            數(shù)據(jù)加載中……

            ffmpeg分析系列之七(打開輸入的流)

            err = av_open_input_stream(ic_ptr, pb, filename, fmt, ap);



            int av_open_input_stream(

            AVFormatContext **ic_ptr// 輸出參數(shù): 格式上下文
            ByteIOContext *pb, 
            // 字節(jié)IO上下文

            const char *filename// 文件名
            AVInputFormat *fmt, 
            // 輸入的格式

            AVFormatParameters *ap// 格式參數(shù), 調(diào)用時(shí)為NULL
            {
                int err;
                AVFormatContext *ic;
                AVFormatParameters default_ap;

                 // 使用缺省的格式參數(shù)
                if(!ap){
                    ap=&default_ap;
                    memset(ap, 0, sizeof(default_ap));
                }

                if(!ap->prealloced_context)
                    ic = avformat_alloc_context()// 分配格式上下文
                else
                    ic = *ic_ptr;
                if (!ic) {
                    err = AVERROR(ENOMEM);
                    goto fail;
                }

                // 初始化格式上下文
                ic->iformat = fmt// 格式
                ic->pb = pb// 字節(jié)IO上下文
                ic->duration = AV_NOPTS_VALUE;
                ic->start_time = AV_NOPTS_VALUE;
                av_strlcpy(ic->filename, filename, sizeof(ic->filename))// 文件名

                /* 分配私有數(shù)據(jù) */
                if (fmt->priv_data_size > 0) {
                    ic->priv_data = av_mallocz(fmt->priv_data_size);
                    if (!ic->priv_data) {
                        err = AVERROR(ENOMEM);
                        goto fail;
                    }
                } else {
                    ic->priv_data = NULL;
                }

                // 讀首部
                if (ic->iformat->read_header) {
                    err = ic->iformat->read_header(ic, ap);
                    if (err < 0)
                        goto fail;
                }

                // 獲得數(shù)據(jù)偏移
                if (pb && !ic->data_offset)
                    ic->data_offset = url_ftell(ic->pb);

            #if LIBAVFORMAT_VERSION_MAJOR < 53
                ff_metadata_demux_compat(ic);
            #endif

                // 原始的包緩沖剩余的大小
                ic->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;

                // 輸出參數(shù): 格式上下文

                *ic_ptr = ic;
                return 0;

            }


            具體請(qǐng)參看

            ffmpeg分析系列之三(輸入輸出格式)


            格式上下文結(jié)構(gòu):

            typedef struct AVFormatContext {
                const AVClass *av_class; /**< Set by avformat_alloc_context. */

                // 省略部分內(nèi)容
            }


            AV類結(jié)構(gòu):

            typedef struct {
                
            /**
                 * The name of the class; usually it is the same name as the
                 * context structure type to which the AVClass is associated.
                 */

                const char* class_name;

                
            /**
                 * A pointer to a function which returns the name of a context
                 * instance ctx associated with the class.
                 */

                const char* (*item_name)(void* ctx);

                
            /**
                 * a pointer to the first option specified in the class if any or NULL
                 *
                 * @see av_set_default_options()
                 */

                const struct AVOption *option;

                
            /**
                 * LIBAVUTIL_VERSION with which this structure was created.
                 * This is used to allow fields to be added without requiring major
                 * version bumps everywhere.
                 */


                int version;
            } AVClass;



            進(jìn)入avformat_alloc_context函數(shù), 分配格式上下文:

            AVFormatContext *avformat_alloc_context(void)
            {
                AVFormatContext *ic;
                ic = av_malloc(sizeof(AVFormatContext));
                if (!ic) return ic;
                avformat_get_context_defaults(ic);
                ic->av_class = &av_format_context_class;
                return ic;
            }


            static const AVClass av_format_context_class = { "AVFormatContext", format_to_name, options,LIBAVUTIL_VERSION_INT };


            進(jìn)入avformat_get_context_defaults函數(shù), 格式獲得缺省上下文:

            static void avformat_get_context_defaults(AVFormatContext *s)
            {
                memset(s, 0, sizeof(AVFormatContext));
                s->av_class = &av_format_context_class;
                av_opt_set_defaults(s);
            }


             

            av_opt_set_defaults函數(shù)就不分析了. 

            下面繼續(xù)分析:

            err = ic->iformat->read_header(ic, ap)


            以輸入格式為libavformat/raw.c下的h264_demuxer為例:

            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,
            };



            會(huì)調(diào)用video_read_header函數(shù):

            static int video_read_header(AVFormatContext *s,
                                         AVFormatParameters *ap)
            {
                AVStream *st;

                st = av_new_stream(s, 0)// 格式上下文增加一個(gè)流
                if (!st)
                    return AVERROR(ENOMEM);


                 // 初始化流
                st->codec->codec_type = AVMEDIA_TYPE_VIDEO
            // 編碼編碼器類型
                st->codec->codec_id = s->iformat->value// 為 CODEC_ID_H264
                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_DNXHD ||
                            st->codec->codec_id == CODEC_ID_H264) {
                    st->codec->time_base= (AVRational){1,25}// 設(shè)置時(shí)基
                }
                av_set_pts_info(st, 64, 1, 1200000)// 設(shè)置PTS(顯示時(shí)間截)信息

                return 0;
            }


            進(jìn)入av_new_stream函數(shù):

            AVStream *av_new_stream(AVFormatContext *s, int id)
            {
                AVStream *st;
                int i;

                // 格式上下文不能太多流
                if (s->nb_streams >= MAX_STREAMS)
                    return NULL;

                // 分配一個(gè)流
                st = av_mallocz(sizeof(AVStream));
                if (!st)
                    return NULL;

                // 分配解碼器上下文
                st->codec= avcodec_alloc_context();
                if (s->iformat) {
                    /* no default bitrate if decoding */
                    st->codec->bit_rate = 0;
                }
                st->index = s->nb_streams// 流索引
                st->id = id// ID, 為0
                st->start_time = AV_NOPTS_VALUE// 開始時(shí)間
                st->duration = AV_NOPTS_VALUE;
                    
            /* we set the current DTS to 0 so that formats without any timestamps
                       but durations get some timestamps, formats with some unknown
                       timestamps have their first few packets buffered and the
                       timestamps corrected before they are returned to the user */

                st->cur_dts = 0// 當(dāng)前的解碼時(shí)間截
                st->first_dts = AV_NOPTS_VALUE// 起始的解碼時(shí)間截
                st->probe_packets = MAX_PROBE_PACKETS// 探測(cè)的最大包數(shù)

                /* default pts setting is MPEG-like */

                av_set_pts_info(st, 33, 1, 90000)// 設(shè)置PTS顯示時(shí)間截信息
                st->last_IP_pts = AV_NOPTS_VALUE
                for(i=0; i<MAX_REORDER_DELAY+1; i++)
                    st->pts_buffer[i]= AV_NOPTS_VALUE;
                st->reference_dts = AV_NOPTS_VALUE;

                st->sample_aspect_ratio = (AVRational){0,1};

                s->streams[s->nb_streams++] = st// 記錄流, 同時(shí)流數(shù)加一
                return st;
            }


            分配編碼解碼器上下文:
             

            static const AVClass av_codec_context_class = { "AVCodecContext", context_to_name, options,LIBAVUTIL_VERSION_INT };


            void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType codec_type){
                int flags=0;
                memset(s, 0, sizeof(AVCodecContext));

                s->av_class= &av_codec_context_class;

                s->codec_type = codec_type;
                if(codec_type == AVMEDIA_TYPE_AUDIO)
                    flags= AV_OPT_FLAG_AUDIO_PARAM;
                else if(codec_type == AVMEDIA_TYPE_VIDEO)
                    flags= AV_OPT_FLAG_VIDEO_PARAM;
                else if(codec_type == AVMEDIA_TYPE_SUBTITLE)
                    flags= AV_OPT_FLAG_SUBTITLE_PARAM;
                av_opt_set_defaults2(s, flags, flags);

                s->time_base= (AVRational){0,1};
                s->get_buffer= avcodec_default_get_buffer;
                s->release_buffer= avcodec_default_release_buffer;
                s->get_format= avcodec_default_get_format;
                s->execute= avcodec_default_execute;
                s->execute2= avcodec_default_execute2;
                s->sample_aspect_ratio= (AVRational){0,1};
                s->pix_fmt= PIX_FMT_NONE;
                s->sample_fmt= SAMPLE_FMT_NONE;

                s->palctrl = NULL;
                s->reget_buffer= avcodec_default_reget_buffer;
                s->reordered_opaque= AV_NOPTS_VALUE;
            }

            AVCodecContext *avcodec_alloc_context2(enum AVMediaType codec_type){
                AVCodecContext *avctx= av_malloc(sizeof(AVCodecContext));

                if(avctx==NULL) return NULL;

                avcodec_get_context_defaults2(avctx, codec_type);

                return avctx;
            }

            void avcodec_get_context_defaults(AVCodecContext *s){
                avcodec_get_context_defaults2(s, AVMEDIA_TYPE_UNKNOWN);
            }

            AVCodecContext *avcodec_alloc_context(void){
                return avcodec_alloc_context2(AVMEDIA_TYPE_UNKNOWN);
            }

            @import url(http://m.shnenglu.com/cutesoft_client/cuteeditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);

            posted on 2012-12-14 01:47 Khan 閱讀(2216) 評(píng)論(0)  編輯 收藏 引用 所屬分類: GCC/G++周邊技術(shù)

            久久久久无码精品国产app| 少妇高潮惨叫久久久久久| 久久久精品视频免费观看| 色播久久人人爽人人爽人人片aV| 久久精品视频一| 国产成人久久精品二区三区| 久久国产乱子伦精品免费午夜| 伊人久久大香线蕉综合影院首页| 日日噜噜夜夜狠狠久久丁香五月 | 久久99精品免费一区二区| 丁香久久婷婷国产午夜视频| 狠狠色丁香婷婷久久综合五月| 99久久超碰中文字幕伊人| 狠狠色丁香婷婷久久综合五月| 精品久久久久久久久中文字幕| 亚洲国产一成久久精品国产成人综合| 久久久久亚洲av无码专区喷水| 91精品无码久久久久久五月天| 久久无码人妻一区二区三区| 老男人久久青草av高清| 久久国产成人亚洲精品影院| 久久精品成人免费看| 亚洲色欲久久久综合网| 久久天天躁夜夜躁狠狠| 久久精品无码免费不卡| 久久99精品国产麻豆蜜芽| 国产精品九九久久免费视频| 久久最新精品国产| 精品久久久久久久| 久久免费精品视频| 久久这里只精品国产99热| 99久久中文字幕| 久久国产高清字幕中文| 99久久www免费人成精品| 人人狠狠综合久久亚洲婷婷| 成人午夜精品久久久久久久小说 | 狠狠色丁香婷婷久久综合不卡| 久久99久国产麻精品66| 无码人妻精品一区二区三区久久| 一本色道久久综合亚洲精品| 亚洲欧美日韩久久精品第一区|