ffmpeg中的http協議相關代碼閱讀筆記

來源:互聯網
上載者:User
ffmpeg中的http協議相關代碼閱讀筆記

今天閑來無事,嘗試看了下ffmpeg中的相關http協議傳輸處理代碼

先簡單說下這個代碼在整個倉庫裡面的位置:

ffmpeg/libavformat/http.h

ffmpeg/libavformat/http.c

 

avoi.h中的函數調用分析

avoi.h是ffmpeg中libavformat/目錄下的一個重要的標頭檔,這個檔案主要處理了一些傳輸協議的傳輸封裝。他的封裝過程是通過函數指標來實現的。

可以先看http.c檔案中的最後一個結構體:

 

URLProtocol http_protocol = {

    "http",

    http_open,

    http_read,

    http_write,

    http_seek,

    http_close,

    .url_get_file_handle = http_get_file_handle,

    .priv_data_size = sizeof(HTTPContext),

    .priv_data_class = &httpcontext_class,

};

 

 

URLProtocol這個結構是在avoi.h中一個很重要的結構,他的存在的意義就是為了統一介面,可以在avoi.h中查到他的定義:

 

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, const 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);

    int priv_data_size;

    const AVClass *priv_data_class;

} URLProtocol;

 

針對http.c檔案處理的http協議,最主要的就是實現URLProtocol中的函數指標,至於每個函數的具體意義,相信看命名就可以知道。

 

那麼avoi.h中的函數又是怎麼使用到這個內容的呢?這就可以從avoi.h中的幾個函數看出來:

int url_open();

int url_read();

int url_write();

int64_t url_seek(URLContext *h, int64_t pos, int whence);int url_close(URLContext *h);找其中的一個分析,url_open:int url_open(URLContext **puc, const char *filename, int flags){    int ret = url_alloc(puc, filename, flags);    if (ret)        return ret;    ret = url_connect(*puc);    if (!ret)        return 0;    url_close(*puc);    *puc = NULL;    return ret;}url_open函數中使用到了url_alloc, url_connect, url_close,這3個函數可能會在不同的情況下進行使用,由於代碼太多,就不貼了,僅記錄如下url_alloc函數:
  • 處理協議探測,如果url參數中沒有正常的協議,就預設填上"file://"然後作為檔案協議處理
  • 處理探測的過程是在所有的已經註冊上的協議鏈表中搜尋對應名稱的協議,這個名稱,就是URLProtocol.name
  • 如果探測成功會把puc,即URLContext結構體也幫忙分配好,並作為參數out

url_connect:

  • 和url_open函數一樣,url_connect會調用協議中的http_open函數進行http請求初始化: uc->prot->url_open()
  • url_connect返回非零值代表失敗

url_close:

  • 如果url_connect失敗,返回是非0值,就會調用url_close,並返回整個url_open函數失敗

 

http.c檔案的一些關鍵點分析http_open函數

http_open函數會嘗試調用其中的http_open_cnx,然後http_open_cnx會調用靜態成員函數http_connect來進行http請求,其中所有的請求發送都是通過http_write函數來進行的。

http_read函數

相關的函數:

http_read, http_getline, http_getc

http_getc會有個1024的緩衝區,如果發現緩衝區滿了才會繼續讀取,如果沒有慢就每次讀緩衝區裡面的一個字元

 

static int http_getc(HTTPContext *s)

{

    int len;

    if (s->buf_ptr >= s->buf_end) {

        len = url_read(s->hd, s->buffer, BUFFER_SIZE);

        if (len < 0) {

            return AVERROR(EIO);

        } else if (len == 0) {

            return -1;

        } else {

            s->buf_ptr = s->buffer;

            s->buf_end = s->buffer + len;

        }

    }

    return *s->buf_ptr++;

}

 

HTTP協議中資料發送和接受的處理

http.c函數的URLProtocol結構體中有個PrivateData的指標,這個指標儲存了http協議中的一些內部使用到的資料變數,內部處理的資料變數結構體如下:

typedef struct {

    const AVClass *class;

    URLContext *hd;

    unsigned char buffer[BUFFER_SIZE], *buf_ptr, *buf_end;

    int line_count;

    int http_code;

    int64_t chunksize;      /**< Used if "Transfer-Encoding: chunked" otherwise -1. */

    int64_t off, filesize;

    char location[MAX_URL_SIZE];

    HTTPAuthState auth_state;

    unsigned char headers[BUFFER_SIZE];

    int willclose;          /**< Set if the server correctly handles Connection: close and will close the connection after feeding us the content. */

} HTTPContext;

 

可以看到一個比較重要的資訊是:該私人的內部資料中竟然也有一個URLContext,那這個是什麼呢?這個URLContext的協議又是什麼呢?我通過閱讀代碼發現這個URLContext就是指向的tcp協議,用來通過tcp讀取和返回資料。很感慨阿。這樣很簡單的就可以同時支援http,tcp協議,而且把tcp,udp協議封裝起來以後,基本上其他的像rtsp, mms等協議也可以通過制定他們自己的內在協議來處理了。

 

在http.c中的http_open_cnx函數中有一句代碼:

ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL);

這樣就很好的把http的底層tcp協議比較好的串接起來總結

通過看ffmpeg的代碼,總結了下,其實ffmpeg本身並不是很神秘,他本身只是提供了一個很好的很平等並可以無限擴充的架構。而在ffmpeg這個架構上,才能有很多codec, decodec和mutex, io, protocol很好的共存處理。

很欣賞,能作這個完美架構的大師,只有這種完美的架構才能吸引更多的開源愛好著去研究ffmpeg的代碼,並不斷的豐富它!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.