av_read_frame 代碼研究

------------------------------------------------------------
author: hjjdebug
date: 2024年 07月 05日 星期五 11:02:51 CST
av_read_frame 代碼研究
------------------------------------------------------------

有人只標注一層,標注一層太膚淺了.不能了解底層之精妙.
有人給出調用框圖, 框圖又太籠統了,還是了解不了細節.
如果來一個完全的標注,那也有兩個毛病.
1. 代碼太多,篇幅太大.
2. 重點不突出, 一葉障目,窺不見森林.
那怎么做呢??
撿一個最深的調用為綱,搞清其工作原理,再輔以上下的各個問題解釋清楚。
做到綱舉目張.

想讀一個frame, 以ts文件為例, 它必需要讀文件, 并且它要在
合適的位置停止讀,因為數據已經構成了一個frame.

mpegts.c 就是ts 文件執行讀寫和分析的基礎文件
我在mpegts.c 中設下了一個斷點.
0 in mpegts_push_data of libavformat/mpegts.c:1377
1 in handle_packet of libavformat/mpegts.c:2846
2 in handle_packets of libavformat/mpegts.c:2975
3 in mpegts_read_packet of libavformat/mpegts.c:3219
4 in ff_read_packet of libavformat/utils.c:843
5 in read_frame_internal of libavformat/utils.c:1546
6 in av_read_frame of libavformat/utils.c:1750
7 in main of main.c:304

上層框架簡單,就是接口,調用別人干活,主要看下層,是具體的操作:
handel_packes:
?? ?它循環調用讀包, 每次讀188字節,處理包 handle_packet, 滿足條件才會退出.
handle_packet:
?? ?根據包的pid 可以拿到它的過濾器
?? ?MpegTsFilter ? tss = ts->pids[pid];
?? ?過濾器的類型也是在分析section 數據時建立的,例如pes 的過濾器是分析pmt表時建立的.
?? ?pmt表中記錄了每個節目包含哪些流(最常見的是一個音頻,一個視頻), 這些流的ID 是多少
?? ?如果過濾器的類型是PES, 就是說該小包數據是pes,就會回調pes_cb, 這就是mpegts_push_data
?? ?if (tss->type == MPEGTS_PES)?
?? ?{
?? ??? ?if ((ret = tss->u.pes_filter.pes_cb(tss, p, p_end - p, is_start,
?? ??? ??? ??? ??? ??? ??? ??? ??? ??? ??? ?pos - ts->raw_packet_size)) < 0)
?? ??? ?return ret;
?? ?}
?? ?就是說從id拿到對應的id對象(tss),然后調用對應的回調函數tss->u.pes_filter.pes_cb = mpegts_push_data
?? ?可見pes_cb并不是tss的直接成員,而是其下成員u.pes_filter的一個成員. 又多了一個中間管理者pes_filter
?? ?可以認為pes_filter和section_filter 是并列的,是一個聯合.
?? ? ? ?union {
? ? ? ? MpegTSPESFilter pes_filter;
? ? ? ? MpegTSSectionFilter section_filter;
? ? } u;

?? ?而tss是它們的上一級.
?? ?struct MpegTSFilter {
? ? int pid;
? ? int es_id;
? ? int last_cc; /* last cc code (-1 if first packet) */
? ? int64_t last_pcr;
? ? int discard;
? ? enum MpegTSFilterType type;
? ? union {
? ? ? ? MpegTSPESFilter pes_filter;
? ? ? ? MpegTSSectionFilter section_filter;
? ? } u;
};

