AVFormatContext 再分析

說明 :將 avfromatContext 的變量依次打印分析,根據ffmpeg 給的說明,猜測,結合網上的文章字節寫測試代碼分析。

從常用到不常用依次分析

1. unsigned int nb_streams;

代表 avfromatContext 中 AVStream **streams 的個數

? ? /**
? ? ?* Number of elements in AVFormatContext.streams.
? ? ?*
? ? ?* Set by avformat_new_stream(), must not be modified by any other code.
? ? ?*/
? ? unsigned int nb_streams;

//打印在解復用時候,avformatContext的主要參數
void PrintfDeMuxingAVFormatContextMainParamter(AVFormatContext* avformatContext) {if (avformatContext == NULL) {cout << "func PrintfDeMuxingAVFormatContextMainParamter error because AVFormatContext == nullptr  " << endl;return;}cout << "avformat中有的avstream的個數為:avformatContext->nb_streams = " << avformatContext->nb_streams << endl;}

2. int64_t bit_rate;

在?AVFormatContext?結構體中,?bit_rate?字段表示媒體文件的全局平均比特率?(單位為 bps,即 bits per second)

? ? /**
? ? ?* Total stream bitrate in bit/s, 0 if not
? ? ?* available. Never set it directly if the file_size and the
? ? ?* duration are known as FFmpeg can compute it automatically.
? ? ?*/
? ? int64_t bit_rate;

2.1 含義再說明1

從說明中可以看出來,代表的是所有 stream 的 平均比特率。啥意思呢?比如這是一個mp4文件,既有視頻也有音頻,我們假設有一個視頻兩個音頻(粵語和普通話),假設視頻是300kbps,普通話音頻是128kbps,粵語音頻是100kbps。那么 AVFormatContext?中的?bit_rate就應該等于 300 +128+100 = 628kbps,注意單位是kbps。

// 遍歷所有流,計算總比特率
int64_t total_bit_rate = 0;
for (int i = 0; i < avformat_ctx->nb_streams; i++) {AVStream *stream = avformat_ctx->streams[i];total_bit_rate += stream->codecpar->bit_rate;
}

2.2 含義再說明2,在TS下無效

0 if not?available

這個意思是說,這個值有可能是0,代表不可使用。

部分封裝格式(如 TS 流)可能不記錄全局比特率,此時?bit_rate?字段無效

2.3?含義再說明3,當文件大小和duration都知道的時候,user不要設置,ffmepg會自動計算

Never set it directly if the file_size and the duration are known as FFmpeg can compute it automatically.

2.5?動態碼率場景?


VBR 編碼的文件中,該字段僅代表平均值,無法反映瞬時碼率波動

CBR 是?(恒定比特率)

VBR(可變比特率),

mp4文件只能是 VBR。

也就是說:如果我們解析的是mp4文件,那么這個值是平均值。無法反映瞬時碼率波動

2.6?典型應用場景?

  • ?帶寬估算?:
    結合容器和流的比特率,判斷網絡傳輸是否滿足實時播放需求56。
  • ?文件分析工具?:
    統計媒體文件的碼率分布,輔助編碼參數優化6。

3. int64_t duration

只能用于解復用,

是 ?AVFormatContext 結構體?的關鍵成員,用于表示 ?媒體文件的總時長?。其數據類型為?int64_t,單位為 ?AV_TIME_BASE?(即微秒的倒數,通常為 1,000,000)。

該字段在 ?成功解析媒體文件流信息后?(調用?avformat_find_stream_info())才會被正確賦值

? ? /**
? ? ?* Duration of the stream, in AV_TIME_BASE fractional
? ? ?* seconds. Only set this value if you know none of the individual stream
? ? ?* durations and also do not set any of them. This is deduced from the
? ? ?* AVStream values if not set.
? ? ?*
? ? ?* Demuxing only, set by libavformat.
? ? ?*/
? ? int64_t duration;

主要使用場景,通過 duration 計算文件時長。

?換算為秒?:

double duration_sec = (double)avformatContext->duration / AV_TIME_BASE;
 

?轉換為時分秒格式?:

int64_t total_us = avformatContext->duration + 5000;  // 四舍五入修正
int hours = total_us / (3600 * AV_TIME_BASE);
int mins = (total_us % (3600 * AV_TIME_BASE)) / (60 * AV_TIME_BASE);
int secs = (total_us % (60 * AV_TIME_BASE)) / AV_TIME_BASE;

常見問題與解決方案

?問題??原因??解決方案?
?返回負值或極大值?未正確解析流信息或文件不完整調用?avformat_find_stream_info()?前設置?max_analyze_duration?參數
?單位換算錯誤?未使用 AV_TIME_BASE 進行轉換確保除以?AV_TIME_BASE(或使用?av_rescale_q()?函數)
?時間精度丟失?直接截斷未四舍五入添加 5000 微秒偏移(如?+5000)后再計算

