AVIOContext 再學習

這個目前階段用的不多,暫時不要花費太多精力。

url 的格式不同,使用的傳輸層協議也不同。這塊看代碼還沒看到自己想的這樣。

目前看的信息是:avformatContext 的 io_open 回調函數 在默認情況下叫?io_open_default,在解復用的?avformat_open_input 方法中一定會調用。那么我們如果不使用這個默認的?io_open_default,使用自己寫的回調函數,會怎么樣呢??

還看到的信息:avformatContext的pb (? ? AVIOContext *pb;)是通過 avio_alloc_context方法創建的,那么我們如果自己創建,也可以使用avio_alloc_context創建。

AVIOContext *avio_alloc_context(unsigned char *buffer,int buffer_size,int write_flag,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))

調用AVFormatContext* avformatContext = nullptr;const char* url_400 = "./120/400_300_25.mp4";const char* url_1080 = "./120/1920_1080_25.mp4";int ret = avformat_open_input(&avformatContext, url_400, nullptr, nullptr);1. avformat_open_input 方法內部會重新創建 avformat_alloc_context,創建 AVFormatContext *s = avformat_alloc_context()  1.1 avformat_alloc_context內部調用 avformat_get_context_defaults
static void avformat_get_context_defaults(AVFormatContext *s)
{memset(s, 0, sizeof(AVFormatContext));s->av_class = &av_format_context_class;s->io_open  = io_open_default; //注意這里,設定了 AVFormatContext 的 io_open 回調函數s->io_close = io_close_default;av_opt_set_defaults(s);
}1.2 然后調用if ((ret = init_input(s, filename, &tmp)) < 0)------>		if ((ret = s->io_open(s, &s->pb, filename, AVIO_FLAG_READ | s->avio_flags, options)) < 0)------> 	也就是調用 io_open_default方法,傳遞參數為 AVFormatContext,AVFormatContext->pb的地址,后面在 ------->	調用 return ffio_open_whitelist(pb, url, flags, &s->interrupt_callback, options, s->protocol_whitelist, s->protocol_blacklist);---------> 和當前關系不大    err = ffurl_open_whitelist(&h, filename, flags, int_cb, options, whitelist, blacklist, NULL);--------->		 err = ffio_fdopen(s, h);int ffio_fdopen(AVIOContext **s, URLContext *h)------>			ffio_fdopen內部做了 avio_alloc_context,創建了AVIOContext *s,也就是 avformatContext的 pb,io_open --- A callback for opening new IO streams.從這里可以看出幾點:
0. 當avformat_open_input方法中傳遞的 avformatContext是nullptr,  則:AVFormatContext->io_open = io_open_default
1.即使我們使用 AVFormatContext *avformat_alloc_context(void)創建了avfromatContext,內部也會   AVFormatContext->io_open = io_open_default
1. io_open 回調函數,在avformat_open_input方法中會調用,也就是說,默認會調用 io_open_default 函數
2. 那么我們可以自己定義 AVFormatContext->io_open的回調函數嗎?那要看 io_open_default  函數的功能是啥?

avio_alloc_context 函數說明

AVIOContext *avio_alloc_context(unsigned char *buffer,int buffer_size,int write_flag,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));opaque是 read_packet / write_packet 的第?個參數,指向?戶數據。
buffer和buffer_size是 read_packet / write_packet 的第?個和第三個參數,是供FFmpeg使?
的數據區。
buffer ?作FFmpeg輸?時,由?戶負責向 buffer 中填充數據,FFmpeg取?數據。
buffer ?作FFmpeg輸出時,由FFmpeg負責向 buffer 中填充數據,?戶取?數據。
write_flag是緩沖區讀寫標志,讀寫的主語是指FFmpeg。
write_flag 為1時, buffer ?于寫,即作為FFmpeg輸出。
write_flag 為0時, buffer ?于讀,即作為FFmpeg輸?。
read_packet和write_packet是函數指針,指向?戶編寫的回調函數。
seek也是函數指針,需要?持seek時使?。 可以類?fseek的機制

需要和如下的結合起來學習,

AVFormatContext 再分析零-CSDN博客

AVIOContext? 是 avformatContext 結構體中一個成員變量

是傳輸層的

中文翻譯:

*-demuxing:

要么由用戶在avformat_open_input()之前設置(然后用戶必須手動關閉它),

要么由avformat_opend_input()設置。這里應該想要表達的是如果不設置,那么avformat_opend_input方法內部會自動查找。


