SDL播放YUV

创建测试文件

// 将mp4转yuv
ffmpeg -i hello.mp4 hello.yuv
// 输出内容如下:
[mov,mp4,m4a,3gp,3g2,mj2 @ 000001a216228800] overread end of atom 'colr' by 1 bytes
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'hello.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    encoder         : Lavf55.33.100
    copyright       :
    copyright-eng   :
  Duration: 00:00:32.60, start: 0.000000, bitrate: 2160 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709), 720x1280, 2102 kb/s, 30 fps, 30 tbr, 12800 tbn, 25600 tbc (default)
    Metadata:
      handler_name    : VideoHandler
    Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, mono, fltp, 48 kb/s (default)
    Metadata:
      handler_name    : SoundHandler
Stream mapping:
  Stream #0:0 -> #0:0 (h264 (native) -> rawvideo (native))
Press [q] to stop, [?] for help
Output #0, rawvideo, to 'hello.yuv':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    copyright-eng   :
    copyright       :
    encoder         : Lavf58.45.100
    Stream #0:0(und): Video: rawvideo (I420 / 0x30323449), yuv420p, 720x1280, q=2-31, 331776 kb/s, 30 fps, 30 tbn, 30 tbc (default)
    Metadata:
      handler_name    : VideoHandler
      encoder         : Lavc58.91.100 rawvideo
frame=  978 fps=185 q=-0.0 Lsize= 1320300kB time=00:00:32.60 bitrate=331776.0kbits/s speed=6.17x
video:1320300kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.000000%
// 测试播放
ffplay -s 720x1280 -pix_fmt yuv420p hello.yuv

代码实现

#define IMAGE_WIDTH 720
#define IMAGE_HEIGHT 1280

// 初始化子系统
int ret = SDL_Init(SDL_INIT_VIDEO);
if(ret){
    qDebug() << "SDL_Init error" << SDL_GetError();
    return;
}
// 创建窗口
SDL_Window * _window = SDL_CreateWindow("SDL显示YUV文件",
                 SDL_WINDOWPOS_UNDEFINED,
                 SDL_WINDOWPOS_UNDEFINED,
                 IMAGE_WIDTH,
                 IMAGE_HEIGHT,
                 SDL_WINDOW_SHOWN);
if(!_window){
    qDebug() << "SDL_CreateWindow error" << SDL_GetError();
    SDL_Quit();
    return;
}
// 创建渲染上下文
SDL_Renderer * _renderer = SDL_CreateRenderer(_window,-1,SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if(!_renderer){
    qDebug() << "SDL_CreateRenderer error" << SDL_GetError();
    SDL_DestroyWindow(_window);
    SDL_Quit();
    return;
}
// YUV 420 -> IYUV
// YUYV 422 -> YUY2
// UYVY 422 -> UYVY


// 创建纹理
SDL_Texture * _texture = SDL_CreateTexture(_renderer,SDL_PIXELFORMAT_IYUV,SDL_TEXTUREACCESS_STREAMING,IMAGE_WIDTH,IMAGE_HEIGHT);
if(!_texture){
    qDebug() << "SDL_CreateTexture error" << SDL_GetError();
    SDL_DestroyRenderer(_renderer);
    SDL_DestroyWindow(_window);
    SDL_Quit();
    return;
}
// 打开文件
char * file_name = "../../resources/output.yuv";
QFile file(file_name);
if(!file.open(QFile::ReadOnly)){
    qDebug() << "file open error" << file_name;
    SDL_DestroyTexture(_texture);
    SDL_DestroyRenderer(_renderer);
    SDL_DestroyWindow(_window);
    SDL_Quit();
    return;
}

const int data_size = 1280*720 *1.5;
char buffers [data_size] = {0};
while (file.read(buffers,data_size) > 0) {
    // 将数据填充到texture上
    ret = SDL_UpdateTexture(_texture,nullptr,buffers,IMAGE_WIDTH);
    if(ret){
        qDebug() << "SDL_UpdateTexture error" << SDL_GetError();
        file.close();
        SDL_DestroyTexture(_texture);
        SDL_DestroyRenderer(_renderer);
        SDL_DestroyWindow(_window);
        SDL_Quit();
        return;
    }
    // 设置画笔的颜色
    ret = SDL_SetRenderDrawColor(_renderer,0,0,0,SDL_ALPHA_OPAQUE);
    if(ret){
        qDebug() << "SDL_SetRenderDrawColor error" << SDL_GetError();
        file.close();
        SDL_DestroyTexture(_texture);
        SDL_DestroyRenderer(_renderer);
        SDL_DestroyWindow(_window);
        SDL_Quit();
        return;
    }
    // 清除渲染目标
    ret = SDL_RenderClear(_renderer);
    if(ret){
        qDebug() << "SDL_RenderClear error" << SDL_GetError();
        file.close();
        SDL_DestroyTexture(_texture);
        SDL_DestroyRenderer(_renderer);
        SDL_DestroyWindow(_window);
        SDL_Quit();
        return;
    }

    // 拷贝
    ret = SDL_RenderCopy(_renderer,_texture,nullptr,nullptr);
    if(ret){
        qDebug() << "SDL_RenderCopy error" << SDL_GetError();
        file.close();
        SDL_DestroyTexture(_texture);
        SDL_DestroyRenderer(_renderer);
        SDL_DestroyWindow(_window);
        SDL_Quit();
        return;
    }
    // 更新
    SDL_RenderPresent(_renderer);
    // 暂停显示图片
    SDL_Delay(1000/30);
}

// 回收资源
file.close();
SDL_DestroyTexture(_texture);
SDL_DestroyRenderer(_renderer);
SDL_DestroyWindow(_window);
SDL_Quit();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值