Ubuntu下使用Qt和ffmpeg,打開音頻采集設備并讀取資料
- 引入編譯好的ffmpeg庫檔案和頭檔案,
(1)在.pro檔案中加入:
unix:!macx: LIBS += -L$$PWD/../../../usr/local/ffmpeg/lib/
-lavcodec -lavdevice -lavfilter -lavformat -lavutil -lswresample -lswscale
INCLUDEPATH += $$PWD/../../../usr/local/ffmpeg/include
DEPENDPATH += $$PWD/../../../usr/local/ffmpeg/include
即可引入庫檔案,庫檔案路徑根據自己的編譯路徑修改,我的路徑是/usr/local/ffmpeg,
(2)也可通過在Qt Creator中引入外部庫檔案的方式引入ffmpeg,
2.引入所需頭檔案
extern "C"
{
#include "libavdevice/avdevice.h"
#include "libavutil/avutil.h"
#include "libavformat/avformat.h"
}
注意:ffmpeg是C語言撰寫的,C++環境下需要加上extern “C”,否則程式編譯會報錯,
- 打開設備
void MainWindow::openDevice()
{
// 注冊設備
avdevice_register_all();
// 獲取采集格式
AVInputFormat *inputFmt = av_find_input_format("alsa");
int ret = 0;
AVFormatContext *fmt_ctx = nullptr;
char *deviceName = "hw:0,0";
AVDictionary *options = nullptr;
// 打開設備
ret = avformat_open_input(&fmt_ctx, deviceName, inputFmt, &options);
char errors[1024];
if (ret < 0)
{
av_strerror(ret, errors, 1024);
printf("Failed to open audio device, [%d]%s\n", ret, errors);
}
}
- 從設備讀取音頻資料
- 增加頭檔案
#include "libavcodec/avcodec.h"
讀取代碼:
void MainWindow::openDeviceAndReadData()
{
// 設定日志級別
av_log_set_level(AV_LOG_DEBUG);
// 注冊設備
avdevice_register_all();
// 獲取采集格式
AVInputFormat *inputFmt = av_find_input_format("alsa");
int ret = 0;
AVFormatContext *fmt_ctx = nullptr;
char *deviceName = "hw:0,0";
AVDictionary *options = nullptr;
// 打開設備
ret = avformat_open_input(&fmt_ctx, deviceName, inputFmt, &options);
char errors[1024] = {0};
if (ret < 0)
{
av_strerror(ret, errors, 1024);
printf("Failed to open audio device, [%d]%s\n", ret, errors);
return;
}
int count = 0;
AVPacket packet;
av_init_packet(&packet);
// 從設備讀取資料
while ((ret = av_read_frame(fmt_ctx, &packet) == 0) && count++ < 500)
{
av_log(NULL, AV_LOG_INFO, "Packet size: %d(%p), count = %d\n",
packet.size, packet.data, count);
// 釋放packet空間
av_packet_unref(&packet);
}
// 關閉設備,釋放背景關系空間
avformat_close_input(&fmt_ctx);
av_log(NULL, AV_LOG_DEBUG, "Finish!\n");
}
使用完背景關系AVFormatContext 和AVPacket以后要注意釋放空間,避免記憶體泄漏,
注:1. C語言和C++中手動分配的空間使用完以后要記得釋放,避免記憶體泄漏,否則服務端程式不斷申請記憶體空間而不釋放,最侄訓導致程式崩潰,
2. 指標變數釋放以后,要置為NULL,避免野指標,在多執行緒中,如果在執行緒1中的指標釋放了其指向的記憶體地址,沒有置為NULL,之后這塊空間被執行緒2使用,而此時執行緒1中的指標依然可以訪問并修改這塊記憶體空間,如果執行緒1中的指標修改了記憶體內容,則會對執行緒2造成影響,產生不可估計的后果,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/46194.html
標籤:其他
