Environment
Ubuntu 16.04
GCC 5.4
CMake 3.9.6
OpenCV 3.3.1
Source code
#include <opencv2/core/mat.hpp>
#include <opencv2/highgui/highgui.hpp>
extern "C" {
#include <swscale.h>
#include "avformat.h"
#include "avdevice.h"
}
int main(int argc, char *argv[]) {
// Init
avcodec_register_all();
avdevice_register_all();
AVFormatContext *formatContext = avformat_alloc_context(); // Format I/O context. Allocate an AVFormatContext.主要存储视音频封装格式中包含的信息
AVInputFormat *inputFormat = av_find_input_format("v4l2"); // or "video4linux2", 存储输入视音频使用的封装格式,每种视音频封装格式都对应一个AVInputFormat结构。
if(inputFormat == nullptr) return -1;
// Open an input stream and read the header.
if(avformat_open_input(&formatContext, "/dev/video0", inputFormat, nullptr) < 0) return -2;
if(avformat_find_stream_info(formatContext, nullptr) < 0) return -3;
// Print detailed information about the input or output format.
av_dump_format(formatContext, 0, "/dev/video0", 0);
// 寻找视频流和对应的解码器(输入可能不止一个流,这里包含音频等流)
int videoStreamIndex = 0;
AVCodec *codec;
if((videoStreamIndex = av_find_best_stream(formatContext, AVMEDIA_TYPE_VIDEO, -1, -1, &codec, 0)) < 0) return -4;
// 获取对应视频流的解码相关信息
AVCodecContext *codecContext = formatContext->streams[videoStreamIndex]->codec;
// Initialize the AVCodecContext to use the given AVCodec.
if(avcodec_open2(codecContext, codec, nullptr) < 0) return -5;
// 分配空间存储图像数据
AVFrame *frame = av_frame_alloc();
AVPicture picture{};
avpicture_alloc(&picture, AV_PIX_FMT_BGR24, codecContext->width, codecContext->height);
int unfinished;
AVPacket packet{};
struct SwsContext * img_convert_ctx = nullptr;
while(av_read_frame(formatContext, &packet) >= 0)
{
if(packet.stream_index == videoStreamIndex) {
// Decode the video frame: packet => frame
avcodec_decode_video2(codecContext, frame, &unfinished, &packet);
if(unfinished) {
// Convert to BGR24.
img_convert_ctx = sws_getCachedContext(
img_convert_ctx,
codecContext->width, codecContext->height, codecContext->pix_fmt,
codecContext->width, codecContext->height, AV_PIX_FMT_BGR24,
SWS_BICUBIC, nullptr, nullptr, nullptr);
sws_scale(img_convert_ctx,
reinterpret_cast<const uint8_t *const *>(frame->data), frame->linesize,
0, codecContext->height,
picture.data, picture.linesize);
// Use OpenCV to display the picture.
cv::Mat img(frame->height, frame->width, CV_8UC3, picture.data[0]);
cv::imshow("display",img);
cv::waitKey(10);
}
av_free_packet(&packet);
}
}
// Destroy
sws_freeContext(img_convert_ctx);
av_free_packet(&packet);
avcodec_close(codecContext);
av_free(frame);
avpicture_free(&picture);
avformat_close_input(&formatContext);
return 0;
}
结构体、函数和函数参数说明在对应的头文件中说明都比较信息。直接看头文件即可。
更多图像处理和视觉处理算法:zMatrix