最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

FFmpeg實(shí)戰(zhàn)之分離出PCM數(shù)據(jù)

 更新時(shí)間:2023年02月10日 10:34:23   作者:怪我冷i  
PCM(Pulse?Code?Modulation,脈沖編碼調(diào)制)音頻數(shù)據(jù)是未經(jīng)壓縮的音頻采樣數(shù)據(jù)裸流,它是由模擬信號(hào)經(jīng)過(guò)采樣、量化、編碼轉(zhuǎn)換成的標(biāo)準(zhǔn)數(shù)字音頻數(shù)據(jù)。本文將通過(guò)FFmpeg實(shí)現(xiàn)分離PCM數(shù)據(jù),感興趣的可以了解一下

什么是PCM

PCM(Pulse Code Modulation,脈沖編碼調(diào)制)音頻數(shù)據(jù)是未經(jīng)壓縮的音頻采樣數(shù)據(jù)裸流,它是由模擬信號(hào)經(jīng)過(guò)采樣、量化、編碼轉(zhuǎn)換成的標(biāo)準(zhǔn)數(shù)字音頻數(shù)據(jù)。

描述PCM數(shù)據(jù)的6個(gè)參數(shù):

  • Sample Rate : 采樣頻率。8kHz(電話)、44.1kHz(CD)、48kHz(DVD)。
  • Sample Size : 量化位數(shù)。通常該值為16-bit。
  • Number of Channels : 通道個(gè)數(shù)。常見(jiàn)的音頻有立體聲(stereo)和單聲道(mono)兩種類(lèi)型,立體聲包含左聲道和右聲道。另外還有環(huán)繞立體聲等其它不太常用的類(lèi)型。
  • Sign : 表示樣本數(shù)據(jù)是否是有符號(hào)位,比如用一字節(jié)表示的樣本數(shù)據(jù),有符號(hào)的話表示范圍為-128 ~ 127,無(wú)符號(hào)是0 ~ 255。
  • Byte Ordering : 字節(jié)序。字節(jié)序是little-endian還是big-endian。通常均為little-endian。字節(jié)序說(shuō)明見(jiàn)第4節(jié)。
  • Integer Or Floating Point : 整形或浮點(diǎn)型。大多數(shù)格式的PCM樣本數(shù)據(jù)使用整形表示,而在一些對(duì)精度要求高的應(yīng)用方面,使用浮點(diǎn)類(lèi)型表示PCM樣本數(shù)據(jù)。

字節(jié)序

字節(jié)序是指多字節(jié)數(shù)據(jù)在計(jì)算機(jī)內(nèi)存中存儲(chǔ)或者網(wǎng)絡(luò)傳輸時(shí)各字節(jié)的存儲(chǔ)順序。

大端字節(jié)序(Big Endian):將多個(gè)字節(jié)值的最高有效字節(jié)儲(chǔ)存于較低的內(nèi)存位置。在大端處理器的機(jī)器上,數(shù)值0xABCD1234在內(nèi)存存儲(chǔ)為連續(xù)字節(jié)0xAB、0xCD、0x12、0x34。

小端字節(jié)序(Little endian):將多個(gè)字節(jié)值的最低有效字節(jié)存儲(chǔ)于較低的內(nèi)存位置。比如在小段處理器的機(jī)器上,數(shù)值0xABCD1234在內(nèi)存中存儲(chǔ)為連續(xù)的字節(jié)0x34、0x12、0xCD、0x341。

FFmpeg支持的PCM數(shù)據(jù)格式

