SDL播放yuv

`SDL播放yuv`

获取yuv

先随便找个mp4,给转成yuv

ffmpeg -i 1.mp4 -pix_fmt yuv420p 1.yuv

示例代码

#include "SDL.h"
#include <iostream>
#include <thread>
#include <vector>

#define SDL_QUIT_EVENT (SDL_USEREVENT + 1)
#define SDL_REFRESH_EVENT (SDL_USEREVENT + 2)

int main(int argc, char* argv[])
{
	SDL_Init(SDL_INIT_VIDEO);

	SDL_Rect rect;
	rect.x = rect.y = 0;
	rect.w = 320;
	rect.h = 568;

	SDL_Window* window = SDL_CreateWindow("123", 100, 100, rect.w, rect.h, SDL_WINDOW_SHOWN);
	SDL_ShowWindow(window);
	SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE); 
	SDL_Texture* texture = SDL_CreateTexture(renderer,
		SDL_PIXELFORMAT_IYUV,
		SDL_TEXTUREACCESS_STREAMING,
		rect.w,
		rect.h);
	std::vector<uint8_t> v(rect.w * rect.h + rect.w * rect.h / 4 + rect.w * rect.h / 4);

	FILE* wj = fopen("1.yuv", "rb");
	bool bContinue = true;

	std::thread t([&]() {
		while (bContinue)
		{
			std::cout << "refresh" << std::endl;
			SDL_Event ev_re;
			ev_re.type = SDL_REFRESH_EVENT;
			SDL_PushEvent(&ev_re);
			std::this_thread::sleep_for(std::chrono::milliseconds(40));
		}
		});
	t.detach();

	
	SDL_Event ev;
	while (bContinue)
	{
		SDL_WaitEvent(&ev);
		switch (ev.type)
		{
		case SDL_QUIT:
			bContinue = false;
			break;
		case SDL_KEYDOWN:
			if (SDLK_a == ev.key.keysym.sym)
			{
				std::cout << "press a" << std::endl;
			}
			else if (SDLK_q == ev.key.keysym.sym)
			{
				std::cout << "press q" << std::endl;
				SDL_Event ev_quit;
				ev_quit.type = SDL_QUIT_EVENT;
				SDL_PushEvent(&ev_quit);
			}
			break;
		case SDL_QUIT_EVENT:
			bContinue = false;
			break;
		case SDL_REFRESH_EVENT:
			if (!feof(wj))
			{
				fread(v.data(), 1, v.size(), wj);
				SDL_UpdateTexture(texture, &rect, v.data(), rect.w);
				SDL_RenderClear(renderer);
				SDL_RenderCopy(renderer, texture, NULL, &rect);
				SDL_RenderPresent(renderer);
			}
			break;
		}
	}

	fclose(wj);


	SDL_DestroyWindow(window);

	return 0;
}

直接跑就行了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SDL2.0 支持渲染 YUV4:2:0 格式的视频,需要使用 SDL_Texture 和 SDL_RenderCopy 函数来实现。 以下是一个简单的示例代码: ```c #include <SDL2/SDL.h> #include <stdio.h> const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; int main(int argc, char* argv[]) { SDL_Window* window = NULL; SDL_Renderer* renderer = NULL; SDL_Texture* texture = NULL; if (SDL_Init(SDL_INIT_VIDEO) < 0) { printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError()); return 1; } window = SDL_CreateWindow("YUV4:2:0 Video", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN); if (window == NULL) { printf("Window could not be created! SDL_Error: %s\n", SDL_GetError()); return 1; } renderer = SDL_CreateRenderer(window, -1, 0); if (renderer == NULL) { printf("Renderer could not be created! SDL_Error: %s\n", SDL_GetError()); return 1; } texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_YV12, SDL_TEXTUREACCESS_STREAMING, SCREEN_WIDTH, SCREEN_HEIGHT); if (texture == NULL) { printf("Texture could not be created! SDL_Error: %s\n", SDL_GetError()); return 1; } // YUV data Uint8* yPlane = NULL; Uint8* uPlane = NULL; Uint8* vPlane = NULL; int yPitch = 0; int uPitch = 0; int vPitch = 0; int w = 0; int h = 0; // read YUV file FILE* fp = fopen("video.yuv", "rb"); if (fp == NULL) { printf("Could not open YUV file!\n"); return 1; } // allocate memory for YUV data int bufferSize = SCREEN_WIDTH * SCREEN_HEIGHT * 3 / 2; Uint8* buffer = (Uint8*)malloc(bufferSize); // main loop SDL_Event event; bool quit = false; while (!quit) { while (SDL_PollEvent(&event)) { if (event.type == SDL_QUIT) { quit = true; } } // read YUV data if (fread(buffer, 1, bufferSize, fp) != bufferSize) { // end of file rewind(fp); } // set YUV data yPlane = buffer; uPlane = yPlane + SCREEN_WIDTH * SCREEN_HEIGHT; vPlane = uPlane + SCREEN_WIDTH * SCREEN_HEIGHT / 4; yPitch = SCREEN_WIDTH; uPitch = SCREEN_WIDTH / 2; vPitch = SCREEN_WIDTH / 2; w = SCREEN_WIDTH; h = SCREEN_HEIGHT; // update texture SDL_UpdateYUVTexture(texture, NULL, yPlane, yPitch, uPlane, uPitch, vPlane, vPitch); // clear screen SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF); SDL_RenderClear(renderer); // render texture SDL_RenderCopy(renderer, texture, NULL, NULL); // update screen SDL_RenderPresent(renderer); } // free memory free(buffer); // cleanup SDL_DestroyTexture(texture); SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); return 0; } ``` 在代码中,我们首先创建一个 SDL 窗口和渲染器。然后,使用 SDL_CreateTexture 函数创建一个 YV12 格式的纹理。接下来,读取 YUV 文件,并将数据设置到纹理中。在主循环中,使用 SDL_RenderCopy 函数将纹理渲染到屏幕上。最后,记得在程序结束前释放所有内存和资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值