随笔 - 632  文章 - 17  评论 - 54  阅读 - 93万

SDL播放YUV数据

一、概述

  上一节使用SDL2在窗口上显示了一张图片,本节使用SDL2播放YUV420P数据。

  YUV420P一帧数据的长度=width*height*3/2

  参考:雷霄骅大神的博客

二、代码示例

  下面这段示例代码读取YUV数据和现实YUV数据都是在同一个线程中的。播放是能播放,但是会很卡,不一会儿就会出现无响应的情况。下一节使用多线程进行改造

复制代码
#include "include/sdl_read_yuv.h"
#include <iostream>
using namespace std;

SDLReadYuv::SDLReadYuv() {

    const int bpp = 12;
    int window_w = 640, window_h = 360;
    const int pixel_w = 640, pixel_h = 360;
    unsigned char buffer[pixel_w * pixel_h * bpp / 8];

    if (SDL_Init(SDL_INIT_VIDEO)) {
        cout << "初始化SDL失败" << SDL_GetError() << endl;
        return;
    }

    SDL_Window* window;
    window = SDL_CreateWindow("Simplest Video Play SDL2",
        SDL_WINDOWPOS_UNDEFINED,
        SDL_WINDOWPOS_UNDEFINED,
        window_w,
        window_h,
        SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE);

    if (!window) {
        cout << "SDL: could not create window" << SDL_GetError() << endl;
        return;
    }

    SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, 0);

    Uint32 pixFormat = 0;
    pixFormat = SDL_PIXELFORMAT_IYUV;

    SDL_Texture* texture = SDL_CreateTexture(renderer, pixFormat, SDL_TEXTUREACCESS_STREAMING, pixel_w, pixel_h);

    FILE* fp = NULL;
    fp = fopen("E:/tony/demo/visualstudio_workspace/SDLDemo/out/build/x64-debug/SDLDemo/yuv/sintel_640_360.yuv", "rb+");
    if (fp == NULL) {
        cout << "cannot open this file" << endl;
        return;
    }

    //这个区域会存放显示的视频
    SDL_Rect sdlRect;

    while (true) {
        //这里是读取一帧视频真,数据格式是YUV420P,像素排列是4:2:0,一行像素=width*height+width*1/4+height*1/4 = width*height*3/2
        //所以下面这句话刚好就是读取了一个视频帧YUV的数据长度
        if (fread(buffer, 1, pixel_w * pixel_h * bpp / 8, fp) != pixel_w * pixel_h * bpp / 8) {
            // Loop
            fseek(fp, 0, SEEK_SET);
            fread(buffer, 1, pixel_w * pixel_h * bpp / 8, fp);
        }

        SDL_UpdateTexture(texture, NULL, buffer, pixel_w);

        sdlRect.x = 0;
        sdlRect.y = 0;
        sdlRect.w = window_w;
        sdlRect.h = window_h;//把视频就显示到这个区域

        SDL_RenderClear(renderer);
        SDL_RenderCopy(renderer, texture, NULL, &sdlRect);
        SDL_RenderPresent(renderer);

        SDL_Delay(40);

    }

    SDL_DestroyTexture(texture);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);

    SDL_Quit();

}
复制代码

 

posted on   飘杨......  阅读(62)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
历史上的今天:
2014-11-14 Unable to execute dex: Multiple dex files defineLcom/google/gson/JsonDeserializer;
2014-11-14 Android 工程引入自定义Library后,工程无法识别Library中的类
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示