录制电脑摄像头的视频流,由于格式限制,很容易出错。如:Input picture width (320) is greater than stride (0)。其它的处理过程,与其它视频处理流程大体相同。
1、取得设备名:
使用ffmpeg命令取得摄像头的设备名称:
ffmpeg -list_devices true -f dshow -i dummy
在取得名称中有中文字符时,需要转化为utf8格式。
CameraName= wchar_to_utf8(L"video=HP HD Camera");
2、格式转化:
从解码出来的帧格式与编码器要求的格式如果不同时,需要格式转化。或者调用函数sws_scale或者自己编程实现。
if (g_outputCameraEncCodecContext->pix_fmt != frame->format)
{
if (g_pConvertedFrame == NULL)
{
g_pConvertedFrame = av_frame_alloc();
int len = av_image_get_buffer_size(g_outputCameraEncCodecContext->pix_fmt, g_outputCameraEncCodecContext->width, g_outputCameraEncCodecContext->height, 1);
uint8_t *out_buffer =(uint8_t *) av_malloc(len);
av_frame_copy_props(g_pConvertedFrame, frame);
av_image_fill_arrays( g_pConvertedFrame->data,
g_pConvertedFrame->linesize,
out_buffer,
g_outputCameraEncCodecContext->pix_fmt,
g_outputCameraEncCodecContext->width,
g_outputCameraEncCodecContext->height,1);
g_pConvertedFrame->format = g_outputCameraEncCodecContext->pix_fmt;
g_pConvertedFrame->width = g_outputCameraEncCodecContext->width;
g_pConvertedFrame->height = g_outputCameraEncCodecContext->height;
if(g_swsContext == NULL)
{
g_swsContext = sws_getContext(g_outputCameraEncCodecContext->width, g_outputCameraEncCodecContext->height,
(AVPixelFormat)frame->format,
g_outputCameraEncCodecContext->width, g_outputCameraEncCodecContext->height,
g_outputCameraEncCodecContext->pix_fmt,
SWS_BICUBIC, NULL, NULL, NULL
);
}
}
if (g_swsContext && g_pConvertedFrame)
{
ret = sws_scale(g_swsContext,
(const uint8_t* const*)frame->data,
frame->linesize,
0,
g_pConvertedFrame->height,
g_pConvertedFrame->data,
g_pConvertedFrame->linesize);
}
ret = avcodec_encode_video2(g_outputCameraEncCodecContext, pkt.get(), g_pConvertedFrame, &gotOutput);
如果两者编码格式不同时,进行转化处理。然后再进入编码操作(avcodec_encode_video2)。
3、下载项目源代码:
在Debug – x86下编译运行。
在函数CatchCamera()修改相应的设备名称