在cmder中使用ffmpeg -formats | grep PCM命令,獲取ffmpeg支持的音視頻格式,其中我們可以找到支持的PCM格式。

 DE alaw            PCM A-law
 DE f32be           PCM 32-bit floating-point big-endian
 DE f32le           PCM 32-bit floating-point little-endian
 DE f64be           PCM 64-bit floating-point big-endian
 DE f64le           PCM 64-bit floating-point little-endian
 DE mulaw           PCM mu-law
 DE s16be           PCM signed 16-bit big-endian
 DE s16le           PCM signed 16-bit little-endian
 DE s24be           PCM signed 24-bit big-endian
 DE s24le           PCM signed 24-bit little-endian
 DE s32be           PCM signed 32-bit big-endian
 DE s32le           PCM signed 32-bit little-endian
 DE s8              PCM signed 8-bit
 DE u16be           PCM unsigned 16-bit big-endian
 DE u16le           PCM unsigned 16-bit little-endian
 DE u24be           PCM unsigned 24-bit big-endian
 DE u24le           PCM unsigned 24-bit little-endian
 DE u32be           PCM unsigned 32-bit big-endian
 DE u32le           PCM unsigned 32-bit little-endian
 DE u8              PCM unsigned 8-bit
 DE vidc            PCM Archimedes VIDC

s是有符號(hào),u是無(wú)符號(hào),f是浮點(diǎn)數(shù)。

be是大端,le是小端。

FFmpeg中Packed和Planar的PCM數(shù)據(jù)區(qū)別

FFmpeg中音視頻數(shù)據(jù)基本上都有Packed(打包格式)和Planar(平面格式)兩種存儲(chǔ)方式,對(duì)于雙聲道音頻來(lái)說(shuō),Packed方式為兩個(gè)聲道的數(shù)據(jù)交錯(cuò)存儲(chǔ);Planar方式為兩個(gè)聲道分開(kāi)存儲(chǔ)。假設(shè)一個(gè)L/R為一個(gè)采樣點(diǎn),數(shù)據(jù)存儲(chǔ)的方式如下所示:

  • Packed: L R L R L R L R
  • Planar: L L L L R R R R

FFmpeg音頻解碼后的數(shù)據(jù)是存放在AVFrame結(jié)構(gòu)中的。

  • Packed格式,frame.data[0]或frame.extended_data[0]包含所有的音頻數(shù)據(jù)中。
  • Planar格式,frame.data[i]或者frame.extended_data[i]表示第i個(gè)聲道的數(shù)據(jù)(假設(shè)聲道0是第一個(gè)), AVFrame.data數(shù)組大小固定為8,如果聲道數(shù)超過(guò)8,需要從frame.extended_data獲取聲道數(shù)據(jù)。

下面為FFmpeg內(nèi)部存儲(chǔ)音頻使用的采樣格式,所有的Planar格式后面都有字母P標(biāo)識(shí)。

enum AVSampleFormat {
    AV_SAMPLE_FMT_NONE = -1,
    AV_SAMPLE_FMT_U8,          ///< unsigned 8 bits
    AV_SAMPLE_FMT_S16,         ///< signed 16 bits
    AV_SAMPLE_FMT_S32,         ///< signed 32 bits
    AV_SAMPLE_FMT_FLT,         ///< float
    AV_SAMPLE_FMT_DBL,         ///< double

    AV_SAMPLE_FMT_U8P,         ///< unsigned 8 bits, planar
    AV_SAMPLE_FMT_S16P,        ///< signed 16 bits, planar
    AV_SAMPLE_FMT_S32P,        ///< signed 32 bits, planar
    AV_SAMPLE_FMT_FLTP,        ///< float, planar
    AV_SAMPLE_FMT_DBLP,        ///< double, planar
    AV_SAMPLE_FMT_S64,         ///< signed 64 bits
    AV_SAMPLE_FMT_S64P,        ///< signed 64 bits, planar

???????    AV_SAMPLE_FMT_NB           ///< Number of sample formats. DO NOT USE if linking dynamically
};

說(shuō)明:

Planar模式是ffmpeg內(nèi)部存儲(chǔ)模式,我們實(shí)際使用的音頻文件都是Packed模式的。