mpegts_push_data:
?? ?它大部分時間是把負載直接copy到pes 數據區,但當數據copy夠了時,就設置退出條件.
?? ?所謂copy夠就是拷貝的pes數據pes->data_index 加頭部大小pes->header_size等于
?? ?pes包總大小加上pes包起始大小
?? ?switch(pes->state)
?? ?{
?? ?case MPEGTS_PAYLOAD
?? ? ? memcpy(pes->buffer->data + pes->data_index, p, buf_size);
?? ??? ?pes->data_index += buf_size;
?? ??? ?if (!ts->stop_parse && pes->total_size < MAX_PES_PAYLOAD &&
?? ??? ??? ?pes->pes_header_size + pes->data_index == pes->total_size + PES_START_SIZE)?
?? ??? ?{ //數據copy夠了,退出
?? ??? ??? ?ts->stop_parse = 1;
?? ??? ??? ?ret = new_pes_packet(pes, ts->pkt); //后面如果還有數,那就屬于新包數據了
?? ??? ??? ?if (ret < 0)
?? ??? ??? ??? ?return ret;
?? ??? ?}
?? ?}
//下面是 gdb 打印的某一次結果
(gdb) p pes->pes_header_size
$20 = 14
(gdb) p pes->data_index //此處是負載的位置索引
$21 = 2304
(gdb) p pes->total_size
$22 = 2312

14+2304 = 2312 + 6

下面我們來分析一個這幾個概念.
1. #define PES_START_SIZE ?6
pes包時由固定的3個字節00 00 01 及后面3個字節stream_id(1)+包長度(packet_length)
2. pes->total_size
這就是上面pes 頭部中的packet_length. 從碼流中得到的大小
它在代碼中什么位置賦值的?

?? ?pes->total_size = AV_RB16(pes->header + 4);
?? ?if (!pes->total_size)
?? ??? ?pes->total_size = MAX_PES_PAYLOAD; //200*1024
//當packet_length==0 時, 我們給最大的尺寸200K , 此時真正的大小要等到再遇到一個pes包頭來確定大小.

?? ?/* allocate pes buffer */
?? ?pes->buffer = buffer_pool_get(ts, pes->total_size);
?? ?if (!pes->buffer)
?? ??? ?return AVERROR(ENOMEM);

3. pes->pes_header_size
? ? ? if (pes->data_index == PES_HEADER_SIZE) ?//#define PES_HEADER_SIZE 9
?? ? ?{
?? ??? ?pes->pes_header_size = pes->header[8] + 9; //9字節是固定頭,前面6字節是start頭,后面3字節是可選頭部,
?? ??? ?pes->state ? ? ? ? ? = MPEGTS_PESHEADER_FILL;
? ? ? }
? ? ??
? 其中:
? pes->header[6], 加擾說明,版權說明等
? pes->header[7], 7個標志位,說明是否有option跟隨,例如pts,dts等等
? pes->header[8], 可選頭部的長度,1byte 不會超過255

? 頭部大小范圍,最大 MAX_PES_HEADER_SIZE (9+255)

4. pes->data_index
?當然是pes數據的位置索引了. 不過它的身份是變的, 一會是數據的索引,一會是負載的索引, 要看它的時機.
?變量嗎,就是變著來, 不過這樣容易混淆,用是簡單了,讀卻費勁了. 最好是分兩個或多個變量.角色應該唯一.
?就像變量i, 一會是這個的索引,一會是那個的索引,只要分的清,也可以不換名,因為用著簡單.

?小結:
?讀一個frame, 就是從原始數據中不停的讀, 讀到一個合適的位置停止讀,把有效的數據作為一個frame反饋給上層.
?當然,如果你不是從數據文件中讀,而是內存中已經有了,例如以鏈表形式或者數組形式,那copy給你就可以了.
?這就是av_read_frame的核心工作.
?

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

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

相關文章

Lianwei 安全周報|2024.07.01

新的一周又開始了&#xff0c;以下是本周「Lianwei周報」&#xff0c;我們總結推薦了本周的政策/標準/指南最新動態、熱點資訊和安全事件&#xff0c;保證大家不錯過本周的每一個重點&#xff01; 政策/標準/指南最新動態 01 出于安全考慮&#xff0c;拜登下令禁用卡巴斯基殺毒…

【康復學習--LeetCode每日一題】3115. 質數的最大距離

