main objects and flow on ffmpeg

来源:互联网 发布:mac 相簿 添加照片 编辑:程序博客网 时间:2024/05/08 08:40


1. AVFormatContext 在 open_input_file / open_output_file中分配
2. AVStream, AVCodecContext在 pmt_cb 中分配并设置
pmt_cb:
   st = avformat_new_stream(pes->stream, NULL);
        avformat_new_stream: 
             streams = av_realloc_array(s->streams, s->nb_streams + 1, sizeof(*streams));
             st->codec = avcodec_alloc_context3(c);
             ......................................
             s->streams[s->nb_streams++] = st;
   if (pes && !pes->stream_type)
        mpegts_set_stream_info(st, pes, stream_type, prog_reg_desc);
        mpegts_set_stream_info:
             mpegts_find_stream_type(st, pes->stream_type, ISO_types);
             mpegts_find_stream_type:
                       for (; types->stream_type; types++) {
                            if (stream_type == types->stream_type) {
                                 st->codec->codec_type = types->codec_type;
                                 st->codec->codec_id   = types->codec_id;
                                 st->request_probe     = 0;
                                 return;
                            }
                       }

3.  AVCodec 在 avformat_find_stream_info  / open_input_file

首先在avformat_find_stream_info of open_input_file 获取

codec = find_decoder(ic, st, st->codec->codec_id);

if (avcodec_open2(st->codec, codec, options ? &options[i] : &thread_opt) < 0)


而后在 open_input_file 再一次获取

add_input_streams(o, ic); => ist->dec = choose_decoder(o, ic, st);


4. encoder/decoder open 在 transcode_init
encoder open

ost->enc = avcodec_find_encoder(codec->codec_id);

AVCodec      *codec = ost->enc;
if ((ret = avcodec_open2(ost->st->codec, codec, &ost->opts)) < 0)
decoder open
    /* init input streams */
    for (i = 0; i < nb_input_streams; i++)
        if ((ret = init_input_stream(i, error, sizeof(error))) < 0) {
            for (i = 0; i < nb_output_streams; i++) {
                ost = output_streams[i];
                avcodec_close(ost->st->codec);
            }
            goto dump_format;
        }
    在 init_input_stream 中

           AVCodec *codec = ist->dec;
           if ((ret = avcodec_open2(ist->st->codec, codec, &ist->opts)) < 0)

5. decode
   output_packet => decode_audio / decode_video =>
   avcodec_decode_audio4 (avctx->codec->decode(avctx, frame, got_frame_ptr, &tmp);)
   avcodec_decode_video2(ret = avctx->codec->decode(avctx, picture, got_picture_ptr,&tmp);)
6. encode
   reap_filters => do_audio_out / do_video_out =>
   avcodec_encode_audio2(ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr);)
   avcodec_encode_video2(ret = avctx->codec->encode2(avctx, avpkt, frame, got_packet_ptr);)
   if(got_packet) write_frame(s, &pkt, ost);
  
  


额外说明:

Output stream 创建流程

in open_output_file:

视频:

           if (idx >= 0)   new_video_stream(o, oc, idx);

in new_video_stream

    AVStream *st;
    OutputStream *ost;
    AVCodecContext *video_enc;

   

    ost = new_output_stream(o, oc, AVMEDIA_TYPE_VIDEO, source_index);
    st  = ost->st;
    video_enc = st->codec;

in new_output_stream:

AVStream *st = avformat_new_stream(oc, NULL);

choose_encoder(o, oc, ost);  // AVCodec 将在这儿通过名字获得, 如 libx264


音频:

if (idx >= 0)       new_audio_stream(o, oc, idx);

in new_audio_stream

    AVStream *st;
    OutputStream *ost;
    AVCodecContext *audio_enc;

    ost = new_output_stream(o, oc, AVMEDIA_TYPE_AUDIO, source_index);

in new_output_stream

同视频处理






0 0
原创粉丝点击