AVFormatContext *fmt_ctx = NULL;
avformat_open_input(&fmt_ctx, filename, NULL, NULL);  // 打開文件
fmt_ctx->max_analyze_duration = 5 * AV_TIME_BASE;     // 限制解析時長避免卡頓
avformat_find_stream_info(fmt_ctx, NULL);              // 解析流信息if (fmt_ctx->duration != AV_NOPTS_VALUE) {int64_t duration = fmt_ctx->duration + 5000;      // 修正精度int hours = duration / (3600 * AV_TIME_BASE);int mins = (duration % (3600 * AV_TIME_BASE)) / (60 * AV_TIME_BASE);int secs = (duration % (60 * AV_TIME_BASE)) / AV_TIME_BASE;printf("Duration: %02d:%02d:%02d\n", hours, mins, secs);
} else {printf("Duration unavailable\n");
}
avformat_close_input(&fmt_ctx);                       // 釋放資源

適用場景

  • ?媒體信息分析工具?:如?ffprobe?使用該字段輸出文件時長。
  • ?播放器開發?:用于顯示進度條總時長。
  • ?流媒體處理?:結合?AVStream?中各流時長進行同步控制。

?注意?:在網絡流或實時流中,duration?可能無法獲取(值為?AV_NOPTS_VALUE),需動態計算

cout << "avformat中duration為:avformatContext->duration = " << avformatContext->duration << endl;double duration_sec = (double)avformatContext->duration / AV_TIME_BASE;
cout << "avformat中秒數為:duration_sec = " << duration_sec << endl;if (avformatContext->duration != AV_NOPTS_VALUE) {int64_t duration = avformatContext->duration + 5000;      // 修正精度int hours = duration / (3600 * AV_TIME_BASE);int mins = (duration % (3600 * AV_TIME_BASE)) / (60 * AV_TIME_BASE);int secs = (duration % (60 * AV_TIME_BASE)) / AV_TIME_BASE;printf("Duration: %02d:%02d:%02d\n", hours, mins, secs);
}else {printf("Duration unavailable\n");
}avformat中duration為:avformatContext->duration = 60024000
avformat中秒數為:duration_sec = 60.024
Duration: 00:01:00

4. char *url;

? ? /**
? ? ?* input or output URL. Unlike the old filename field, this field has no
? ? ?* length restriction.
? ? ?*
? ? ?* - demuxing: set by avformat_open_input(), initialized to an empty
? ? ?* ? ? ? ? ? ? string if url parameter was NULL in avformat_open_input().
? ? ?* - muxing: may be set by the caller before calling avformat_write_header()
? ? ?* ? ? ? ? ? (or avformat_init_output() if that is called first) to a string
? ? ?* ? ? ? ? ? which is freeable by av_free(). Set to an empty string if it
? ? ?* ? ? ? ? ? was NULL in avformat_init_output().
? ? ?*
? ? ?* Freed by libavformat in avformat_free_context().
? ? ?*/
? ? char *url;

和之前的filename不同,url是沒有長度限制的。

在解碼時,通過 avformat_open_input 方法 會將url 記錄到 AVFormatContext ,可能會nullptr。

在編碼時,需要在 調用 avformat_write_header 方法之前設置。

   char * url =  avformatContext->url;cout << "avformat中duration為 url = " << url << endl;結果為:avformat中duration為 url = ./120/400_300_25.mp4

5. int64_t start_time;

? ? /**
? ? ?* Position of the first frame of the component, in
? ? ?* AV_TIME_BASE fractional seconds. NEVER set this value directly:
? ? ?* It is deduced from the AVStream values.
? ? ?*
? ? ?* Demuxing only, set by libavformat.
? ? ?*/
? ? int64_t start_time;

組件第一幀的位置,以AV_TIME_BASE? 為單位。?
切勿直接設置此值:它是從AVStream值推斷出來的。

這玩意有啥用呢?表示該avformatContext 第一幀的開始時間,那么應該都是0。

可能的點:todo

如果我們從文件的中間位置讀取的,那么這個值就不是0?

在網絡流的時候用?

   int64_t starttime = avformatContext->start_time;cout << "avformat中duration為 starttime = " << starttime << endl;avformat中duration為 starttime = 0

6.?接下來都是非重點 AVCodec* audio_codec;

? ? /**
? ? ?* Forced audio codec.
? ? ?* This allows forcing a specific decoder, even when there are multiple with the same codec_id.
? ? ?* Demuxing: Set by user
? ? ?*/
? ? AVCodec *audio_codec;

這里從翻譯來看,意思是該變量是為了 音頻的編解碼。

允許在解碼的時候,允許強制使用特定的解碼器,即使存在多個具有相同codec_id的解碼器