題目&#xff1a; 給你一個整數數組 nums。 返回兩個&#xff08;不一定不同的&#xff09;質數在 nums 中 下標 的 最大距離。 示例 1&#xff1a; 輸入&#xff1a; nums [4,2,9,5,3] 輸出&#xff1a; 3 解釋&#xff1a; nums[1]、nums[3] 和 nums[4] 是質數。因此答案是…

SpringBoot各類數量限制及超出后拋出的異常

前言 在使用SpringBoot開發接口時&#xff0c;動不動的就發生各種超過默認值的限制&#xff0c;這里總結了下SpringBoot默認限制的設置以及可能會發生的異常&#xff0c;便于問題的排查和快速修改默認值。 配置項配置項說明默認值超過大小后拋出的異常spring.servlet.multipa…

系統管理(System Keeping):全新迭代,優化您的開發體驗

隨著科技的不斷進步和用戶需求的日益增長&#xff0c;系統管理&#xff08;System Keeping&#xff09;不斷進行迭代更新&#xff0c;致力于為用戶帶來更加高效、便捷的開發體驗。本次全新迭代&#xff0c;不僅在界面與交互上進行了革新&#xff0c;更在功能整合、個性化與安全…

ECOLOGY9重置系統管理員密碼

ECOLOGY9系統管理員密碼忘記需要重置&#xff1a; 1、KB2110之后版本加了防篡改邏輯&#xff0c;數據庫中初始話密碼需要將hashdata、signdata更新為空&#xff0c;執行如下語句初始化 update HrmResourceManager set password ‘C4CA4238A0B923820DCC509A6F75849B’,salt‘’…

Android --- Service

出自于此&#xff0c;寫得很清楚。關于Android Service真正的完全詳解&#xff0c;你需要知道的一切_android service-CSDN博客 出自【zejian的博客】 什么是Service? Service(服務)是一個一種可以在后臺執行長時間運行操作而沒有用戶界面的應用組件。 服務可由其他應用組件…

萬字長文|關于 OpenAI 接口開發你應該知道的一切

這篇文章中個人結合自己的實踐經驗把 OpenAI 官方文檔解讀一遍。但是原文檔涉及內容眾多&#xff0c;包括微調&#xff0c;嵌入&#xff08;Embeddings&#xff09;等眾多主題&#xff0c;我這里重點挑選自己開發高頻使用到的&#xff0c;需要詳細了解的可以自行前往官網閱讀。…

Java中的文本搜索與全文檢索引擎

Java中的文本搜索與全文檢索引擎 大家好&#xff0c;我是免費搭建查券返利機器人省錢賺傭金就用微賺淘客系統3.0的小編&#xff0c;也是冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01; 在現代應用程序中&#xff0c;處理和搜索大量文本數據是一項關鍵任務。傳統的…

2024科技文化節程序設計競賽

補題鏈接 https://www.luogu.com.cn/contest/178895#problems A. 簽到題 忽略掉大小為1的環&#xff0c;答案是剩下環的大小和減環的數量 #include<bits/stdc.h> #include<iostream> #include<cstdio> #include<vector> #include<map> #incl…

c進階篇(四):內存函數

內存函數以字節為單位更改 1.memcpy memcpy 是 C/C 中的一個標準庫函數&#xff0c;用于內存拷貝操作。它的原型通常定義在 <cstring> 頭文件中&#xff0c;其作用是將一塊內存中的數據復制到另一塊內存中。 函數原型&#xff1a;void *memcpy(void *dest, const void…

多模態融合算法應用:CT + 臨床文本數據 + pyradiomics提取到的圖像特征

多模態融合算法應用 CT 臨床文本數據 pyradiomics提取圖像特征 單模態建模臨床數據建模pyradiomics提取圖像特征建模CT建模 多模態建模前融合為什么能直接合并在一起&#xff1f; 后融合Med-CLIP&#xff1a;深度學習 可解釋性 單模態建模 臨床數據建模 臨床文本數據&…

