基于SDL库 一个窗口播放多个视频

1 篇文章 0 订阅

这是一个小小示例程序
最近需要对一些视频电话的窗口做播放多路视频,简单地用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

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值