Chinaunix首页 | 论坛 | 博客
  • 博客访问: 464177
  • 博文数量: 89
  • 博客积分: 1126
  • 博客等级: 少尉
  • 技术积分: 1432
  • 用 户 组: 普通用户
  • 注册时间: 2011-04-11 23:37
文章分类

全部博文(89)

文章存档

2016年(6)

2015年(2)

2014年(1)

2013年(3)

2012年(23)

2011年(54)

分类: LINUX

2011-11-25 17:21:24

最近看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 }

阅读(4861) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~