前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >【FFmpeg】SDL 音视频开发 ⑥ ( SDL 播放 YUV 视频 | YUV 4:2:0 采样 | YUV420P 格式介绍 | 获取 YUV 视频文件 | 读取并加载 YUV 画面数据 )

【FFmpeg】SDL 音视频开发 ⑥ ( SDL 播放 YUV 视频 | YUV 4:2:0 采样 | YUV420P 格式介绍 | 获取 YUV 视频文件 | 读取并加载 YUV 画面数据 )

作者头像
韩曙亮
发布于 2024-09-06 04:18:37
发布于 2024-09-06 04:18:37
20000
代码可运行
举报
运行总次数:0
代码可运行

博客源码下载 : https://download.csdn.net/download/han1202012/89717218 ;

一、SDL 播放 YUV 视频

1、YUV 4:2:0 采样

【音视频原理】图像相关概念 ④ ( YUV 排列格式 | 打包格式 | 平面格式 | YUV 表示法 | YUV 采样格式表示方法 | YUV 4:2:2 采样 | 上采样与下采样概念 ) 博客中 的 YUV 4:2:0 采样 章节 , 介绍了 YUV420 格式的采样详情 ;

YUV420 格式的 视频中 , 4 个 Y 灰度值 分量 , 才会有一个 UV 色度值 分量 对应 ; 也就是说 四个 Y 灰度值 使用 相同的 UV 色度值 进行编码显示 ;

下图展示的是 YUV 4:2:0 采样的示意图 , 四个 Y 灰度值 分量 , 对应这 一个 UV 色度值 分量 ;

YUV420 采样 , 存储时 , 水平方向进行下采样 , 垂直方向也进行了下采样 , 数据进行了压缩 , YUV 的比例是 4:1:1 , 即 4 和 Y 分量 对应 1 个 UV 分量 ;

2、YUV420P 格式介绍

【音视频原理】图像相关概念 ⑤ ( YUV 数据存储 | I444 格式说明 | I422 格式说明 | I420 格式说明 | NV12 格式说明 | NV21 格式说明 ) 博客中 , 讲解了 YUV420P 格式的具体像素编码排列 ;

YUV420P 数据存储 格式如下图所示 :

不同类型的分量放在不同的数组中 ,

  • Y 灰度值 分量 , 存储在 最上面的数组中 , 在下图的 Y0 ~ Y7 的 灰度值 就是存放在一个数组中 ;
  • U 色度值 分量 , 存储在 中间数组中 , 在下图的 U0 ~ U3 的 色度值 就是存放在一个数组中 , U 的个数只有 4 个 , 是 Y 分量个数的一半 ;
  • V 色度值 分量 , 存储在 最下面的数组中 , 在下图的 V0 ~ V3 的 色度值 就是存放在一个数组中 , V 分量 的个数只有 4 个 , 是 Y 分量 个数的一半 ;

上面的 数据 中 ,

  • Y0 , Y1 , Y4 , Y5 灰度值 使用 U0V0 色度值 , 4 个像素用了 6 字节 , 一个像素 1.5 字节 ;
  • Y2 , Y3 , Y6 , Y7 灰度值 使用 U1V1 色度值 , 4 个像素用了 6 字节 , 一个像素 1.5 字节 ;
  • Y8 , Y9 , Y12 , Y13 灰度值 使用 U2V2 色度值 , 4 个像素用了 6 字节 , 一个像素 1.5 字节 ;
  • Y10 , Y11 , Y14 , Y15 灰度值 使用 U3V3 色度值 , 4 个像素用了 6 字节 , 一个像素 1.5 字节 ;

3、获取 YUV 视频文件

使用 如下命令 , 将 H.264 格式的 视频文件 转为 YUV 格式的文件 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ffmpeg -i input.mp4 -pix_fmt yuv420p output.yuv

上述命令中 -pix_fmt yuv420p 参数的作用是

该 YUV 视频的 画面分辨率是 848x480 ;

这里特别注意 , YUV 视频是 未经压缩的 视频格式 , mp4 格式的视频有 59.3MB , YUV 格式的视频有 1.12GB ;

4、读取 YUV 画面数据

YUV 画面中 , 一个 UV 颜色值 分量 对应 4 个 Y 灰度值 分量 ;