FFmpeg解碼不同格式的音頻輸出的音頻采樣格式不是一樣。測(cè)試發(fā)現(xiàn),其中AAC解碼輸出的數(shù)據(jù)為浮點(diǎn)型的 AV_SAMPLE_FMT_FLTP 格式,MP3解碼輸出的數(shù)據(jù)為 AV_SAMPLE_FMT_S16P 格式(使用的mp3文件為16位深)。具體采樣格式可以查看解碼后的AVFrame中的format成員或解碼器的AVCodecContext中的sample_fmt成員。

Planar或者Packed模式直接影響到保存文件時(shí)寫(xiě)文件的操作,操作數(shù)據(jù)的時(shí)候一定要先檢測(cè)音頻采樣格式。

實(shí)戰(zhàn)FFmpeg分離出PCM數(shù)據(jù)

先用ffprobe命令查看文件詳情

ffprobe -i input.mp4

詳情

#音頻
  Stream #0:0(und): Audio: aac (LC) (mp4a / 0x6134706D), 
  44100 Hz, stereo, fltp, 128 kb/s (default)
    Metadata:
      creation_time   : 2020-10-12T15:12:33.000000Z
      vendor_id       : [0][0][0][0]
#視頻      
  Stream #0:1(und): Video: h264 (High) (avc1 / 0x31637661), 
  yuv420p, 368x384, 383 kb/s, 29.95 fps, 
  29.97 tbr, 90k tbn, 60 tbc (default)
    Metadata:
      creation_time   : 2020-10-12T15:12:33.000000Z
      vendor_id       : [0][0][0][0]
      encoder         : JVT/AVC Coding

用ffmpeg命令轉(zhuǎn)換

ffmpeg -i input.mp4 -ar 44100 -ac 2 -f s16le output.pcm

其中

# 輸入文件
-i 
# 格式
-f fmt              force format
#設(shè)置音頻采樣率
-ar rate            set audio sampling rate (in Hz)
#設(shè)置音頻通道數(shù)
-ac channels        set number of audio channels

輸出

Audicity播放

文件-原理音頻

分離雙聲道PCM音頻數(shù)據(jù)左右聲道的數(shù)據(jù)

按照雙聲道的LRLRLR的PCM音頻數(shù)據(jù)可以通過(guò)將它們交叉的讀出來(lái)的方式來(lái)分離左右聲道的數(shù)據(jù)。

int pcm_s16le_split(const char* file, const char* out_lfile, const char* out_rfile) {
     FILE *fp = fopen(file, "rb+");
     if (fp == NULL) {
         printf("open %s failed\n", file);
         return -1;
     }
     FILE *fp1 = fopen(out_lfile, "wb+");
     if (fp1 == NULL) {
         printf("open %s failed\n", out_lfile);
         return -1;
     }
     FILE *fp2 = fopen(out_rfile, "wb+");
     if (fp2 == NULL) {
         printf("open %s failed\n", out_rfile);
         return -1;
     }
     char * sample = (char *)malloc(4);
     while(!feof(fp)) {
         fread(sample, 1, 4, fp);
         //L
         fwrite(sample, 1, 2, fp1);
         //R
         fwrite(sample + 2, 1, 2, fp2);
     }
     free(sample);
     fclose(fp);
     fclose(fp1);
     fclose(fp2);
     return 0;
 }

函數(shù)說(shuō)明

fread函數(shù)

描述

C 庫(kù)函數(shù) size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream) 從給定流 stream 讀取數(shù)據(jù)到 ptr 所指向的數(shù)組中。

聲明

下面是 fread() 函數(shù)的聲明。

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)

參數(shù)

  • ptr – 這是指向帶有最小尺寸 size*nmemb 字節(jié)的內(nèi)存塊的指針。
  • size – 這是要讀取的每個(gè)元素的大小,以字節(jié)為單位。
  • nmemb – 這是元素的個(gè)數(shù),每個(gè)元素的大小為 size 字節(jié)。
  • stream – 這是指向 FILE 對(duì)象的指針,該 FILE 對(duì)象指定了一個(gè)輸入流。

返回值

