最近看ffmpeg的代码,在打开文件时,使用了一个AVIOContext对象的概念。在ffmepg中将输入做了封装,将流媒体和本地文件都封装为AVIOContext结构体。和编解码的概念类似。在libavformat/allformats.c中的 av_register_all()不仅注册了编解码器,还注册了各种AVIOContext。
36 #define REGISTER_PROTOCOL(X,x) { \
37 extern URLProtocol ff_##x##_protocol; \
38 if(CONFIG_##X##_PROTOCOL) ffurl_register_protocol(&ff_##x##_protocol, sizeof(ff_##x##_protocol)); }
239 /* protocols */
240 REGISTER_PROTOCOL (APPLEHTTP, applehttp);
241 REGISTER_PROTOCOL (CONCAT, concat);
242 REGISTER_PROTOCOL (CRYPTO, crypto);
243 REGISTER_PROTOCOL (FILE, file);
244 REGISTER_PROTOCOL (GOPHER, gopher);
245 REGISTER_PROTOCOL (HTTP, http);
246 REGISTER_PROTOCOL (MMSH, mmsh);
247 REGISTER_PROTOCOL (MMST, mmst);
248 REGISTER_PROTOCOL (MD5, md5);
249 REGISTER_PROTOCOL (PIPE, pipe);
250 REGISTER_PROTOCOL (RTMP, rtmp);
251 #if CONFIG_LIBRTMP
252 REGISTER_PROTOCOL (RTMP, rtmpt);
253 REGISTER_PROTOCOL (RTMP, rtmpe);
254 REGISTER_PROTOCOL (RTMP, rtmpte);
255 REGISTER_PROTOCOL (RTMP, rtmps);
256 #endif
257 REGISTER_PROTOCOL (RTP, rtp);
258 REGISTER_PROTOCOL (TCP, tcp);
259 REGISTER_PROTOCOL (UDP, udp);
下面是一些流的结构体:
116 /**
117 * @deprecated This struct is to be made private. Use the higher-level
118 * AVIOContext-based API instead.
119 */
120 typedef struct URLProtocol {
121 const char *name;
122 int (*url_open)(URLContext *h, const char *url, int flags);
123 int (*url_read)(URLContext *h, unsigned char *buf, int size);
124 int (*url_write)(URLContext *h, const unsigned char *buf, int size);
125 int64_t (*url_seek)(URLContext *h, int64_t pos, int whence);
126 int (*url_close)(URLContext *h);
127 struct URLProtocol *next;
128 int (*url_read_pause)(URLContext *h, int pause);
129 int64_t (*url_read_seek)(URLContext *h, int stream_index,
130 int64_t timestamp, int flags);
131 int (*url_get_file_handle)(URLContext *h);
132 int priv_data_size;
133 const AVClass *priv_data_class;
134 int flags;
135 int (*url_check)(URLContext *h, int mask);
136 } URLProtocol;
//这是每种流的各种文件操作函数的封装。其实对本地文件来说就是open ,read 等的调用。
95 /**
96 * URL Context.
97 * New fields can be added to the end with minor version bumps.
98 * Removal, reordering and changes to existing fields require a major
99 * version bump.
100 * sizeof(URLContext) must not be used outside libav*.
101 * @deprecated This struct will be made private
102 */
103 typedef struct URLContext {
104 const AVClass *av_class; ///< information for av_log(). Set by url_open().
105 struct URLProtocol *prot;
106 int flags;
107 int is_streamed; /**< true if streamed (no seek possible), default = false */
108 int max_packet_size; /**< if non zero, the stream is packetized with this max packet size */
109 void *priv_data;
110 char *filename; /**< specified URL */
111 int is_connected;
112 } URLContext;
39 * Bytestream IO Context.
40 * New fields can be added to the end with minor version bumps.
41 * Removal, reordering and changes to existing fields require a major
42 * version bump.
43 * sizeof(AVIOContext) must not be used outside libav*.
44 *
45 * @note None of the function pointers in AVIOContext should be called
46 * directly, they should only be set by the client application
47 * when implementing custom I/O. Normally these are set to the
48 * function pointers specified in avio_alloc_context()
49 */
50 typedef struct {
51 unsigned char *buffer; /**< Start of the buffer. */
52 int buffer_size; /**< Maximum buffer size */
53 unsigned char *buf_ptr; /**< Current position in the buffer */
54 unsigned char *buf_end; /**< End of the data, may be less than
55 buffer+buffer_size if the read function returned
56 less data than requested, e.g. for streams where
57 no more data has been received yet. */
58 void *opaque; /**< A private pointer, passed to the read/write/seek/...
59 functions. */
60 int (*read_packet)(void *opaque, uint8_t *buf, int buf_size);
61 int (*write_packet)(void *opaque, uint8_t *buf, int buf_size);
62 int64_t (*seek)(void *opaque, int64_t offset, int whence);
63 int64_t pos; /**< position in the file of the current buffer */
64 int must_flush; /**< true if the next seek should flush */
65 int eof_reached; /**< true if eof reached */
66 int write_flag; /**< true if open for writing */
67 #if FF_API_OLD_AVIO
68 attribute_deprecated int is_streamed;
69 #endif
70 int max_packet_size;
71 unsigned long checksum;
72 unsigned char *checksum_ptr;
73 unsigned long (*update_checksum)(unsigned long checksum, const uint8_t *buf, unsigned int size);
74 int error; /**< contains the error code or 0 if no error happened */
75 /**
76 * Pause or resume playback for network streaming protocols - e.g. MMS.
77 */
78 int (*read_pause)(void *opaque, int pause);
79 /**
80 * Seek to a given timestamp in stream with the specified stream_index.
81 * Needed for some network streaming protocols which don't support seeking
82 * to byte position.
83 */
84 int64_t (*read_seek)(void *opaque, int stream_index,
85 int64_t timestamp, int flags);
86 /**
87 * A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
88 */
89 int seekable;
90 } AVIOContext;
int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options);
avformat_alloc_context();
在这个函数里调用AVFormatContext *avformat_alloc_context(void)分配内存。
然后调用static int init_input(AVFormatContext *s, const char *filename);
int avio_open(AVIOContext **s, const char *filename, int flags)
这里的(AVIOContext **s, 来自于AVFormatContext->pb
938 {
939 URLContext *h;
940 int err;
941
942 err = ffurl_open(&h, filename, flags); 在这里完成url协议的匹配。
945 err = ffio_fdopen(s, h); 在这里填充的URLContext
949 }
950 return 0;
951 }
阅读(4884) | 评论(0) | 转发(0) |