*-muxing:由用戶在avformat_write_header()之前設置。調用者必須負責關閉/釋放IO上下文。
*如果在中設置了AVFMT_NOFILE標志,則不要設置此字段iform/oform.flags。在這種情況下,(解)復用器將以其他方式處理I/O,此字段將為NULL。

    /*** I/O context.** - demuxing: either set by the user before avformat_open_input() (then*             the user must close it manually) or set by avformat_open_input().* - muxing: set by the user before avformat_write_header(). The caller must*           take care of closing / freeing the IO context.** Do NOT set this field if AVFMT_NOFILE flag is set in* iformat/oformat.flags. In such a case, the (de)muxer will handle* I/O in some other way and this field will be NULL.*/AVIOContext *pb;

AVIOContext 自己是一個結構體

/*** Bytestream IO Context.* New fields can be added to the end with minor version bumps.* Removal, reordering and changes to existing fields require a major* version bump.* sizeof(AVIOContext) must not be used outside libav*.** @note None of the function pointers in AVIOContext should be called*       directly, they should only be set by the client application*       when implementing custom I/O. Normally these are set to the*       function pointers specified in avio_alloc_context()*/
typedef struct AVIOContext {/*** A class for private options.** If this AVIOContext is created by avio_open2(), av_class is set and* passes the options down to protocols.** If this AVIOContext is manually allocated, then av_class may be set by* the caller.** warning -- this field can be NULL, be sure to not pass this AVIOContext* to any av_opt_* functions in that case.*/const AVClass *av_class;/** The following shows the relationship between buffer, buf_ptr,* buf_ptr_max, buf_end, buf_size, and pos, when reading and when writing* (since AVIOContext is used for both):************************************************************************************                                   READING************************************************************************************                            |              buffer_size              |*                            |---------------------------------------|*                            |                                       |**                         buffer          buf_ptr       buf_end*                            +---------------+-----------------------+*                            |/ / / / / / / /|/ / / / / / /|         |*  read buffer:              |/ / consumed / | to be read /|         |*                            |/ / / / / / / /|/ / / / / / /|         |*                            +---------------+-----------------------+**                                                         pos*              +-------------------------------------------+-----------------+*  input file: |                                           |                 |*              +-------------------------------------------+-----------------+*************************************************************************************                                   WRITING************************************************************************************                             |          buffer_size                 |*                             |--------------------------------------|*                             |                                      |**                                                buf_ptr_max*                          buffer                 (buf_ptr)       buf_end*                             +-----------------------+--------------+*                             |/ / / / / / / / / / / /|              |*  write buffer:              | / / to be flushed / / |              |*                             |/ / / / / / / / / / / /|              |*                             +-----------------------+--------------+*                               buf_ptr can be in this*                               due to a backward seek**                            pos*               +-------------+----------------------------------------------+*  output file: |             |                                              |*               +-------------+----------------------------------------------+**/unsigned char *buffer;  /**< Start of the buffer. */int buffer_size;        /**< Maximum buffer size */unsigned char *buf_ptr; /**< Current position in the buffer */unsigned char *buf_end; /**< End of the data, may be less thanbuffer+buffer_size if the read function returnedless data than requested, e.g. for streams whereno more data has been received yet. */void *opaque;           /**< A private pointer, passed to the read/write/seek/...functions. */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 eof_reached;        /**< true if was unable to read due to error or eof */int write_flag;         /**< true if open for writing */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 *//*** Pause or resume playback for network streaming protocols - e.g. MMS.*/int (*read_pause)(void *opaque, int pause);/*** Seek to a given timestamp in stream with the specified stream_index.* Needed for some network streaming protocols which don't support seeking* to byte position.*/int64_t (*read_seek)(void *opaque, int stream_index,int64_t timestamp, int flags);/*** A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.*/int seekable;/*** max filesize, used to limit allocations* This field is internal to libavformat and access from outside is not allowed.*/int64_t maxsize;/*** avio_read and avio_write should if possible be satisfied directly* instead of going through a buffer, and avio_seek will always* call the underlying seek function directly.*/int direct;/*** Bytes read statistic* This field is internal to libavformat and access from outside is not allowed.*/int64_t bytes_read;/*** seek statistic* This field is internal to libavformat and access from outside is not allowed.*/int seek_count;/*** writeout statistic* This field is internal to libavformat and access from outside is not allowed.*/int writeout_count;/*** Original buffer size* used internally after probing and ensure seekback to reset the buffer size* This field is internal to libavformat and access from outside is not allowed.*/int orig_buffer_size;/*** Threshold to favor readahead over seek.* This is current internal only, do not use from outside.*/int short_seek_threshold;/*** ',' separated list of allowed protocols.*/const char *protocol_whitelist;/*** ',' separated list of disallowed protocols.*/const char *protocol_blacklist;/*** A callback that is used instead of write_packet.*/int (*write_data_type)(void *opaque, uint8_t *buf, int buf_size,enum AVIODataMarkerType type, int64_t time);/*** If set, don't call write_data_type separately for AVIO_DATA_MARKER_BOUNDARY_POINT,* but ignore them and treat them as AVIO_DATA_MARKER_UNKNOWN (to avoid needlessly* small chunks of data returned from the callback).*/int ignore_boundary_point;/*** Internal, not meant to be used from outside of AVIOContext.*/enum AVIODataMarkerType current_type;int64_t last_time;/*** A callback that is used instead of short_seek_threshold.* This is current internal only, do not use from outside.*/int (*short_seek_get)(void *opaque);int64_t written;/*** Maximum reached position before a backward seek in the write buffer,* used keeping track of already written data for a later flush.*/unsigned char *buf_ptr_max;/*** Try to buffer at least this amount of data before flushing it*/int min_packet_size;
} AVIOContext;

