FFMPEG系列課程-讀取視訊幀
阿新 • • 發佈:2018-11-08
再來介紹下如何讀取視訊幀,開啟視訊參考前面的文章,首先需要建立一個幀的存放物件
AVPacket pkt;
memset(&pkt, 0, sizeof(AVPacket));
再通過 int err = av_read_frame(ic, &pkt); 讀取幀資料,其中ic是之前開啟的視訊流控制代碼。讀取視訊幀後要注意一點av_read_frame會自動給視訊幀分配空間,返回值0表示成功。
可以通過 av_packet_unref(&pkt);刪除packet的控制,注意這裡刪除的不是packet物件的空間,而是packet物件指向的資料空間。
通過判斷pkt的stream_index 成員可以判斷此幀資料是不是視訊
if (pkt.stream_index == videoStream),
videoStream是開啟視訊時存放的視訊流索引,大部分檔案都是0,參考前一篇文章。
更多的資料也可以關注我csdn上的視訊課程 夏老師課程專欄http://edu.csdn.net/lecturer/961extern "C" { #include<libavformat/avformat.h> } //引用lib庫,也可以在專案中設定,開啟視訊只需要用到這三個庫 #pragma comment(lib,"avformat.lib") #pragma comment(lib,"avutil.lib") #pragma comment(lib,"avcodec.lib") #include <iostream> using namespace std; int main(int argc, char *argv[]) { //初始化所以ffmpeg的解碼器 av_register_all(); char path[1024] = "video.mp4"; //用來存放開啟的視訊流資訊 AVFormatContext *ic = NULL; //用來儲存視訊流索引 int videoStream = 0; //開啟視訊播放流 //path引數表示開啟的視訊路徑,這個路徑可以包括各種視訊檔案 //也包括rtsp和http網路視訊流 //第三個引數表示傳入的視訊格式,我這邊不傳遞有FFmpeg內部獲取 //最後一個引數是設定,我們這裡也不傳遞 int re = avformat_open_input(&ic, path, 0, 0); if (re != 0) { //獲取到FFmpeg的錯誤資訊 char errorbuf[1024] = { 0 }; av_strerror(re, errorbuf, sizeof(errorbuf)); printf("open %s failed: %s\n", path, errorbuf); return -1; } //遍歷視訊流,裡面包含音訊流,視訊流,或者字母流,我們這裡只處理視訊 for (int i = 0; i < ic->nb_streams; i++) { AVCodecContext *enc = ic->streams[i]->codec; //確認是視訊流 if (enc->codec_type == AVMEDIA_TYPE_VIDEO) { //存放視訊流索引,後面的程式碼要用到 videoStream = i; //找到解碼器,比如H264,解碼器的資訊也是ffmpeg內部獲取的 AVCodec *codec = avcodec_find_decoder(enc->codec_id); if (!codec) { printf("video code not find!\n"); return -2; } //開啟視訊解碼器,開啟音訊解碼器用的也是同一個函式 int err = avcodec_open2(enc, codec, NULL); if (err != 0) { char buf[1024] = { 0 }; av_strerror(err, buf, sizeof(buf)); printf(buf); return -3; } } } //建立視訊幀物件 AVPacket pkt; memset(&pkt, 0, sizeof(AVPacket)); for (;;) { //讀取視訊幀 int err = av_read_frame(ic, &pkt); if (err != 0) { //讀到結尾或者出錯 char buf[1024] = { 0 }; av_strerror(err, buf, sizeof(buf)); printf(buf); break; } //判斷是否是音訊 if (pkt.stream_index == videoStream) { printf("video pkt size is %d\n", pkt.size); //視訊處理,解碼或者儲存 } //視訊幀資料空間 av_packet_unref(&pkt); } }
手把手教您開發視訊播放器
http://edu.csdn.net/course/detail/3300