成功讀取的元素總數(shù)會(huì)以 size_t 對(duì)象返回,size_t 對(duì)象是一個(gè)整型數(shù)據(jù)類(lèi)型。如果總數(shù)與 nmemb 參數(shù)不同,則可能發(fā)生了一個(gè)錯(cuò)誤或者到達(dá)了文件末尾。

fwrite函數(shù)

描述

C 庫(kù)函數(shù) size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) 把 ptr 所指向的數(shù)組中的數(shù)據(jù)寫(xiě)入到給定流 stream 中。

聲明

下面是 fwrite() 函數(shù)的聲明。

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)

參數(shù)

  • ptr – 這是指向要被寫(xiě)入的元素?cái)?shù)組的指針。
  • size – 這是要被寫(xiě)入的每個(gè)元素的大小,以字節(jié)為單位。
  • nmemb – 這是元素的個(gè)數(shù),每個(gè)元素的大小為 size 字節(jié)。
  • stream – 這是指向 FILE 對(duì)象的指針,該 FILE 對(duì)象指定了一個(gè)輸出流。

返回值

如果成功,該函數(shù)返回一個(gè) size_t 對(duì)象,表示元素的總數(shù),該對(duì)象時(shí)一個(gè)整型數(shù)據(jù)類(lèi)型。如果該數(shù)字與 nmemb 參數(shù)不同,則會(huì)顯示一個(gè)錯(cuò)誤。

fopen函數(shù)

描述

C 庫(kù)函數(shù) FILE *fopen(const char *filename, const char *mode) 使用給定的模式 mode 打開(kāi) filename 所指向的文件。

聲明

下面是 fopen() 函數(shù)的聲明。

FILE *fopen(const char *filename, const char *mode)

參數(shù)

  • filename – 這是 C 字符串,包含了要打開(kāi)的文件名稱(chēng)。
  • mode – 這是 C 字符串,包含了文件訪問(wèn)模式,模式如下:
模式描述
“r”打開(kāi)一個(gè)用于讀取的文件。該文件必須存在。
“w”創(chuàng)建一個(gè)用于寫(xiě)入的空文件。如果文件名稱(chēng)與已存在的文件相同,則會(huì)刪除已有文件的內(nèi)容,文件被視為一個(gè)新的空文件。
“a”追加到一個(gè)文件。寫(xiě)操作向文件末尾追加數(shù)據(jù)。如果文件不存在,則創(chuàng)建文件。
“r+”打開(kāi)一個(gè)用于更新的文件,可讀取也可寫(xiě)入。該文件必須存在。
“w+”創(chuàng)建一個(gè)用于讀寫(xiě)的空文件。
“a+”打開(kāi)一個(gè)用于讀取和追加的文件。

返回值

該函數(shù)返回一個(gè) FILE 指針。否則返回 NULL,且設(shè)置全局變量 errno 來(lái)標(biāo)識(shí)錯(cuò)誤。

