zoukankan      html  css  js  c++  java
  • 音视频之播放YUV数据(十二)

    使用SDL显示YUV数据

    宏定义

    extern "C" {
    #include <libavutil/imgutils.h>
    }
    
    #define RET(judge, func) \
        if (judge) { \
            qDebug() << #func << "error" << SDL_GetError(); \
            return; \
        }
    
    static const std::map<AVPixelFormat, SDL_PixelFormatEnum>
    PIXEL_FORMAT_MAP = {
        {AV_PIX_FMT_YUV420P, SDL_PIXELFORMAT_IYUV},
        {AV_PIX_FMT_YUYV422, SDL_PIXELFORMAT_YUY2},
        {AV_PIX_FMT_NONE, SDL_PIXELFORMAT_UNKNOWN}
    };

    变量定义

     SDL_Window *_window = nullptr;
     SDL_Renderer *_renderer = nullptr;
     SDL_Texture *_texture = nullptr;
     QFile _file;
     int _timerId = 0;
     State _state = Stopped;
     Yuv _yuv;
     bool _playing;

    创建窗口

    // 创建窗口
    _window = SDL_CreateWindowFrom((void *)winId());
    RET(!_window, SDL_CreateWindow);

    创建渲染上下文

    // 创建渲染上下文
        _renderer = SDL_CreateRenderer(_window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
        if (!_renderer) {
            _renderer = SDL_CreateRenderer(_window, -1, 0);
            RET(!_renderer, SDL_CreateRenderer);
        }

    创建纹理

    // 创建纹理
        _texture = SDL_CreateTexture(_renderer,
                                     PIXEL_FORMAT_MAP.find(yuv.pixelFormat)->second,
                                     SDL_TEXTUREACCESS_STREAMING,
                                     yuv.width,
                                     yuv.height);
        RET(!_texture, SDL_CreateTextureFromSurface);

    打开文件

     // 打开文件
        _file.setFileName(yuv.filename);
        if (!_file.open(QFile::ReadOnly)) {
            qDebug() << "file open error" << yuv.filename;
        }

    渲染

    // 图片大小
        int imgSize = av_image_get_buffer_size(_yuv.pixelFormat,
                                               _yuv.width,
                                               _yuv.height,
                                               1);
    
        char data[imgSize];
        if (_file.read(data, imgSize) > 0) {
            // 将YUV的像素数据填充到texture
            RET(SDL_UpdateTexture(_texture, nullptr, data, _yuv.width), SDL_UpdateTexture);
    
            // 设置绘制颜色 (画笔颜色)
            RET(SDL_SetRenderDrawColor(_renderer, 0, 0, 0, SDL_ALPHA_OPAQUE), SDL_SetRenderDrawColor);
    
            //用绘制颜色 (画笔颜色) 清除渲染目标
            RET(SDL_RenderClear(_renderer), SDL_RenderClear);
    
            // 拷贝纹理数据到渲染目标(默认是window)
            RET(SDL_RenderCopy(_renderer, _texture, nullptr, nullptr), SDL_RenderCopy);
    
            // 更新所有的渲染操作到屏幕上
            SDL_RenderPresent(_renderer);
        } else {
            // 文件数据已经读取
            killTimer(_timerId);
        }

    对应的播放、暂停、播放状态

    void YuvPlayer::play() {
        _timerId = startTimer(1000 / _yuv.fps);
        _state = YuvPlayer::Playing;
    }
    
    void YuvPlayer::pause() {
        if (_timerId) {
            killTimer(_timerId);
        }
        _state = YuvPlayer::Paused;
    }
    
    void YuvPlayer::stop() {
        if (_timerId) {
            killTimer(_timerId);
        }
        _state = YuvPlayer::Stopped;
    }
    
    bool YuvPlayer::isPlaying() {
        return _state == YuvPlayer::Playing;
    }
    
    YuvPlayer::State YuvPlayer::getstate() {
        return _state;
    }

    释放资源

    YuvPlayer::~YuvPlayer() {
        _file.close();
        SDL_DestroyTexture(_texture);
        SDL_DestroyRenderer(_renderer);
        SDL_DestroyWindow(_window);
    }
  • 相关阅读:
    Codeforces Round #513解题报告(A~E)By cellur925
    Luogu P1463 [POI2002][HAOI2007]反素数【数论/dfs】By cellur925
    NOIp2016 蚯蚓 【二叉堆/答案单调性】By cellur925
    Luogu P4139 上帝与集合的正确用法【扩展欧拉定理】By cellur925
    hdu 4704 Sum【组合数学/费马小定理/大数取模】By cellur925
    poj 1723 Soldiers【中位数】By cellur925
    MyBatis 简介
    对象导航查询和OID查询(补)
    Hibernate查询方式(补)
    Hibernate一级缓存(补)
  • 原文地址:https://www.cnblogs.com/muzichenyu/p/15577756.html
Copyright © 2011-2022 走看看