一张画面帧中 , 有 video_width * video_height 个像素点 ,

  • Y 灰度值 分量 有 video_width * video_height 字节 , 则 UV 分量是这个大小的 1/4 ;
  • UV 颜色值 分量 各有 video_width * video_height / 4 字节大小 ;
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    // YUV 格式相关长度计算
    //  Y 分量 是 灰度值分量 , UV 分量 是 颜色值分量
    //  4 个 Y 灰度值分量 对应 1 个 UV 颜色值分量
    uint32_t y_frame_len = video_width * video_height;      // Y分量长度
    uint32_t u_frame_len = video_width * video_height / 4;  // U分量长度
    uint32_t v_frame_len = video_width * video_height / 4;  // V分量长度

这样可以计算出 YUV420P 格式中 每张画面的大小 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    uint32_t yuv_frame_len = y_frame_len + u_frame_len + v_frame_len; // 总长度

数据准备部分代码 :

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    // YUV文件句柄
    FILE *video_fd = NULL;   // 文件指针 , 用于读取 YUV 视频文件路径
    const char *yuv_path = "yuv420p_848x480.yuv"; // YUV文件路径 , 这是一个相对路径

    // 设置 视频缓冲区长度 读取文件时 每次读取多少字节的数据
    size_t video_buff_len = 0;

    // 视频数据缓冲区
    // 读取的 YUV 视频数据存储在该缓冲区中
    uint8_t *video_buf = NULL;

    // YUV 格式相关长度计算
    //  Y 分量 是 灰度值分量 , UV 分量 是 颜色值分量
    //  4 个 Y 灰度值分量 对应 1 个 UV 颜色值分量
    uint32_t y_frame_len = video_width * video_height;      // Y分量长度
    uint32_t u_frame_len = video_width * video_height / 4;  // U分量长度
    uint32_t v_frame_len = video_width * video_height / 4;  // V分量长度
    uint32_t yuv_frame_len = y_frame_len + u_frame_len + v_frame_len; // 总长度

5、加载 YUV 视频数据

首先 , 使用 malloc 为 YUV 缓存空间分配堆内存 , 这个缓冲空间正好可以存放 一帧画面帧的数据 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    // 分配 YUV 视频数据 缓冲区空间
    video_buf = (uint8_t*)malloc(yuv_frame_len); // 分配YUV帧的内存
    if(!video_buf)  // 如果分配失败
    {
        fprintf(stderr, "Failed to alloce yuv frame space!\n"); // 输出错误信息
        goto _FAIL;  // 跳转到失败处理
    }

然后 , 打开 YUV 文件 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    // 打开YUV文件
    video_fd = fopen(yuv_path, "rb");  // 以只读方式打开文件
    if( !video_fd )  // 如果打开失败
    {
        fprintf(stderr, "Failed to open yuv file\n"); // 输出错误信息
        goto _FAIL;  // 跳转到失败处理
    }

最后 , 每次刷新画面时 , 从 YUV 视频文件中 , 读取一帧画面数据 , 然后更新到 SDL_Texture 纹理数据中 ;

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
            video_buff_len = fread(video_buf, 1, yuv_frame_len, video_fd); // 从文件读取数据到缓冲区
            if(video_buff_len <= 0)  // 如果读取失败
            {
                fprintf(stderr, "Failed to read data from yuv file!\n"); // 输出错误信息
                goto _FAIL;  // 跳转到失败处理
            }
            // 更新纹理数据
            SDL_UpdateTexture(texture, NULL, video_buf, video_width);

二、完整代码示例


1、代码示例

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>  // 引入标准输入输出库
#include <string.h> // 引入字符串处理库

#include <SDL.h>    // 引入SDL库

// 自定义消息类型
// 画面刷新事件 , 每秒刷新的次数又称为 FPS , 使用 SDL 现成控制画面帧刷新
#define REFRESH_EVENT   (SDL_USEREVENT + 1)
// 退出事件 , 在 main 函数中的主循环中 , 不停地在循环刷新视频画面 ,
#define QUIT_EVENT      (SDL_USEREVENT + 2)

// 定义分辨率
#define YUV_WIDTH   848   // YUV视频宽度
#define YUV_HEIGHT  480   // YUV视频高度
#define YUV_FORMAT  SDL_PIXELFORMAT_IYUV // YUV格式

// 退出标志,非0值表示退出 , 在 refresh_video_timer 函数中使用该标志位作为循环判定条件
int s_thread_exit = 0;

