FFmpeg实现获取USB摄像头视频流测试代码
通過USB攝像頭(注:windows7/10下使用內置攝像頭,linux下接普通的usb攝像頭(Logitech))獲取視頻流用到的模塊包括avformat和avdevice。頭文件僅include avdevice.h即可,因為avdevice.h中會include avformat.h。libavdevice庫是libavformat的一個補充庫(complementary library)。主要涉及到的接口函數包括:
1. avdevice_register_all:初始化libavdevice庫并注冊所有輸入輸出設備;
2. av_find_input_format:根據輸入格式的名字查找AVInputFormat,在測試代碼中,windows平臺使用”vfwcap”(video for windows capture),linux平臺使用”v4l2”(Video4Linux2);
3. avformat_alloc_context:分配AVFormatContext;
4. avformat_open_input:打開輸入流并讀取header;
5. avformat_find_stream_info:讀取媒體文件的數據包以獲取流信息;
6. 通過AVFormatContext中AVStream查找視頻/音頻流索引,這里在windows10下獲取到的編碼類型為mjpeg即AV_CODEC_ID_MJPEG,像素格式為yuv422p即AV_PIX_FMT_YUVJ422P;在linux或windows7下獲取到的編碼類型為rawvideo即AV_CODEC_ID_RAWVIDEO,像素格式yuyv422即AV_PIX_FMT_YUYV422;可見攝像頭類型不同、系統不同獲取到的編碼類型和像素格式可能也不同;
7. av_read_frame:獲取流即packet(AVPacket);
8. av_packet_unref:釋放packet引用的緩沖區;
9. avformat_close_input:關閉打開的輸入AVFormatContext。
測試代碼如下(test_ffmpeg_usb_stream.cpp):
#include "funset.hpp"
#include <iostream>#ifdef __cplusplus
extern "C" {
#endif#include <libavdevice/avdevice.h>#ifdef __cplusplus
}
#endifint test_ffmpeg_usb_stream()
{avdevice_register_all();#ifdef _MSC_VERconst char* input_format_name = "vfwcap";const char* url = "";
#elseconst char* input_format_name = "v4l2";const char* url = "/dev/video0";
#endifAVInputFormat* fmt = av_find_input_format(input_format_name);AVFormatContext* ctx = avformat_alloc_context();int ret = avformat_open_input(&ctx, url, fmt, nullptr);if (ret != 0) {fprintf(stderr, "fail to open input stream: %d\n", ret);return -1;}// read packets of a media file to get stream informationret = avformat_find_stream_info(ctx, nullptr);if (ret < 0) {fprintf(stderr, "fail to get stream information: %d\n", ret);return -1;}// find audio/video stream indexint video_stream_index = -1;int audio_stream_index = -1;fprintf(stdout, "Number of elements in AVFormatContext.streams: %d\n", ctx->nb_streams);for (int i = 0; i < ctx->nb_streams; ++i) {const AVStream* stream = ctx->streams[i];fprintf(stdout, "type of the encoded data: %d\n", stream->codecpar->codec_id);if (stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {video_stream_index = i;fprintf(stdout, "dimensions of the video frame in pixels: width: %d, height: %d, pixel format: %d\n",stream->codecpar->width, stream->codecpar->height, stream->codecpar->format);}else if (stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {audio_stream_index = i;fprintf(stdout, "audio sample format: %d\n", stream->codecpar->format);}}if (video_stream_index == -1) {fprintf(stderr, "Error: no video stream\n");return -1;}if (audio_stream_index == -1) {fprintf(stdout, "Warning: no audio stream\n");}int cnt = 0;AVPacket pkt;while (1) {if (++cnt > 100) break;ret = av_read_frame(ctx, &pkt);if (ret < 0) {fprintf(stderr, "error or end of file: %d\n", ret);continue;}if (pkt.stream_index == video_stream_index) {fprintf(stdout, "video stream, packet size: %d\n", pkt.size);}if (pkt.stream_index == audio_stream_index) {fprintf(stdout, "audio stream, packet size: %d\n", pkt.size);}av_packet_unref(&pkt);}avformat_close_input(&ctx);fprintf(stdout, "test finish\n");return 0;
}Linux下執行結果如下:
GitHub:https://github.com/fengbingchun/OpenCV_Test
總結
以上是生活随笔為你收集整理的FFmpeg实现获取USB摄像头视频流测试代码的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 远程过程调用RPC简介
- 下一篇: FFmpeg通过摄像头实现对视频流进行解