/**
?* Forced audio codec.
?* This allows forcing a specific decoder, even when there are multiple with the same codec_id.
?* Demuxing: Set by user
?* AVCodec* audio_codec;
?* 在 音頻 編解碼器 的時候使用,
?* 在解復用的時候,允許強制使用特定的解碼器,即使存在多個具有相同codec_id的解碼器
?* 我們使用test02測試
?*/

avformatContext->audio_codec;cout << "avformatContext->audio_codec = " << avformatContext->audio_codec << endl;


?* 在 音頻 編解碼器 的時候使用,
?* 在解復用的時候,允許強制使用特定的解碼器,即使存在多個具有相同codec_id的解碼器

   AVCodec* audioavcodec = avformatContext->audio_codec;if (audioavcodec == nullptr) {cout << "audioavcodec == nullptr" << endl;}else {cout << "audioavcodec != nullptr  audioavcodec->id = " << audioavcodec->id << endl;}log 為:audioavcodec == nullptr

last

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

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

相關文章

計算機網絡-運輸層(1)

計算機網絡-運輸層(1) 文章目錄 計算機網絡-運輸層(1)5.1 運輸層概述5.2 運輸層端口號、復用與分用端口號基本概念端口號特性端口號分類重要說明 5.3 UDP與TCP協議對比關鍵區別說明 5.1 運輸層概述 計算機網絡體系結構中的物理層、數據鏈路層以及網絡層共同解決了主機通過異構…

2025 FIC wp

這次比賽計算機和手機大部分題目都比較常規 第一和第四部分有點讓人摸不著頭腦 比賽的時候第一部分有四個題沒出 第四部分基本都沒怎么出 現在復盤一下 把我當時做題的心得和獲取的新知識記錄一下 互聯網取證的部分就先學習一下別的師傅 檢材 鏈接&#xff1a;https://pan.bai…

【大數據技術-聯邦集群RBF】DFSRouter日志一直打印修改Membership為EXPIRED狀態的日志分析

生產環境遇到下面報錯 2025-04-23 17:44:15,780 INFO store.CachedRecordStore (CachedRecordStore.java:overrideExpiredRecords(192)) - Override State Store record MembershipState: router1:8888->hh-fed-sub25:nn2:nn2:8020-EXPIRED 2025-04-23 17:44:15,781 INFO …

【HarmonyOS 5】鴻蒙檢測系統完整性

【HarmonyOS 5】鴻蒙檢測系統完整性 一、前言 從現實安全威脅來看&#xff0c;設備系統完整性風險已影響至移動應用的各個場景。不少用戶因使用越獄設備&#xff08;Jailbreak&#xff09;或非真實設備&#xff08;Emulator&#xff09;&#xff0c;導致應用安全防護機制失效…

學習spark-streaming收獲

1.流處理的核心概念 ?實時 vs微批處理&#xff1a;理解了 Spark Streaming 的微批處理&#xff08;Micro-Batch&#xff09;模型&#xff0c;將流數據切分為小批次&#xff08;如1秒間隔&#xff09;進行處理&#xff0c;與真正的流處理&#xff08;如Flink&#xff09;的區…

Redis一些小記錄

Redis一些小記錄 SpringData Redis&#xff1a;RedisTemplate配置與數據操作 操作String類型數據 String是Redis中最基本的數據類型&#xff0c;可以存儲字符串、整數或浮點數。RedisTemplate提供了ValueOperations接口來操作String類型的數據&#xff0c;支持設置值、獲取值、…

5G融合消息PaaS項目深度解析 - Java架構師面試實戰

5G融合消息PaaS項目深度解析 - Java架構師面試實戰 場景&#xff1a;互聯網大廠Java求職者面試&#xff0c;面試官針對5G融合消息PaaS項目進行提問。 第一輪提問 面試官&#xff1a;馬架構&#xff0c;請簡要介紹5G融合消息PaaS平臺的核心功能和應用場景。 馬架構&#xff…

【C語言極簡自學筆記】C 語言數組詳解:一維數組與二維數組

在 C 語言中&#xff0c;數組是一種非常重要的數據結構&#xff0c;它可以將多個相同類型的元素組織在一起&#xff0c;以便于我們進行批量處理和操作。本文將詳細介紹 C 語言中的一維數組和二維數組&#xff0c;包括它們的定義、初始化、元素訪問以及內存存儲等方面的內容。 …

04.通過OpenAPI-Swagger規范讓Dify玩轉Agent

dify安裝 cd dify cd docker cp .env.example .env docker compose up -d準備自定義工具 我自建的PowerDNS&#xff0c;它的swagger如下&#xff1a; https://github.com/PowerDNS/pdns/blob/master/docs/http-api/swagger/authoritative-api-swagger.yaml 但需要加上&#x…

