Khan's Notebook GCC/GNU/Linux Delphi/Window Java/Anywhere

路漫漫,长修远,我们不能没有钱
随笔 - 172, 文章 - 0, 评论 - 257, 引用 - 0
数据加载中……

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

(不知原始出处, 方便请告知, 此处转载于 http://hi.baidu.com/monkeyifox)

URL协议结构:

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;
    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;



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;
}

posted on 2012-12-14 01:21 Khan 阅读(1048) 评论(0)  编辑 收藏 引用 所属分类: GCC/G++跨平台开发周边技术


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理