ffmpeg内部解析之: http + ts格式数据输入流程

date: 2015.09.09; modification:2015.09.09

目录:

1 管理结构体的上下文关系

AVFormatContext {
    AVIOContext *pb; {
        void *opaque -->    URLContext {  // 由ffurl_open()得到
                               struct URLProtocol *prot {  // http即为此类型
                                   const char *name;
                                   int (*url_open) (URLContext * h, const char *url, int flags);
                                   int (*url_read) (URLContext * h, char *buf, int size);
                               }
                            }

        int (*read_packet)(void *opaque, uint8_t *buf, int buf_size);
            --> ffurl_read(URLContext *h, unsigned char *buf, int size)
    }

    struct AVInputFormat *iformat; {  // ff_mpegts_demuxer即为此类型
        int (*read_packet)(struct AVFormatContext *, AVPacket *pkt);  --> mpegts_read_packet()
    }
}

2 函数调用关系

说明: 如下符号:

|  
+->

表示调用.

调用关系

av_read_packet(AVFormatContext *s, AVPacket *pkt)
|   // 通过: s->iformat->read_packet(s, pkt)调到:
+-> mpegts_read_packet(AVFormatContext *s, AVPacket *pkt)
    |
    +-> handle_packets(ts, 0)
        |   // 通过调用 static read_packet 调用:
        +-> avio_read(AVIOContext *pb, buf, TS_PACKET_SIZE);  // 该函数自带缓存buffer, 当buffer读完才去调用下面的s->read_packet()
            |
            +-> s->read_packet(s->opaque, buf, size)


avformat_open_input()
|
+-> init_input(AVFormatContext s, filename, &tmp)
    |
    +-> avio_open2(AVIOContext **s, *filename, int flags, *int_cb, **options)  <aviobuf.c>
    |   |
    |   +-> ffurl_open(URLContext **puc, *filename, int flags, *int_cb, **options)
    |   |   |
    |   |   +-> ffurl_alloc(URLContext **puc, const char *filename, int flags, *int_cb) // 可以得到输入协议类型, 比如http.
    |   |   +-> ffurl_connect(URLContext* uc, AVDictionary **options)
    |   |       |
    |   |       +-> uc->prot->url_open(uc, uc->filename, uc->flags); // 对于http即为: http_open() :
    |   |           http_open(URLContext *h, const char *uri, int flags)
    |   |           |
    |   |           +-> http_open_cnx(URLContext *h)
    |   |               |
    |   |               +-> ffurl_open(URLContext **puc, *filename, int flags, *int_cb, **options) // 此时的filename已经变成tcp://172.16.5.144:5100
    |   +-> ffio_fdopen(AVIOContext **s, URLContext *h) // 在此分配: buffer(默认32k), AVIOContext, 并关联到URLContext
    |
    +-> av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt, *filename, *logctx, offset, max_probe_size)
            // 如果是http播放在这里获取到mpegts等封装格式并存入s->iformat.


av_read_packet(AVFormatContext *s, AVPacket *pkt)
|
+-> s->iformat->read_packet(s, pkt);