再來介紹下如何讀取視頻幀,打開視頻參考前面的文章,首先須要建立一個幀的存放對象html
AVPacket pkt;ios
memset(&pkt, 0, sizeof(AVPacket));
網絡
再經過 int err = av_read_frame(ic, &pkt); 讀取幀數據,其中ic是以前打開的視頻流句柄。讀取視頻幀後要注意一點av_read_frame會自動給視頻幀分配空間,返回值0表示成功。ide
能夠經過 av_packet_unref(&pkt);刪除packet的控制,注意這裏刪除的不是packet對象的空間,而是packet對象指向的數據空間。函數
經過判斷pkt的stream_index 成員能夠判斷此幀數據是否是視頻spa
if (pkt.stream_index == videoStream),code
videoStream是打開視頻時存放的視頻流索引,大部分文件都是0,參考前一篇文章。orm
extern "C" 視頻
{ htm
#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);
}
}
更多的資料也能夠關注我51CTO上的視頻課程
夏老師的課堂 http://edu.51cto.com/lecturer/12016059.html
http://edu.51cto.com/course/course_id-8059.html