• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

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

            路漫漫,長修遠,我們不能沒有錢
            隨筆 - 173, 文章 - 0, 評論 - 257, 引用 - 0
            數據加載中……

            ffmpeg分析系列之五(打開輸入的文件)

            1. 打開文件:

            if (!fmt || !(fmt->flags & AVFMT_NOFILE)) { 

                
            因 fmt == NULL, 上面成立, 再看下面的代碼:

                    ByteIOContext *pb = NULL; // 字節IO上下文

                    if ((err=url_fopen(&pb, filename, URL_RDONLY)) < 0) { // 只讀方式打開輸入的文件
                        goto fail;
                    }
                    if (buf_size > 0) { // 因 buf_size == 0, 不成立
                        url_setbufsize(pb, buf_size);

                    }


            進入url_fopen函數:

            int url_fopen(ByteIOContext **s, // 輸出參數: 字節IO上下文
                          const char *filename, // 文件名
                          int flags) // 標志
            {
                URLContext *h; // URL(統一資源定位)上下文
                int err;

                err = url_open(&h, filename, flags); // 打開URL
                if (err < 0)
                    return err;
                err = url_fdopen(s, h); // 用URL上下文打開字節IO上下文
                if (err < 0) {
                    url_close(h);
                    return err;
                }
                return 0;
            }


            進入url_open函數:

            int url_open(URLContext **puc, // 輸出參數: URL上下文

            const char *filename, // 文件名

            int flags) // 標志

            {
                URLProtocol *up;
                const char *p;
                char proto_str[128], *q;

                // 提取協議
                p = filename;
                q = proto_str;
                while (*!= '\0' && *!= ':') { // 未結束, 并未遇到分隔符':'
                    if (!isalpha(*p)) // 如果不是英文字母
                        goto file_proto;
                    if ((- proto_str) < sizeof(proto_str) - 1)
                        *q++ = *p; // 記錄協議字符串
                    p++;
                }

                if (*== '\0' || is_dos_path(filename)) { // 如果上面是因為結束而跳出, 或且
            文件名是DOS路徑

                file_proto:
                    strcpy(proto_str, "file"); // 文件協議
                } else {
                    *= '\0'; // 追加結束符
                }

                up = first_protocol;
                while (up != NULL) {
                    if (!strcmp(proto_str, up->name)) // 協議匹配
                        return url_open_protocol (puc, up, filename, flags); // 用這個協議打開URL
                    up = up->next;
                }
                *puc = NULL;
                return AVERROR(ENOENT);
            }


            進入url_open_protocol函數:

            int url_open_protocol (URLContext **puc, // 輸出參數: URL上下文

            struct URLProtocol *up, // URL協議

            const char *filename, // 文件名

            int flags// 標志
            {
                URLContext *uc;
                int err;

                // 網絡初始化
            #if CONFIG_NETWORK
                if (!ff_network_init())
                    return AVERROR(EIO);
            #endif

                // 分配URL上下文并加上文件名的存儲空間
                uc = av_mallocz(sizeof(URLContext) + strlen(filename) + 1);
                if (!uc) {
                    err = AVERROR(ENOMEM);
                    goto fail;
                }

                // 初始化URL上下文
            #if LIBAVFORMAT_VERSION_MAJOR >= 53
                uc->av_class = &urlcontext_class;
            #endif

                // 記錄文件名
                uc->filename = (char *) &uc[1];
                strcpy(uc->filename, filename);
             
                uc->prot = up
            // URL協議

                uc->flags = flags// 標志
                uc->is_streamed = 0// 默認不是流, 可以在up->url_open函數里修改
                uc->max_packet_size = 0; // 
            包最大多大, 默認為0, 可以在up->url_open函數里修改

                // 打開URL
                err = up->url_open(uc, filename, flags);
                if (err < 0) {
                    av_free(uc);
                    goto fail;
                }

             

                if( (flags & (URL_WRONLY | URL_RDWR)// 如果以可寫方式打開

                   || !strcmp(up->name, "file")// 或且是文件協議

                     // 如果不是流并且不可以url_seek

                    if(!uc->is_streamed && url_seek(uc, 0, SEEK_SET) < 0)
                        uc->is_streamed= 1
            // 強制為流

                // 輸出
            參數: URL上下文

                *puc = uc;
                return 0;
             fail:
                *puc = NULL;
            #if CONFIG_NETWORK
                ff_network_close();
            #endif
                return err;
            }


            先來看看url_get_max_packet_size函數

            int url_get_max_packet_size(URLContext *h)
            {
                return h->max_packet_size; // 包最大多大, 被上面初始化為0
            }


            進入url_fdopen函數:

            int url_fdopen(

            ByteIOContext **s, // 輸出參數: 字節IO上下文

            URLContext *h// URL上下文
            {
                uint8_t *buffer;
                int buffer_size, max_packet_size;

                max_packet_size = url_get_max_packet_size(h);
                if (max_packet_size) {
                    buffer_size = max_packet_size;
                } else {
                    buffer_size = IO_BUFFER_SIZE; // 緩沖大小為IO_BUFFER_SIZE
                }
                buffer = av_malloc(buffer_size); // 分配緩沖
                if (!buffer)
                    return AVERROR(ENOMEM);

                *= av_mallocz(sizeof(ByteIOContext)); // 分配字節IO上下文

                if(!*s) {
                    av_free(buffer);
                    return AVERROR(ENOMEM);
                }

                if (init_put_byte(*s, buffer, buffer_size,
                                  (h->flags & URL_WRONLY || h->flags & URL_RDWR), h,
                                  url_read, url_write, url_seek) < 0) {
                    av_free(buffer);
                    av_freep(s);
                    return AVERROR(EIO);
                }
                (*s)->is_streamed = h->is_streamed// 是否為流
                (*s)->max_packet_size = max_packet_size// 包最大多大
                if(h->prot) {
                    (*s)->read_pause = (int (*)(void *, int))h->prot->url_read_pause; // 讀暫停函數
                    (*s)->read_seek = (int64_t (*)(void *, int, int64_t, int))h->prot->url_read_seek; // 讀seek函數
                }
                return 0;
            }


            進入init_put_byte函數:

            int init_put_byte(ByteIOContext *s, // 字節IO上下文
                              unsigned char *buffer, // 緩沖
                              int buffer_size, // 緩沖的大小
                              int write_flag, // 寫標志
                              void *opaque, // URL上下文
                              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)) // 調整文件指針
            {
                s->buffer = buffer;
                s->buffer_size = buffer_size;
                s->buf_ptr = buffer;
                s->opaque = opaque;
                url_resetbuf(s, write_flag ? URL_WRONLY : URL_RDONLY);
                s->write_packet = write_packet;
                s->read_packet = read_packet;
                s->seek = seek;
                s->pos = 0;
                s->must_flush = 0;
                s->eof_reached = 0;
                s->error = 0;
                s->is_streamed = 0;
                s->max_packet_size = 0;
                s->update_checksum= NULL;
                if(!read_packet && !write_flag){
                    s->pos = buffer_size;
                    s->buf_end = s->buffer + buffer_size;
                }
                s->read_pause = NULL;
                s->read_seek = NULL;
                return 0;
            }

            @import url(http://www.shnenglu.com/cutesoft_client/cuteeditor/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/css/cuteeditor.css);

            posted on 2012-12-14 01:34 Khan 閱讀(1170) 評論(0)  編輯 收藏 引用 所屬分類: GCC/G++ 、跨平臺開發

            国产99久久久国产精品小说| 久久国产精品久久精品国产| 国产成人久久精品区一区二区| 伊人久久大香线蕉综合网站| 久久精品一区二区影院| 91精品国产91久久综合| 久久久久久久久久久久中文字幕 | 国产精品久久久久乳精品爆 | 日韩人妻无码精品久久久不卡| 午夜精品久久久久久久无码| 午夜精品久久影院蜜桃| 伊人久久大香线蕉精品不卡| 久久国产精品无| 久久精品人人做人人爽电影| 久久精品日日躁夜夜躁欧美| 久久精品国产亚洲精品2020 | 93精91精品国产综合久久香蕉| 久久久青草久久久青草| 大美女久久久久久j久久| 久久99精品久久久久久齐齐| 噜噜噜色噜噜噜久久| 久久精品国产亚洲AV香蕉| a高清免费毛片久久| 精品无码久久久久久国产| 婷婷久久综合| 99re久久精品国产首页2020| 久久AⅤ人妻少妇嫩草影院| 狠狠色丁香婷婷久久综合五月| 国产美女亚洲精品久久久综合| 99久久99这里只有免费的精品| 国产精品99久久精品爆乳| 久久午夜综合久久| 久久久久久夜精品精品免费啦| 精品国产乱码久久久久久浪潮 | 亚洲欧洲精品成人久久曰影片| 国产aⅴ激情无码久久| 亚洲国产成人久久综合碰碰动漫3d| 日韩美女18网站久久精品| 久久九九精品99国产精品| 久久久久久久亚洲精品 | 无码国内精品久久人妻|