ffmpeg 是如何通過參數url 找到具體的 AVIOContext 的?

在解復用一個本地的mp4文件的時候,我們 是這樣調用的,傳遞的 url的值是?"./120/400_300_25.mp4"

? ? const char* url_400 = "./120/400_300_25.mp4";

? ? int ret = avformat_open_input(&avformatContext, url_400, nullptr, nullptr);

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/81495.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/81495.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/81495.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

在Java項目中實現本地語音識別與熱點檢測,并集成阿里云智能語音服務

引言 隨著語音交互技術的發展&#xff0c;如何高效地處理用戶的語音輸入成為許多應用的重要課題。本文將詳細介紹如何在一個Java項目中同時實現&#xff1a; 基于Vosk的本地語音識別&#xff1a;無需調用云端API即可完成語音到文本的轉換。本地熱點語音內容識別&#xff1a;對…

第15章 對API的身份驗證和授權

第15章 對API的身份驗證和授權 在構建RESTful API時,確保只有經過身份驗證和授權的用戶才能訪問特定資源是至關重要的。身份驗證是確認用戶身份的過程,而授權則是決定用戶是否有權訪問特定資源的過程。在本章中,我們將詳細探討如何在ASP.NET Core Web API中實現身份驗證和授…

asp.net客戶管理系統批量客戶信息上傳系統客戶跟單系統crm

# crm-150708 客戶管理系統批量客戶信息上傳系統客戶跟單系統 # 開發背景 本軟件是給鄭州某企業管理咨詢公司開發的客戶管理系統軟件 # 功能 1、導入客戶數據到系統 2、批量將不同的客戶分配給不同的業務員跟進 3、可以對客戶數據根據緊急程度標記不同的顏色&#xff0c…

深入理解現代JavaScript:從ES6+語法到Fetch API

引言 JavaScript作為Web開發的基石語言&#xff0c;近年來經歷了翻天覆地的變化。ES6(ECMAScript 2015)的發布帶來了革命性的新特性&#xff0c;而現代瀏覽器提供的API也讓前端開發變得更加強大和高效。本文將深入探討ES6核心語法、DOM操作優化技巧以及使用Fetch API進行異步請…

仙盟創夢IDE-智能編程,C#判斷數組中是否存在key

一、net4 net core版本 使用LINQ的Contains方法 string[] array { "apple", "banana", "cherry" };string key "banana";bool exists array.Contains(key);if (exists){Console.WriteLine($"數組中存在鍵 {key}");}else…

360驅動大師v2.0(含網卡版)驅動工具軟件下載及安裝教程

1.軟件名稱&#xff1a;360驅動大師 2.軟件版本&#xff1a;2.0 3.軟件大小&#xff1a;218 MB 4.安裝環境&#xff1a;win7/win10/win11 5.下載地址&#xff1a; https://www.kdocs.cn/l/cdZMwizD2ZL1?RL1MvMTM%3D 提示&#xff1a;先轉存后下載&#xff0c;防止資源丟失&…

2025年- H22-Lc130-206. 反轉鏈表(鏈表)---java版

1.題目描述 2.思路 使用迭代法 (1)定義一個前指針 (2)然后定義兩個變量 curr&#xff08;head&#xff09;&#xff0c;curr.next。 (3)curr和curr.next交換位置&#xff08;只要當前指針不為空&#xff0c;執行兩兩交換&#xff09; 3.代碼實現 /*** Definition for singly-…

機器學習常用評價指標

1. 指標說明 (1) AccuracyClassification&#xff08;準確率&#xff09; ? 計算方式&#xff1a;accuracy_score(y_true, y_pred) ? 作用&#xff1a; 衡量模型正確預測的樣本比例&#xff08;包括所有類別&#xff09;。 公式&#xff1a; Accuracy TP TN TP TN FP…

CGI(Common Gateway Interface)協議詳解

CGI&#xff08;通用網關接口&#xff09;是一種標準化的協議&#xff0c;定義了 Web服務器 與 外部程序&#xff08;如腳本或可執行文件&#xff09;之間的數據交互方式。它允許服務器動態生成網頁內容&#xff0c;而不僅僅是返回靜態文件。 1. CGI 的核心作用 動態內容生成&a…

