ffmpeg4教程1:采集桌面图像(desktop)win32显示

基于vs2017 vc++  ffmpeg4.0.2下测试

ffmpeg 环境配置请百度(vs2017 ffmpeg )图像和声音请安装screencapturer便于查找https://sourceforge.net/projects/screencapturer/files/

部分方法在https://blog.csdn.net/Java_lilin/article/details/85118365中查找


#include "pch.h"
#include <iostream>

extern "C" {
#include "libavcodec/avcodec.h" 
#include "libavformat/avformat.h"
#include "libavdevice/avdevice.h"
#include "libavutil/imgutils.h"
#include "libavutil/audio_fifo.h"
#include "libavutil/time.h"
#include "libavutil/mathematics.h"
#include "libavutil/channel_layout.h"
#include "libswscale/swscale.h"
#include "libswresample/swresample.h"
}
#include <Windows.h>


static int test1() {
	AVFormatContext *formatCtx = avformat_alloc_context();
	AVInputFormat *ifmt = av_find_input_format("gdigrab");//设备类型
	//AVInputFormat *ifmt = av_find_input_format("dshow");//设备类型
	AVDictionary* options = NULL;
	//av_dict_set(&options, "video_size","1920*1080",0);//大小  默认全部
	av_dict_set(&options, "framerate","15",0);//帧lu
	if (avformat_open_input(&formatCtx, "desktop", ifmt, &options) != 0) {
	//if (avformat_open_input(&formatCtx, "video=Integrated Camera", ifmt, &options) != 0) {
		printf("open input device fail\n");
		return -1;
	}
	av_dict_free(&options);

	if (avformat_find_stream_info(formatCtx,NULL)<0) {
		printf("avformat_find_stream_info faill\n");
		return -1;
	}
	if (formatCtx->streams[0]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO) {
		printf("no find stream info\n");
		return -1;
	}
	//查找解密器
	AVCodec *codec = avcodec_find_decoder(formatCtx->streams[0]->codecpar->codec_id);
	if (codec == NULL) {
		printf("codec not found\n");
		return -1;
	}
	AVCodecContext *ctx = avcodec_alloc_context3(codec);
	avcodec_parameters_to_context(ctx, formatCtx->streams[0]->codecpar);
	if (avcodec_open2(ctx, codec, NULL) < 0) {
		printf("codec not open\n");
		return -1;
	}
	printf("pix format is %d\n", formatCtx->streams[0]->codecpar->format);//==AVPixelFormat->AV_PIX_FMT_BGRA 
	 
	AVFrame *frame = alloc_picture((AVPixelFormat)formatCtx->streams[0]->codecpar->format, formatCtx->streams[0]->codecpar->width, formatCtx->streams[0]->codecpar->height);
	//目标
	AVFrame *bgrframe = alloc_picture(AV_PIX_FMT_BGR24, formatCtx->streams[0]->codecpar->width, formatCtx->streams[0]->codecpar->height);;

	//图像转换
	SwsContext *img_convert_ctx = sws_getContext(formatCtx->streams[0]->codecpar->width, formatCtx->streams[0]->codecpar->height, (AVPixelFormat)formatCtx->streams[0]->codecpar->format,
		formatCtx->streams[0]->codecpar->width, formatCtx->streams[0]->codecpar->height, AV_PIX_FMT_BGR24,SWS_BICUBIC,NULL,NULL,NULL);

	while (true) {
		AVPacket packet = { 0 };
		av_init_packet(&packet);
		if (av_read_frame(formatCtx, &packet) >= 0) {
			avcodec_send_packet(ctx, &packet);
			if (avcodec_receive_frame(ctx, frame) < 0) {
				printf("decode error\n");
			}
			else {
				printf("采集到图片");
				//转换 AV_PIX_FMT_BGRA to AV_PIX_FMT_BGR24
				sws_scale(img_convert_ctx, (const unsigned char* const*)frame->data, frame->linesize,0, frame->height , bgrframe->data, bgrframe->linesize);
				Show( FindWindow(NULL,L"视频播放"), bgrframe->data[0], bgrframe->width, bgrframe->height,true);
				
			}

		}
		av_packet_unref(&packet);
	}
	av_frame_free(&frame);
	av_frame_free(&bgrframe);
	avcodec_free_context(&ctx);
	avformat_close_input(&formatCtx);

	return 0;
}
int main()
{
    printf("ok:%d\n", avcodec_version());
	avdevice_register_all(); 
	

	HINSTANCE hInstance;
	hInstance = GetModuleHandle(NULL);
	WNDCLASSEX wce = { 0 };
	wce.cbSize = sizeof(wce);
	wce.cbClsExtra = 0;
	wce.cbWndExtra = 0;
	wce.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wce.hCursor = NULL;
	wce.hIcon = NULL;
	wce.hIconSm = NULL;
	wce.hInstance = hInstance;
	wce.lpfnWndProc = WinProc;
	wce.lpszClassName = L"Main";
	wce.lpszMenuName = NULL;
	wce.style = CS_HREDRAW | CS_VREDRAW;
	ATOM nAtom = RegisterClassEx(&wce);
	if (!nAtom)
	{
		MessageBox(NULL, L"RegisterClassEx失败", L"错误", MB_OK);
		return 0;
	}
	const char* szStr = "Main";
	WCHAR wszClassName[256];
	memset(wszClassName, 0, sizeof(wszClassName));
	MultiByteToWideChar(CP_ACP, 0, szStr, strlen(szStr) + 1, wszClassName,
		sizeof(wszClassName) / sizeof(wszClassName[0]));
	HWND hwnd = CreateWindow(wszClassName, L"视频播放", WS_OVERLAPPEDWINDOW, 38, 20, 640, 480, NULL, NULL, hInstance, NULL);
	// 显示窗口  
	ShowWindow(hwnd, SW_SHOW);
	// 更新窗口  
	UpdateWindow(hwnd);
	 

	test1(); //屏幕


	// 消息循环  
	MSG msg;
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return 0;
}

窗口名字要一样 不然找不到

部分教程参考http://www.52ffmpeg.com/edu

讨论群261074724

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值