这是一个小小示例程序
最近需要对一些视频电话的窗口做播放多路视频,简单地用sdl库写了一个测试小程序
不废话,直接上代码:
关于测试程序里面的YUV图像数据,这可以下载到,不过下载有点慢
https://media.xiph.org/video/derf/
#include<iostream>
#include<string>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<vector>
#include"SDL.h"
//窗口的大小
const int SCREEN_WIDTH = 1280;
const int SCREEN_HEIGHT = 720;
//窗口的位置
const int SCREEN_X = 500;
const int SCREEN_Y = 100;
//文件的大小
const int YUV_SIZE_W = 1280;
const int YUV_SIZE_H = 720;
const int YUV_PLAY_X = 0;
const int YUV_PLAY_Y = 0;
//文件的大小
const int YUV_SIZE_W_2 = 352;
const int YUV_SIZE_H_2 = 288;
const int YUV_PLAY_X_2 = 0;
const int YUV_PLAY_Y_2 = 0;
char Yuv_buffer_1[YUV_SIZE_W * YUV_SIZE_H * 12 / 8];
char Yuv_buffer_2[YUV_SIZE_W * YUV_SIZE_H * 12 / 8];
int main(int argv, char* argc[])
{
if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
{
printf("SDL 初始化失败\n");
return -1;
}
//屏幕的大小属于屏幕的
SDL_Window* sdl_win = SDL_CreateWindow("My Vidoe Test", SCREEN_X, SCREEN_Y, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
if (sdl_win == NULL)
{
printf("SDL 创建窗口失败\n");
return -1;
}
SDL_Surface* sdl_win_sur = SDL_GetWindowSurface(sdl_win);
//创建一个窗口的渲染器,一个窗口只能创建一个
SDL_Renderer* sdl_win_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
//第一个文件的纹理YUV数据必须创建打开和读取都一样大 例:1280 * 720
SDL_Texture* yuv_Texture_1 = SDL_CreateTexture(sdl_win_render, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING, YUV_SIZE_W, YUV_SIZE_H);
//第二个文件的纹理
SDL_Texture* yuv_Texture_2 = SDL_CreateTexture(sdl_win_render, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING, YUV_SIZE_W, YUV_SIZE_H);
FILE* yuv_fp_1 = fopen("D:\\C++ Test\\SDL-Test\\SDL_Test\\SDL_Test\\1280x720p50_mobcal_ter.y4m", "rb");
FILE* yuv_fp_2 = fopen("D:\\C++ Test\\SDL-Test\\SDL_Test\\SDL_Test\\1280x720p5994_stockholm_ter.y4m", "rb");
SDL_Rect dest1;
SDL_Rect dest2;
size_t read_size_2 = (YUV_SIZE_W * YUV_SIZE_H * 12 / 8);
size_t read_size = (YUV_SIZE_W * YUV_SIZE_H * 12 / 8);
while (true)
{
memset(Yuv_buffer_1, 0, read_size);
memset(Yuv_buffer_2, 0, read_size);
//读取一帧的数据
if (fread(Yuv_buffer_1, 1, read_size, yuv_fp_1) != read_size) {
fseek(yuv_fp_1, 0, SEEK_SET);
}
//读取一帧的数据
if (fread(Yuv_buffer_2, 1, read_size, yuv_fp_2) != read_size) {
fseek(yuv_fp_2, 0, SEEK_SET);
}
SDL_UpdateTexture(yuv_Texture_1, NULL, Yuv_buffer_1, YUV_SIZE_W);
SDL_UpdateTexture(yuv_Texture_2, NULL, Yuv_buffer_2, YUV_SIZE_W);
SDL_RenderClear(sdl_win_render);
dest1.w = SCREEN_WIDTH;
dest1.h = SCREEN_HEIGHT;
dest1.x = 0;
dest1.y = 0;
SDL_RenderCopy(sdl_win_render, yuv_Texture_1, NULL, NULL);//全面覆盖
//小视频的默认显示在左上角
dest2.w = SCREEN_WIDTH / 2 / 2;
dest2.h = SCREEN_HEIGHT / 2;
dest2.x = SCREEN_WIDTH / SCREEN_WIDTH + 10;
dest2.y = SCREEN_HEIGHT / SCREEN_HEIGHT + 10;
SDL_RenderCopy(sdl_win_render, yuv_Texture_2, NULL, &dest2);
SDL_RenderPresent(sdl_win_render);
SDL_Delay(40);// 延迟40毫秒
}
fclose(yuv_fp_1);
fclose(yuv_fp_2);
SDL_DestroyRenderer(sdl_win_render);
SDL_DestroyTexture(yuv_Texture_1);
SDL_DestroyTexture(yuv_Texture_2);
SDL_DestroyWindow(sdl_win);
SDL_Quit();
system("pause");
return 0;
效果图如下:
联系我:
c_wujinbiao@163.com