2025.4.29總結

工作&#xff1a;最近手頭活變得多起來了&#xff0c;畢竟要測兩個版本&#xff0c;有時候覺得很奇怪&#xff0c;活少的時候&#xff0c;又想讓別人多分點活&#xff0c;活多的時候&#xff0c;又會有些許不自然。這種反差往往伴隨著項目的節奏&#xff0c;伴隨著兩個極端。所…

【KWDB 創作者計劃】技術解讀:多模架構、高效時序數據處理與分布式實現

技術解讀&#xff1a;多模架構、高效時序數據處理與分布式實現 一、多模架構1.1 架構概述1.2 源碼分析1.3 實現流程 二、高效時序數據處理2.1 處理能力概述2.2 源碼分析2.3 實現流程 三、分布式實現3.1 分布式特性概述3.2 源碼分析3.3 實現流程 四、總結 在當今數據爆炸的時代&…

# 前后端分離象棋對戰項目開發記錄

1. **結構清晰**&#xff1a;使用更直觀的標題、分段和列表&#xff0c;增強可讀性。 2. **視覺美觀**&#xff1a;添加Markdown格式化&#xff08;如代碼塊、加粗、斜體&#xff09;&#xff0c;并建議配色和排版風格。 3. **內容精煉**&#xff1a;精簡冗余表述&#xff0c;突…

HarmonyOS NEXT 詩詞元服務項目開發上架全流程實戰(一、項目介紹及實現效果)

在當今數字化時代&#xff0c;如何讓傳統文化與現代科技相結合&#xff0c;成為了一個值得思考的問題。詩詞作為中國傳統文化的重要組成部分&#xff0c;承載著豐富的歷史信息和文化內涵。為了讓更多人了解和欣賞詩詞的魅力&#xff0c;我們決定開發一款基于HarmonyOS NEXT的詩…

linux jounery 日志相關問題

/var/log 目錄 是 Linux 系統中存放各種日志文件的標準位置。 這些日志文件記錄了系統及其服務的運行狀態。 日志文件來源 系統日志 由 syslog 或 systemd-journald&#xff08;如果使用 systemd 的話&#xff09;等日志服務生成。記錄內核消息和各種系統事件&#xff0c;例如…

JavaWeb學習打卡-Day7-正向代理、反向代理、Nginx

正向代理 概念&#xff1a;正向代理是一個位于客戶端和目標服務器之間的代理服務器&#xff08;中間服務器&#xff09;。為了從目標服務器取得內容&#xff0c;客戶端向代理服務器發送一個請求&#xff0c;并且指定目標服務器&#xff0c;之后代理向目標服務器轉發請求&#…

AI算法可視化:如何用Matplotlib與Seaborn解釋模型?

AI算法可視化&#xff1a;如何用Matplotlib與Seaborn解釋模型&#xff1f; 系統化學習人工智能網站&#xff08;收藏&#xff09;&#xff1a;https://www.captainbed.cn/flu 文章目錄 AI算法可視化&#xff1a;如何用Matplotlib與Seaborn解釋模型&#xff1f;摘要引言基礎可…

GoogleTest:TEST_F

GoogleTest:簡單示例及ASSERT/EXPECT說明-CSDN博客 介紹了寫一個簡單的測試用例 如果某些測試用例在開始測試前需要先做一些準備工作,那么如果每次都需要先準備,那么會比較的麻煩,基于這種情況可以使用GoogleTest的TEST_F方法。 簡單點說,就是需要先定義一個繼承于testin…

【云備份】配置文件加載模塊

目錄 一.為什么要配置文件 二.配置文件的實現 三.單例文件配置類設計 四.源碼 一.為什么要配置文件 我們將服務端程序運行中用到的一些關鍵信息保存到配置文件中&#xff0c;這樣可以使程序的運行更加靈活。 這樣做的好處是&#xff0c;未來如果我們想要修改一些關鍵信息&…

文號驗證-同時對兩個輸入框驗證

文號驗證-同時對兩個輸入框驗證 效果&#xff1a; 一、如果有多個文號&#xff1a; <div v-for"(item, index) in approvalForm.productApprovalTypeEvents" :key"index"> <el-form-itemlabel"文號":prop"productApprovalTypeEv…

高翔視覺slam中常見的OpenCV和Eigen的幾種數據類型的內存布局及分配方式詳解

vector<Eigen::Vector2d, Eigen::aligned_allocator<Eigen::Vector2d>> 內存布局及分配方式詳解 1. 內存對齊的必要性 Eigen 的固定大小類型(如 Eigen::Vector2d、Eigen::Matrix4d 等)需要 16 字節內存對齊,以支持 SIMD 指令(如 SSE/AVX)的并行計算。若未對…