WPF Menu實現快捷鍵操作

很多小伙伴說&#xff0c;在Menu中&#xff0c;實現單個快捷鍵操作很簡單&#xff0c;怎么實現多個快捷鍵操作和&#xff0c;組合快捷鍵呢&#xff0c;今天他來了。 上代碼和效果圖 一、Ctrl Shift 任意子母鍵實現快捷鍵組合 <Window x:Class"XH.TemplateLesson.M…

【測試開發】【postman】按順序循環執行接口

postman按順序循環執行接口 新建接口接口排序執行請求集合 新建接口 Request 001 Request 002 Request 003 接口排序 在Request 001的Tests中添加代碼 postman.setNextRequest("Request 002");在Request 002的Tests中添加代碼 postman.setNextRequest("Requ…

Redis 7.x 系列【17】四種持久化策略

有道無術&#xff0c;術尚可求&#xff0c;有術無道&#xff0c;止于術。 本系列Redis 版本 7.2.5 源碼地址&#xff1a;https://gitee.com/pearl-organization/study-redis-demo 文章目錄 1. 概述2. 案例演示2.1 無持久化2.2 RDB2.3 AOF2.4 混合模式2.4.1 方式一&#xff1a;…

線性代數|機器學習-P21概率定義和Markov不等式

文章目錄 1. 樣本期望和方差1.1 樣本期望 E ( X ) \mathrm{E}(X) E(X)1.2 樣本期望 D ( X ) \mathrm{D}(X) D(X) 2. Markov 不等式&Chebyshev不等式2.1 Markov不等式公式 概述2.2 Markov不等式公式 證明&#xff1a;2.3 Markov不等式公式 舉例&#xff1a;2.4 Chebyshev不…

AI繪畫 Stable Diffusion圖像的臉部細節控制——采樣器全解析

大家好&#xff0c;我是畫畫的小強 我們在運用AI繪畫 Stable Diffusion 這一功能強大的AI繪圖工具時&#xff0c;我們往往會發現自己對提示詞的使用還不夠充分。在這種情形下&#xff0c;我們應當如何調整自己的策略&#xff0c;以便更加精確、全面地塑造出理想的人物形象呢&a…

域環境提權

域內提權漏洞(1) Netlogon域權限提升 1.查看域控主機名稱 net group "domain controllers" /domain 2.檢測漏洞是否存在 https://github.com/SecuraBV/CVE-2020-1472.git python zerologon_tester.py OWA 192.168.52.138 3.漏洞利用&#xff0c;對域賬號重置 ht…

《簡歷寶典》01 - 一文帶你學會如何寫一份糟糕透頂的簡歷

我們每個人幾乎都會面對找工作這件事&#xff0c;而找工作或者說求職首先就是要寫一份簡歷。今天狗哥將以一個不同的視角帶你寫一份無與倫比&#xff0c;糟糕透頂的求職簡歷&#xff0c;說實話&#xff0c;其實幾年前&#xff0c;我就是這么寫的。 目錄 1. 文件名 2. 基本信…

【項目管理】項目風險管理(Word原件)

風險和機會管理就是在一個項目開發過程中對風險進行識別、跟蹤、控制的手段。風險和機會管理提供了對可能出現的風險進行持續評估&#xff0c;確定重要的風險機會以及實施處理的策略的一種規范化的環境。包括識別、分析、制定處理和減緩行動、跟蹤 。合理的風險和機會管理應盡力…

白騎士的Python教學進階篇 2.4 高級數據結構

系列目錄 上一篇&#xff1a;白騎士的Python教學進階篇 2.3 文件操作??????? 在Python中&#xff0c;掌握高級數據結構可以顯著提升你的編程效率和代碼可讀性。高級數據結構包括列表推導式、生成器與迭代器以及裝飾器。本文將詳細介紹這些高級數據結構&#xff0c;幫助…