ffmpeg录制桌面(队列方式)

本文介绍使用FFmpeg进行桌面录制的技术细节,重点讲解如何利用AVFifoBuffer实现音视频数据的队列管理。通过创建两个线程分别抓取麦克风音频和桌面视频数据,再将这些数据合并。

vs版本:2017
ffmpeg版本号:
ffmpeg version N-102642-g864d1ef2fc Copyright © 2000-2021 the FFmpeg developers
built with gcc 8.1.0 (x86_64-win32-seh-rev0, Built by MinGW-W64 project)
configuration: --arch=x86_64 --prefix=/home/ffmpeg_static_x64 --disable-debug
libavutil 57. 0.100 / 57. 0.100
libavcodec 59. 1.100 / 59. 1.100
libavformat 59. 2.101 / 59. 2.101
libavdevice 59. 0.100 / 59. 0.100
libavfilter 8. 0.101 / 8. 0.101
libswscale 6. 0.100 / 6. 0.100
libswresample 4. 0.100 / 4. 0.100

关于ffmpeg的lib和dll,本人在csdn上上传了相关资源,并且免费下载。

之前写过ffmpeg录制桌面ffmpeg录制麦克风声音

现在需要将音视频合入一块,初步想法是在main函数里面创建两个线程,其中一个线程抓取麦克风音频数据,另外一个线程抓取桌面视频数据,然后在主线程里面将数据合并,这自然涉及音视频数据的队列。
本文介绍下ffmpeg录制桌面的队列方式。
本人用的是ffmpeg自带的AVFifoBuffer结构,在抓取到视频数据后,用的是下面这种方式入队列

av_fifo_generic_write(fifo_video, pFrameYUV->data[0], y_size, NULL);
av_fifo_generic_write(fifo_video, pFrameYUV->data[1], y_size / 4, NULL);
av_fifo_generic_write(fifo_video, pFrameYUV->data[2], y_size / 4, NULL);

这里面的写法与视频格式是AV_PIX_FMT_YUV420P有关,YUV420结构的数据,Y的大小是U的4倍,V的四倍。

从队列里面取数据时,用的是av_fifo_generic_read(fifo_video, out_buffer_yuv420, frame_size, NULL);
这里面的out_buffer_yuv420用来接上面av_fifo_generic_write写入的YUV数据,并且由于out_buffer_yuv420的空间刚好是一帧YUV420的数据大小。
uint8_t *out_buffer_yuv420 = (uint8_t *)av_malloc(frame_size);

在main函数的下面语句确立了out_buffer_yuv420和pFrameYUVInMain的对应关系,即确立了out_buffer_yuv420,也就相当于确立了pFrameYUVInMain。

av_image_fill_arrays(pFrameYUVInMain->data, pFrameYUVInMain->linesize, out_buffer_yuv420, AV_PIX_FMT_YUV420P, pCodecCtx_Video->width, pCodecCtx_Video->height, 1);

全部代码如下所示:

// FfmpegTest.cpp : Defines the entry point for the console application.
//

#include <Windows.h>
#include <conio.h>

#ifdef	__cplusplus

extern "C"
{
   
   
#endif
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "libavdevice/avdevice.h"
#include "libavutil/audio_fifo.h"
#include "libavutil/imgutils.h"

#pragma comment(lib, "avcodec.lib")
#pragma comment(lib, "avformat.lib")
#pragma comment(lib, "avutil.lib")
#pragma comment(lib, "avdevice.lib")
#pragma comment(lib, "avfilter.lib")

	//#pragma comment(lib, "avfilter.lib")
	//#pragma comment(lib, "postproc.lib")
	//#pragma comment(lib, "swresample.lib")
#pragma comment(lib, "swscale.lib")
#ifdef __cplusplus
};
#endif

AVFormatContext	*pFormatCtx_Video = NULL, *pFormatCtx_Out = NULL;
AVCodecContext	*pCodecCtx_Video = NULL;
AVCodec			*pCodec_Video = NULL;
AVFifoBuffer	*fifo_video = NULL;
int VideoIndex;


AVCodecContext	*pCodecEncodeCtx_Video = NULL;
AVCodec			*pCodecEncode_Video = NULL;


SwsContext *img_convert_ctx;
int frame_size = 0;

uint8_t *picture_buf = NULL, *frame_buf = NULL;

bool bCap = true;

int iPicCount = 0;


CRITICAL_SECTION VideoSection;


DWORD WINAPI ScreenCapThreadProc(LPVOID lpParam);



int OpenVideoCapture()
{
   
   
	const AVInputFormat *ifmt = av_find_input_format("gdigrab");
	//这里可以加参数打开,例如可以指定采集帧率
	AVDictionary 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值