// 该函数用于 在子线程 中 控制画面的刷新速度
// 子线程 中 向主线程发送 刷新事件 , 主线程收到 REFRESH_EVENT 事件 , 就会刷新界面
// 播放完毕后 主线程 收到 QUIT_EVENT 事件 , 就会停止播放
// 本函数中设置 每 40ms 刷新一次 , 一秒刷新 25 帧 , 25 FPS
int refresh_video_timer(void *data)
{
    while (!s_thread_exit)  // 当未请求退出时
    {
        SDL_Event event;   // 创建事件
        event.type = REFRESH_EVENT; // 设置事件类型为画面刷新
        // 将自定义的 画面刷新事件 推送事件到事件队列
        SDL_PushEvent(&event);
        SDL_Delay(40);  // 延时40毫秒
    }

    s_thread_exit = 0;  // 退出标志重置为0

    // 推送退出事件
    SDL_Event event;
    event.type = QUIT_EVENT;  // 设置事件类型为退出
    SDL_PushEvent(&event);   // 推送事件到事件队列

    return 0;
}
#undef main  // 取消主函数宏定义
int main(int argc, char* argv[])
{
    // 初始化 SDL
    if(SDL_Init(SDL_INIT_VIDEO))  // 初始化SDL视频模块
    {
        fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError());  // 输出错误信息
        return -1;  // 返回错误码
    }

    // SDL相关变量初始化
    SDL_Event event;                    // SDL 事件
    SDL_Rect rect;                      // 矩形区域
    SDL_Window *window = NULL;          // SDL 窗口
    SDL_Renderer *renderer = NULL;      // SDL 渲染器
    SDL_Texture *texture = NULL;        // SDL 纹理
    SDL_Thread *timer_thread = NULL;    // 刷新线程
    uint32_t pixformat = YUV_FORMAT;    // YUV格式

    // YUV 视频 的 分辨率设置
    int video_width = YUV_WIDTH;        // 视频宽度
    int video_height = YUV_HEIGHT;      // 视频高度

    // SDL 播放窗口 分辨率设置
    int win_width = YUV_WIDTH;          // 窗口宽度
    int win_height = YUV_HEIGHT;        // 窗口高度

    // YUV文件句柄
    FILE *video_fd = NULL;   // 文件指针 , 用于读取 YUV 视频文件路径
    const char *yuv_path = "yuv420p_848x480.yuv"; // YUV文件路径 , 这是一个相对路径

    // 设置 视频缓冲区长度 读取文件时 每次读取多少字节的数据
    size_t video_buff_len = 0;

    // 视频数据缓冲区
    // 读取的 YUV 视频数据存储在该缓冲区中
    uint8_t *video_buf = NULL;

    // YUV 格式相关长度计算
    //  Y 分量 是 灰度值分量 , UV 分量 是 颜色值分量
    //  4 个 Y 灰度值分量 对应 1 个 UV 颜色值分量
    uint32_t y_frame_len = video_width * video_height;      // Y分量长度
    uint32_t u_frame_len = video_width * video_height / 4;  // U分量长度
    uint32_t v_frame_len = video_width * video_height / 4;  // V分量长度
    uint32_t yuv_frame_len = y_frame_len + u_frame_len + v_frame_len; // 总长度

    // 创建窗口
    window = SDL_CreateWindow("Simplest YUV Player",  // 窗口标题
                           SDL_WINDOWPOS_UNDEFINED,  // 窗口x坐标
                           SDL_WINDOWPOS_UNDEFINED,  // 窗口y坐标
                           video_width, video_height, // 窗口宽高
                           SDL_WINDOW_OPENGL|SDL_WINDOW_RESIZABLE); // 窗口属性
    if(!window)  // 如果创建失败
    {
        fprintf(stderr, "SDL: could not create window, err:%s\n",SDL_GetError()); // 输出错误信息
        goto _FAIL;  // 跳转到失败处理
    }
    // 创建渲染器
    renderer = SDL_CreateRenderer(window, -1, 0); // 创建基于窗口的渲染器
    // 创建纹理
    texture = SDL_CreateTexture(renderer, pixformat, SDL_TEXTUREACCESS_STREAMING, video_width, video_height); // 创建纹理

    // 分配 YUV 视频数据 缓冲区空间
    video_buf = (uint8_t*)malloc(yuv_frame_len); // 分配YUV帧的内存
    if(!video_buf)  // 如果分配失败
    {
        fprintf(stderr, "Failed to alloce yuv frame space!\n"); // 输出错误信息
        goto _FAIL;  // 跳转到失败处理
    }

    // 打开YUV文件
    video_fd = fopen(yuv_path, "rb");  // 以只读方式打开文件
    if( !video_fd )  // 如果打开失败
    {
        fprintf(stderr, "Failed to open yuv file\n"); // 输出错误信息
        goto _FAIL;  // 跳转到失败处理
    }
    // 创建 YUV 画面 刷新线程 , 该线程与主线程 并行执行
    timer_thread = SDL_CreateThread(refresh_video_timer, NULL, NULL); // 创建刷新线程

    // 在下面 主循环 中 , 不断刷新 YUV 画面数据
    while (1)  // 主循环
    {
        SDL_WaitEvent(&event); // 等待事件发生

        if(event.type == REFRESH_EVENT) // 如果是画面刷新事件
        {
            video_buff_len = fread(video_buf, 1, yuv_frame_len, video_fd); // 从文件读取数据到缓冲区
            if(video_buff_len <= 0)  // 如果读取失败
            {
                fprintf(stderr, "Failed to read data from yuv file!\n"); // 输出错误信息
                goto _FAIL;  // 跳转到失败处理
            }
            // 更新纹理数据
            SDL_UpdateTexture(texture, NULL, video_buf, video_width);

            // 设置显示区域
            rect.x = 0;  // 区域左上角x坐标
            rect.y = 0;  // 区域左上角y坐标
            float w_ratio = win_width * 1.0 /video_width; // 宽度比例
            float h_ratio = win_height * 1.0 /video_height; // 高度比例
            // 计算显示区域宽高
            rect.w = video_width * w_ratio;
            rect.h = video_height * h_ratio;

            // 清除当前显示
            SDL_RenderClear(renderer);
            // 将纹理绘制到渲染器上
            SDL_RenderCopy(renderer, texture, NULL, &rect);
            // 更新显示
            SDL_RenderPresent(renderer);
        }
        else if(event.type == SDL_WINDOWEVENT) // 如果是窗口事件
        {
            // 如果窗口尺寸改变
            SDL_GetWindowSize(window, &win_width, &win_height); // 获取窗口尺寸
            printf("SDL_WINDOWEVENT win_width:%d, win_height:%d\n",win_width, win_height); // 输出新尺寸
        }
        else if(event.type == SDL_QUIT) // 如果是退出事件 , SDL_QUIT 是标准退出事件
        {
            s_thread_exit = 1; // 设置退出标志
        }
        else if(event.type == QUIT_EVENT) // 自定义退出事件
        {
            break; // 退出主循环
        }
    }