汽車產業鏈主表及類別表設計

&#xff08;提前設計&#xff0c;備用&#xff09; 一、汽車產業鏈類別表&#xff08;industry_chain_category&#xff09; 設計要點 1、核心字段&#xff1a;定義產業鏈分類&#xff08;如零部件、整車制造、銷售服務等&#xff09; 2、主鍵約束&#xff1a;自增ID作為唯一標…

?RISC-V架構的低功耗MCU多電壓域優化設計

RISC-V核低功耗MCU的多電壓域設計是一種優化電源管理以降低功耗的技術方案。該設計通過電源域劃分、電壓轉換和時序管理等手段&#xff0c;有效降低了系統功耗并提升能效&#xff0c;適用于物聯網和嵌入式系統等場景。 多電壓域設計的基本原理是將芯片劃分為多個獨立供電區域&…

基于STM32、HAL庫的AD7616BSTZ模數轉換器ADC驅動程序設計

一、簡介: AD7616BSTZ是Analog Devices公司生產的一款16位、雙通道、同步采樣SAR型ADC芯片,主要特點包括: 16位分辨率 雙通道同步采樣 最高采樣率:1MSPS/通道 輸入范圍:10V, 5V或2.5V(軟件可編程) 串行(SPI)和并行接口選項 低功耗:典型值100mW 工作溫度范圍:-40C至+8…

CUDA Stream 回調函數示例代碼

文章目錄 CUDA Stream 回調函數示例代碼基本概念示例代碼代碼解釋回調函數的特點更復雜的示例&#xff1a;多個回調注意事項 CUDA Stream 回調函數中使用 MPI 或 NCCL示例程序注意事項 CUDA Stream 回調函數示例代碼 CUDA 中的流回調函數(stream callback)是一種在 CUDA 流中插…

全棧黑暗物質:可觀測性之外的非確定性調試

一、量子計算的測不準Bug 1. 經典 vs. 量子系統的錯誤模式 量子程序崩潰的觀測影響&#xff1a; 調試方法崩潰復現率觀測干擾度日志打印12%35%斷點調試5%78%無侵入跟蹤27%9%量子態層析成像63%2% 二、量子調試工具箱 1. 非破壞性觀測協議 # 量子程序的無干擾快照 from qiski…

ASP.NET8.0入門與實戰

1、項目初始化 創建一個ASP.NET Core Web API的項目&#xff0c;取消Https和身份驗證。 API項目實際上是一個控制臺程序&#xff0c;這點可以在項目的屬性的輸出類型中看到。 launchSettings.json&#xff0c;在這里可以配置運行項目的名稱&#xff0c;端口號&#xff0c;路…

Synopsys 邏輯綜合的整體架構概覽

目錄 一、DC Shell 邏輯綜合的整體架構概覽 ?? 邏輯綜合的主要階段&#xff08;Pipeline&#xff09; 二、核心架構模塊詳解 1. Internal Database&#xff08;設計對象數據庫&#xff09; 2. Scheduler&#xff08;調度器&#xff09; 3. Rewriting Engine&#xff08…

低壓電工常見知識點

一.工廠用電 1.工廠一般有電源380V和220V。 三相:黃綠紅 藍 雙色 助記符:王力宏 分別對應第一相(R),第二相(S)&#xff0c;第三相(T)&#xff0c;零線(N),地線(PE) 單相:紅 黑 對應火線(L) 零線(N) 左零右火 二.人體安全電壓是36V 三.變壓器的講解 變壓器的符號…

【沉浸式求職學習day27】

沉浸式求職學習 家人們誰懂啊&#xff01;明天下午又實習筆試了&#xff0c;所以今天大部分時間還是在搞一些行測之類的東西&#xff0c;所以今天沒什么分享給大家的&#xff0c;明晚會簡單的和大家分享一下關于數據庫的一些東西&#xff0c;以及和大家聊聊我筆試的感覺哈哈哈哈…

進入救援模式(物理服務器)

目錄 **?? 準備工作****?? 進入救援模式(物理服務器)****方法 1:直接修改啟動參數****適用情況****操作步驟****方法 2:通過GRUB引導菜單進入(系統未完全崩潰時)****適用情況****操作步驟****兩者的核心區別****如何選擇?****注意事項****總結**當物理服務器無法正常…

基于Pytest接口自動化的requests模塊項目實戰以及接口關聯方法詳解

&#x1f345; 點擊文末小卡片&#xff0c;免費獲取軟件測試全套資料&#xff0c;資料在手&#xff0c;漲薪更快 1、基于pytest單元測試框架的規則 1.1 模塊名&#xff08;即文件名&#xff09;必須以test_開頭或者_test結尾 1.2 類名必須以Test開頭且不能有init方法 1.3 用…