好贷网好贷款

ffmpeg分析系列之二(文件协议)

发布时间:2016-12-4 5:59:48 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"ffmpeg分析系列之二(文件协议)",主要涉及到ffmpeg分析系列之二(文件协议)方面的内容,对于ffmpeg分析系列之二(文件协议)感兴趣的同学可以参考一下。

URL协议结构: URLProtocol,URLContext和ByteIOContext是FFMpeg操作文件(即I/O,包括网络数据流)的结构,这几个结构现实的功能类似于C++的多态继承吧,C++的多态是通过子类继承实现,而FFMpeg的“多态”是通过静态对像现实。这部分的代码非常值得C程序借鉴,我是说,如果你要在C里实现类似C++多态性的功能;比如当你要区分你老婆和情人之间的不同功能时。 typedef struct URLProtocol {       const char *name;     int (*url_open)(URLContext *h, const char *url, int flags);     int (*url_read)(URLContext *h, unsigned char *buf, int size);     int (*url_write)(URLContext *h, unsigned char *buf, int size);     int64_t (*url_seek)(URLContext *h, int64_t pos, int whence);     int (*url_close)(URLContext *h);     struct URLProtocol *next;   //指向下一个URLProtocol见备注1     int (*url_read_pause)(URLContext *h, int pause);     int64_t (*url_read_seek)(URLContext *h, int stream_index,                              int64_t timestamp, int flags);     int (*url_get_file_handle)(URLContext *h); } URLProtocol; 备注1:FFMpeg所有的Protol类型都用这个变量串成一个链表,表头为avio.c里的URLProtocol *first_protocol = NULL; 每个文件类似都有自己的一个URLProtocol静态对象,如libavformat/file.c里   URLProtocol file_protocol = {     "file",     file_open,     file_read,     file_write,     file_seek,     file_close,     .url_get_file_handle = file_get_handle, }; 再通过av_register_protocol()将他们链接成链表。在FFMpeg中所有的URLProtocol对像值都在编译时确定。 typedef struct URLContext { #if LIBAVFORMAT_VERSION_MAJOR >= 53     const AVClass *av_class; ///< information for av_log(). Set by url_open(). #endif     struct URLProtocol *prot;          //指向具体的I/0类型,在运行时通过文件URL确定,如是file类型时就是file_protocol               int flags;     int is_streamed;   /**< true if streamed (no seek possible), default = false */     int max_packet_size;  /**< if non zero, the stream is packetized with this max packet size */     void *priv_data;                       //指向具体的I/O句柄     char *filename; /**< specified URL */ } URLContext; 不同于URLProtocol对象值在编译时确定,URLContext对象值是在运行过程中根据输入的I/O类型动态确定的。这一动一静组合起到了C++的多态继承一样的作用。URLContext像是基类,为大家共同所有,而URLProtocol像是子类部分。 typedef struct {     unsigned char *buffer;     int buffer_size;     unsigned char *buf_ptr, *buf_end;     void *opaque;     int (*read_packet)(void *opaque, uint8_t *buf, int buf_size);     int (*write_packet)(void *opaque, uint8_t *buf, int buf_size);     int64_t (*seek)(void *opaque, int64_t offset, int whence);     int64_t pos; /**< position in the file of the current buffer */     int must_flush; /**< true if the next seek should flush */     int eof_reached; /**< true if eof reached */     int write_flag;  /**< true if open for writing */     int is_streamed;     int max_packet_size;     unsigned long checksum;     unsigned char *checksum_ptr;     unsigned long (*update_checksum)(unsigned long checksum, const uint8_t *buf, unsigned int size);     int error;         ///< contains the error code or 0 if no error happened     int (*read_pause)(void *opaque, int pause);     int64_t (*read_seek)(void *opaque, int stream_index,                          int64_t timestamp, int flags); } ByteIOContext; ByteIOContext是URLContext和URLProtocol 一个扩展,也是FFMpeg提供给用户的接口,URLContext和URLProtocol对用户是透明,我们所有的操作是通过ByteIOContext现实。这几个struct的相关的关键函数有: int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,                        AVInputFormat *fmt,                        int buf_size,                        AVFormatParameters *ap) {     int url_fopen(ByteIOContext **s, const char *filename, int flags)     {          url_open(URLContext **puc, const char *filename, int flags)          {                URLProtocol *up;                //根据filename确定up                url_open_protocol (URLContext **puc, struct URLProtocol *up, const char *filename, int flags)                {                     //初始化URLContext对像,并通过 up->url_open()将I/O打开将I/O fd赋值给URLContext的priv_data对像                }          }          url_fdopen(ByteIOContext **s, URLContext *h)          {                //初始化ByteIOContext 对像          }     } } libavformat/file.c文件的file协议: static int file_open(URLContext *h, const char *filename, int flags) {     int access;     int fd;     av_strstart(filename, "file:", &filename);     if (flags & URL_RDWR) {         access = O_CREAT | O_TRUNC | O_RDWR;     } else if (flags & URL_WRONLY) {         access = O_CREAT | O_TRUNC | O_WRONLY;     } else {         access = O_RDONLY;     } #ifdef O_BINARY     access |= O_BINARY; #endif     fd = open(filename, access, 0666);     if (fd == -1)         return AVERROR(errno);     h->priv_data = (void *) (intptr_t) fd;     return 0; } static int file_read(URLContext *h, unsigned char *buf, int size) {     int fd = (intptr_t) h->priv_data;     return read(fd, buf, size); } static int file_write(URLContext *h, unsigned char *buf, int size) {     int fd = (intptr_t) h->priv_data;     return write(fd, buf, size); } /* XXX: use llseek */ static int64_t file_seek(URLContext *h, int64_t pos, int whence) {     int fd = (intptr_t) h->priv_data;     if (whence == AVSEEK_SIZE) {         struct stat st;         int ret = fstat(fd, &st);         return ret < 0 ? AVERROR(errno) : st.st_size;     }     return lseek(fd, pos, whence); } static int file_close(URLContext *h) {     int fd = (intptr_t) h->priv_data;     return close(fd); } static int file_get_handle(URLContext *h) {     return (intptr_t) h->priv_data; } URLProtocol file_protocol = {     "file",     file_open,     file_read,     file_write,     file_seek,     file_close,     .url_get_file_handle = file_get_handle, }; libavformat/allformats.c文件的av_register_all函数注册了file协议: #define REGISTER_PROTOCOL(X,x) { \     extern URLProtocol x##_protocol; \     if(CONFIG_##X##_PROTOCOL) av_register_protocol(&x##_protocol); } void av_register_all(void) {     /* 省略部分代码 */     /* protocols */     REGISTER_PROTOCOL (FILE, file);     /* 省略部分代码 */ } 把注册协议函数也贴出来吧: URLProtocol *first_protocol = NULL; int av_register_protocol(URLProtocol *protocol) {     URLProtocol **p;     p = &first_protocol;     while (*p != NULL) p = &(*p)->next;     *p = protocol;     protocol->next = NULL;     return 0; }

上一篇:[转]聚类算法实践(1)—— 层次、K-means聚类
下一篇:hdu2487(枚举)

相关文章

相关评论