以上就是FFmpeg實(shí)戰(zhàn)之分離出PCM數(shù)據(jù)的詳細(xì)內(nèi)容,更多關(guān)于FFmpeg分離PCM數(shù)據(jù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解Qt如何加載libxl庫(kù)

    詳解Qt如何加載libxl庫(kù)

    這篇文章主要介紹了詳解Qt如何加載libxl庫(kù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • C語(yǔ)言 structural body結(jié)構(gòu)體詳解用法

    C語(yǔ)言 structural body結(jié)構(gòu)體詳解用法

    C 數(shù)組允許定義可存儲(chǔ)相同類(lèi)型數(shù)據(jù)項(xiàng)的變量,結(jié)構(gòu)是 C 編程中另一種用戶自定義的可用的數(shù)據(jù)類(lèi)型,它允許您存儲(chǔ)不同類(lèi)型的數(shù)據(jù)項(xiàng),結(jié)構(gòu)用于表示一條記錄,假設(shè)您想要跟蹤圖書(shū)館中書(shū)本的動(dòng)態(tài),您可能需要跟蹤每本書(shū)的下列屬性
    2021-10-10
  • C/C++ 數(shù)組和指針及引用的區(qū)別

    C/C++ 數(shù)組和指針及引用的區(qū)別

    這篇文章主要介紹了C/C++ 數(shù)組和指針及引用的區(qū)別的相關(guān)資料,這里從匯編的角度來(lái)分析他們之間的區(qū)別,需要的朋友可以參考下
    2017-07-07
  • C語(yǔ)言實(shí)現(xiàn)動(dòng)態(tài)順序表的實(shí)現(xiàn)代碼

    C語(yǔ)言實(shí)現(xiàn)動(dòng)態(tài)順序表的實(shí)現(xiàn)代碼

    這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)動(dòng)態(tài)順序表的實(shí)現(xiàn)代碼的相關(guān)資料,動(dòng)態(tài)順序表在內(nèi)存中開(kāi)辟一塊空間,可以隨我們數(shù)據(jù)數(shù)量的增多來(lái)擴(kuò)容,需要的朋友可以參考下
    2017-08-08
  • c語(yǔ)言 漢諾塔算法代碼

    c語(yǔ)言 漢諾塔算法代碼

    c語(yǔ)言 漢諾塔算法代碼,需要的朋友可以參考一下
    2013-04-04
  • C/C++下讀取ENVI柵格文件格式的示例代碼

    C/C++下讀取ENVI柵格文件格式的示例代碼

    ENVI使用的是通用柵格數(shù)據(jù)格式,包含一個(gè)簡(jiǎn)單的二進(jìn)制文件( a simple flat binary )和一個(gè)相關(guān)的ASCII(文本)的頭文件,下面我們就來(lái)看看如何使用C++讀取ENVI柵格文件格式吧
    2024-10-10
  • C語(yǔ)言中查詢進(jìn)程信號(hào)是否被遮罩或擱置的簡(jiǎn)單方法

    C語(yǔ)言中查詢進(jìn)程信號(hào)是否被遮罩或擱置的簡(jiǎn)單方法

    這篇文章主要介紹了C語(yǔ)言中查詢進(jìn)程信號(hào)是否被遮罩或擱置的簡(jiǎn)單方法,包括sigprocmask函數(shù)和sigpending函數(shù)的簡(jiǎn)介,需要的朋友可以參考下
    2015-09-09
  • C語(yǔ)言中判斷int,long型等變量是否賦值的方法詳解

    C語(yǔ)言中判斷int,long型等變量是否賦值的方法詳解

    聲明了int ,long型等局部變量,在利用一些方法給這些變量賦值之后,想判斷這些變量是不是真的被賦初值了,怎么辦
    2013-07-07
  • C語(yǔ)言進(jìn)階幾分鐘帶你理解大小端存儲(chǔ)模式

    C語(yǔ)言進(jìn)階幾分鐘帶你理解大小端存儲(chǔ)模式

    這篇文章主要為大家介紹了C語(yǔ)言進(jìn)階大小端模式的示例詳解,帶各位讀者朋友五分鐘腳踩大小端模式,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2022-02-02
  • C++中字符串以及數(shù)組和指針的互相使用講解

    C++中字符串以及數(shù)組和指針的互相使用講解

    這篇文章主要介紹了C++中字符串以及數(shù)組和指針的互相使用講解,是C++入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-09-09

最新評(píng)論

湟中县| 南漳县| 大足县| 玛曲县| 剑阁县| 油尖旺区| 潼南县| 浮梁县| 迁安市| 吐鲁番市| 常山县| 环江| 临西县| 望江县| 邮箱| 天等县| 通城县| 新泰市| 大连市| 南雄市| 磐石市| 隆回县| 宜丰县| 卓尼县| 驻马店市| 溧阳市| 偃师市| 铅山县| 南充市| 喜德县| 迁安市| 深泽县| 喀喇沁旗| 呈贡县| 沙湾县| 岳阳县| 乐山市| 珠海市| 仁化县| 靖江市| 襄垣县|