编译之前得下载好ffmpeg库文件
pro文件
SOURCES += \
ffmpeg_libavdevice.cppINCLUDEPATH += $$PWD/ffmpeg/include
LIBS += $$PWD/ffmpeg/lib/avcodec.lib \
$$PWD/ffmpeg/lib/avdevice.lib \
$$PWD/ffmpeg/lib/avfilter.lib \
$$PWD/ffmpeg/lib/avformat.lib \
$$PWD/ffmpeg/lib/avutil.lib \
$$PWD/ffmpeg/lib/postproc.lib \
$$PWD/ffmpeg/lib/swresample.lib \
$$PWD/ffmpeg/lib/swscale.lib
INCLUDEPATH += $$PWD/ffmpeg/include
ffmpeg_libavdevice.cpp
#include <stdio.h>
extern "C"
{#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "libavdevice/avdevice.h"
}
//'1' Use Dshow
//'0' Use VFW
#define USE_DSHOW 0
//Show Dshow Device
void show_dshow_device(){
AVFormatContext *pFormatCtx = avformat_alloc_context();
AVDictionary* options = NULL;
av_dict_set(&options,"list_devices","true",0);
AVInputFormat *iformat = av_find_input_format("dshow");
printf("========Device Info=============\n");
avformat_open_input(&pFormatCtx,"video=dummy",iformat,&options);
printf("================================\n");
}
//Show Dshow Device Option
void show_dshow_device_option(){
AVFormatContext *pFormatCtx = avformat_alloc_context();
AVDictionary* options = NULL;
av_dict_set(&options,"list_options","true",0);
AVInputFormat *iformat = av_find_input_format("dshow");
printf("========Device Option Info======\n");
avformat_open_input(&pFormatCtx,"video=Integrated Camera",iformat,&options);
printf("================================\n");
}
//Show VFW Device
void show_vfw_device(){
AVFormatContext *pFormatCtx = avformat_alloc_context();
AVInputFormat *iformat = av_find_input_format("vfwcap");
printf("========VFW Device Info======\n");
avformat_open_input(&pFormatCtx,"list",iformat,NULL);
printf("=============================\n");
}
//Show AVFoundation Device
void show_avfoundation_device(){
AVFormatContext *pFormatCtx = avformat_alloc_context();
AVDictionary* options = NULL;
av_dict_set(&options,"list_devices","true",0);
AVInputFormat *iformat = av_find_input_format("avfoundation");
printf("==AVFoundation Device Info===\n");
avformat_open_input(&pFormatCtx,"",iformat,&options);
printf("=============================\n");
}
#define USE_DSHOW 1
int main(int argc, char* argv[])
{AVFormatContext *pFormatCtx;
int i, videoindex;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
av_register_all(); avformat_network_init();avdevice_register_all();//Register Device
show_dshow_device();pFormatCtx = avformat_alloc_context();
#if 0
AVInputFormat *ifmt=av_find_input_format("dshow");
//Set own video device's name
if(avformat_open_input(&pFormatCtx,"video=e2eSoft VCam",ifmt,NULL)!=0){
printf("Couldn't open input stream.\n");
return -1;
}#elseAVInputFormat *ifmt=av_find_input_format("vfwcap");
if(avformat_open_input(&pFormatCtx,"0",ifmt,NULL)!=0){
printf("Couldn't open input stream.\n");
return -1;
}#endifif(avformat_find_stream_info(pFormatCtx,NULL)<0)
{printf("Couldn't find stream information.\n");
return -1;
}videoindex=-1;
for(i=0; i<pFormatCtx->nb_streams; i++)
{if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
{ videoindex=i; } }if(videoindex==-1)
{printf("Couldn't find a video stream.\n");
return -1;
}pCodecCtx=pFormatCtx->streams[videoindex]->codec;
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL)
{printf("Codec not found.\n");
return -1;
}if(avcodec_open2(pCodecCtx, pCodec,NULL)<0)
{printf("Could not open codec.\n");
return -1;
}AVFrame *pFrame,*pFrameYUV;
pFrame=av_frame_alloc(); pFrameYUV=av_frame_alloc();uint8_t *out_buffer=(uint8_t *)av_malloc(avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height));
avpicture_fill((AVPicture *)pFrameYUV, out_buffer, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);
int ret, got_picture;
AVPacket *packet=(AVPacket *)av_malloc(sizeof(AVPacket));
FILE *fp_yuv=fopen("output.yuv","wb");
struct SwsContext *img_convert_ctx;
img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
///这里打印出视频的宽高
fprintf(stderr,"w= %d h= %d\n",pCodecCtx->width, pCodecCtx->height);
///我们就读取100张图像
for(int i=0;i<100;i++)
{if(av_read_frame(pFormatCtx, packet) < 0)
{break;
}if(packet->stream_index==videoindex)
{ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);
if(ret < 0){
printf("Decode Error.\n");
return -1;
}if(got_picture)
{sws_scale(img_convert_ctx, (const uint8_t* const*)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameYUV->data, pFrameYUV->linesize);
int y_size=pCodecCtx->width*pCodecCtx->height;
fwrite(pFrameYUV->data[0],1,y_size,fp_yuv); //Y
fwrite(pFrameYUV->data[1],1,y_size/4,fp_yuv); //U
fwrite(pFrameYUV->data[2],1,y_size/4,fp_yuv); //V
} } av_free_packet(packet); } sws_freeContext(img_convert_ctx); fclose(fp_yuv); av_free(out_buffer); av_free(pFrameYUV); avcodec_close(pCodecCtx); avformat_close_input(&pFormatCtx);return 0;
}
本文介绍使用FFmpeg库从不同设备(如Dshow、VFW等)进行视频采集,并将其转换为YUV格式的过程。文章详细展示了如何设置输入设备、打开输入流、查找流信息并解码视频帧。

669

被折叠的 条评论
为什么被折叠?