_FAIL:
    s_thread_exit = 1;  // 确保线程退出
    // 释放资源
    if(timer_thread)
        SDL_WaitThread(timer_thread, NULL); // 等待线程退出
    if(video_buf)
        free(video_buf);  // 释放视频缓冲区
    if(video_fd)
        fclose(video_fd);  // 关闭文件
    if(texture)
        SDL_DestroyTexture(texture);  // 销毁纹理
    if(renderer)
        SDL_DestroyRenderer(renderer);  // 销毁渲染器
    if(window)
        SDL_DestroyWindow(window);  // 销毁窗口

    SDL_Quit();  // 退出SDL

    return 0;  // 返回成功
}

2、执行效果

运行上述程序 , 效果如下 :

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-09-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
golang调用sdl2,播放yuv视频
golang调用sdl2,播放yuv视频win10 x64下测试成功,其他操作系统下不保证成功。采用的是syscall方式,不是cgo方式。见地址代码如下:package mainimport ("fmt""github.com/moonfdd/sdl2-go/sdl""github.com/moonfdd/sdl2-go/sdlcommon""io/ioutil""time""unsafe")const REFRESH_EVENT = sdl.SDL_USEREVENT + 1 // 请求画面刷新事件co
福大大架构师每日一题
2022/06/16
3740
golang调用sdl2,播放yuv视频
【FFmpeg】SDL 音视频开发 ⑤ ( SDL 播放 YUV 视频 | SDL 播放 YUV 画面流程 | YUV 视频存放位置 | 刷新控制子线程 | 主线程事件处理 )
在 【FFmpeg】SDL 音视频开发 ① ( SDL 窗口绘制 | SDL 视频显示函数 | SDL_Window 窗口 | SDL_Renderer 渲染器 | SDL_Texture 纹理 ) 博客中 , 介绍了
韩曙亮
2024/09/06
1630
【FFmpeg】SDL 音视频开发 ⑤ ( SDL 播放 YUV 视频 | SDL 播放 YUV 画面流程 | YUV 视频存放位置 | 刷新控制子线程 | 主线程事件处理 )
「SDL第八篇」支持倍速与慢放的YUV视频播放器
今天向大家介绍一下如何通过 SDL 实现一个YUV视频播放器。它与上次介绍的音频播放器一样,也是一个简单的不能再简单的播放器了。只不过一个是播放的音频PCM数据,另一个播放的时视频YUV数据。
音视频_李超
2020/04/02
1.1K0
FFmpeg_3.2.4+SDL_2.0.5学习(1)音视频解码帧及显示/播放数据
int OpenAVFile(const char* szFileName) { char errbuf[256] = { 0 }; int iRes = 0; int vindex = -1; AVFormatContext* pFmtCtx = NULL; AVCodecContext* vCodecCtx = NULL; AVCodec* vCodec = NULL; AVPacket* pkt = NULL; AVFrame* pfe = NULL; AVFrame* YUV =
_gongluck
2018/03/08
1.4K0
【音视频连载-005】基础学习篇-SDL 加载 YUV 文件并显示
在前面的文章中已经完成了图片的加载和显示,接下来要做的就是加载 YUV 文件并显示。
音视频开发进阶
2020/03/11
9820
音视频开发中如何使用ffmpeg 一帧H264解码YUV420P?
作为在音视频行业持续发力多年的视频服务厂商,TSINGSEE青犀视频研发了开源平台EasyDarwin,还有多款音视频流媒体平台,我们开发流媒体平台基本都要使用ffmpeg,在ffmpeg中,H264在编码前必须要转换成YUV420P,本文就分享一下怎么将h264转成YUV420P。
TSINGSEE青犀视频
2021/08/04
1K0
FFmpeg 内容介绍 音视频解码和播放
FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。FFmpeg本身是跨平台的,支持多个平台。
包子388321
2020/07/21
2.3K0
Android Bitmap转I420的坑,以及图文详解YUV420数据格式
今天Android要把Bitmap里的数据转成I420,用的YUV库,但是总有色差。查了好久,最终发现
望天
2020/03/11
3.7K0
音视频开发之旅(34) - 基于FFmpeg实现简单的视频解码器
FFmpeg解码涉及的知识点比较多,很容易被函数和结构体搞定不知所错,我们先从整体上对解码流程有个认知,画了张图把解码流程图,如下
音视频开发之旅
2021/02/28
1.4K0
【音视频原理】图像相关概念 ④ ( YUV 排列格式 | 打包格式 | 平面格式 | YUV 表示法 | YUV 采样格式表示方法 | YUV 4:2:2 采样 | 上采样与下采样概念 )
YUV 格式 的 颜色编码算法 有 很多排列格式 , 但是大概可以分为以下两大类 :
韩曙亮
2024/01/21
2930
【音视频原理】图像相关概念 ④ ( YUV 排列格式 | 打包格式 | 平面格式 | YUV 表示法 | YUV 采样格式表示方法 | YUV 4:2:2 采样 | 上采样与下采样概念 )
音视频技术(5)-iOS ffmpeg+SDL播放视频
参照SDL官网文档说明,iOS上使用SDL显示图像,需要修改main入口,SDL有自己的appdelegate实现,
公号sumsmile
2020/03/27
1.4K0
【音视频原理】图像相关概念 ⑤ ( YUV 数据存储 | I444 格式说明 | I422 格式说明 | I420 格式说明 | NV12 格式说明 | NV21 格式说明 )
YUV 4:4:4 采样格式 , Y 亮度分量 与 UV 色度分量 的比例是 1:1 ;
韩曙亮
2024/01/21
1.2K0
【音视频原理】图像相关概念 ⑤ ( YUV 数据存储 | I444 格式说明 | I422 格式说明 | I420 格式说明 | NV12 格式说明 | NV21 格式说明 )
FFmpeg简易播放器的实现-视频播放
下图引用自“雷霄骅,视音频编解码技术零基础学习方法”,因原图太小,看不太清楚,故重新制作了一张图片。
叶余
2019/04/02
4.5K0
FFmpeg简易播放器的实现-视频播放
图解YU12、I420、YV12、NV12、NV21、YUV420P、YUV420SP、YUV422P、YUV444P的区别
YUV模型是根据一个亮度(Y分量)和两个色度(UV分量)来定义颜色空间,常见的YUV格式有YUY2、YUYV、YVYU、UYVY、AYUV、Y41P、Y411、Y211、IF09、IYUV、YV12、YVU9、YUV411、YUV420等,其中比较常见的YUV420分为两种:YUV420P和YUV420SP。
全栈程序员站长
2022/09/13
3.3K0
图解YU12、I420、YV12、NV12、NV21、YUV420P、YUV420SP、YUV422P、YUV444P的区别
FFmpeg4.0+SDL2.0笔记02:Outputting to the Screen
背景:在系统性学习FFmpeg时,发现官方推荐教程还是15年的,不少接口已经弃用,大版本也升了一级,所以在这里记录下FFmpeg4.0+SDL2.0的学习过程。
非一
2021/04/06
5650
结合ffmpeg用SDL播放YUV实现简易播放器
通过解码之后得到的yuv视频数据我们直接可以进行播放,本篇使用SDL来实现视频播放。
曾大稳
2018/09/11
1.3K0
SDL2库(2)-Android 端集成FFmpeg及简单的播放器
项目位置 https://github.com/deepsadness/SDLCmakeDemo
deep_sadness
2018/12/14
1.7K0
SDL2库(2)-Android 端集成FFmpeg及简单的播放器
FFmpeg简易播放器的实现-最简版
下图引用自“雷霄骅,视音频编解码技术零基础学习方法”,因原图太小,看不太清楚,故重新制作了一张图片。
叶余
2019/04/02
1.5K0
FFmpeg简易播放器的实现-最简版
【音视频连载-006】基础学习篇-SDL 播放 YUV 视频文件
我们已经能够加载 YUV 帧并显示了,那是把一张图片转换成 YUV 帧得到的素材。
音视频开发进阶
2020/03/12
8770
Android 基于OpenGl ES渲染yuv视频(十二)
本文是基于前面两篇OpenGl理论学习的实际应用,更好的巩固一下前面的学习内容,重点讲下如何使用OpenGl去渲染一个yuv格式视频。
PengJie
2021/01/14
2.4K0
推荐阅读
golang调用sdl2,播放yuv视频
3740
【FFmpeg】SDL 音视频开发 ⑤ ( SDL 播放 YUV 视频 | SDL 播放 YUV 画面流程 | YUV 视频存放位置 | 刷新控制子线程 | 主线程事件处理 )
1630
「SDL第八篇」支持倍速与慢放的YUV视频播放器
1.1K0
FFmpeg_3.2.4+SDL_2.0.5学习(1)音视频解码帧及显示/播放数据
1.4K0
【音视频连载-005】基础学习篇-SDL 加载 YUV 文件并显示
9820
音视频开发中如何使用ffmpeg 一帧H264解码YUV420P?
1K0
FFmpeg 内容介绍 音视频解码和播放
2.3K0
Android Bitmap转I420的坑,以及图文详解YUV420数据格式
3.7K0
音视频开发之旅(34) - 基于FFmpeg实现简单的视频解码器
1.4K0
【音视频原理】图像相关概念 ④ ( YUV 排列格式 | 打包格式 | 平面格式 | YUV 表示法 | YUV 采样格式表示方法 | YUV 4:2:2 采样 | 上采样与下采样概念 )
2930
音视频技术(5)-iOS ffmpeg+SDL播放视频
1.4K0
【音视频原理】图像相关概念 ⑤ ( YUV 数据存储 | I444 格式说明 | I422 格式说明 | I420 格式说明 | NV12 格式说明 | NV21 格式说明 )
1.2K0
FFmpeg简易播放器的实现-视频播放
4.5K0
图解YU12、I420、YV12、NV12、NV21、YUV420P、YUV420SP、YUV422P、YUV444P的区别
3.3K0
FFmpeg4.0+SDL2.0笔记02:Outputting to the Screen
5650
结合ffmpeg用SDL播放YUV实现简易播放器
1.3K0
SDL2库(2)-Android 端集成FFmpeg及简单的播放器
1.7K0
FFmpeg简易播放器的实现-最简版
1.5K0
【音视频连载-006】基础学习篇-SDL 播放 YUV 视频文件
8770
Android 基于OpenGl ES渲染yuv视频(十二)
2.4K0
相关推荐
golang调用sdl2,播放yuv视频
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验