#include "SDL.h"

#include "as_lesson_log.h"

#define PATH_YUV420 "/sdcard/output.yuv"

#define width 1280

#define height 720

extern "C" int yuv_main(int argc, char *argv[])

{

//根据分辨率计算Y,U,V的长度

int lenY = width * height;

int lenU = width * height / 4;

int lenV = width * height / 4;

Uint8 *pYBuf = (Uint8 *)malloc(lenY);

Uint8 *pUBuf = (Uint8 *)malloc(lenU);

Uint8 *pVBuf = (Uint8 *)malloc(lenV);

FILE *pFile = fopen(PATH_YUV420, "rb");

if (pFile == NULL) {

LOGE("%s %d load yuv failed", __FUNCTION__, __LINE__);

return -1;

}

//初始化SDL

if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) == -1) {

LOGE("SDL_Init failed %s", SDL_GetError());

return -1;

}

SDL_Window *window = SDL_CreateWindow("SDL_WINDOW_TITLE", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, 0);

SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0); //渲染器

SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_IYUV, SDL_TEXTUREACCESS_STREAMING, width, height); //纹理是渲染的内容

SDL_Rect rect;

rect.x = 0;

rect.y = 0;

rect.w = width;

rect.h = height;

while (true) {

if ((fread((void *)pYBuf, 1, lenY, pFile) == 0 || fread((void *)pUBuf, 1, lenU, pFile) == 0 || fread((void *)pVBuf, 1, lenV, pFile) == 0)) {

LOGI("SDL_file-end");

break;

}

SDL_UpdateYUVTexture(texture, &rect, pYBuf, width, pUBuf, width / 2, pVBuf, width / 2);

//下面开始显示纹理

SDL_RenderClear(renderer);

// SDL_RenderCopy(renderer, texture, NULL, &rect);

SDL_RenderCopy(renderer, texture, NULL, NULL);

SDL_RenderPresent(renderer);

SDL_Delay(45);

}

fclose(pFile);

free((void *)pYBuf);

free((void *)pUBuf);

free((void *)pVBuf);

return 0;

}

思路:

while (true) {

如果YUV读取完,退出

YUV渲染

SDL_Delay(45); //加这个延时进行伪帧率控制。45ms放一帧。22.2帧每秒,167X45=7.5s放完

//Delay 40ms,25FPS 40X25 = 1000ms=1s

}

问题点:

1,播放时候,视频不能全屏。

有2个关键函数,SDL_UpdateYUVTextureSDL_RenderCopy,

一个是设置纹理,一个是把纹理放到渲染器。

只需要把输出到目标渲染器的窗口设为null就行,之前设为原始视频的大小。

2,第一次可以放,第二次不行。

加了创建失败的调制信息后发现

那是c最后退出时候,没加SDL_Quit(); 所以窗口没回收,第二次创建时候,窗口创建失败。看日志

2019-04-18 16:02:18.741 29208-29208/com.gx123.net_wifi.leesoo V/SDL: Window size: 1920x1008

2019-04-18 16:02:18.748 29208-29674/com.gx123.net_wifi.leesoo I/SDL: SDL_Android_Init()

2019-04-18 16:02:18.748 29208-29674/com.gx123.net_wifi.leesoo I/SDL: SDL_Android_Init() finished!

2019-04-18 16:02:18.749 29208-29674/com.gx123.net_wifi.leesoo E/as_lesson: SDL_CreateWindow failed Android only supports one window

2019-04-18 16:02:18.749 29208-29674/com.gx123.net_wifi.leesoo E/as_lesson: SDL_CreateRenderer failed Invalid window

2019-04-18 16:02:18.749 29208-29674/com.gx123.net_wifi.leesoo E/as_lesson: yuv_main 47 createtexture failed Invalid renderer

疑惑点;

1, 渲染器和纹理的对应关系和显示大小比例。

纹理比喻画布? 没有存数据,只是把数据信息最后给渲染器 ?

纹理大,渲染器小,会显示不全,纹理小,渲染器大,会有黑边。

http://www.hewebgl.com/article/getarticle/108

2,怎么循环渲染每一帧。怎么知道这一帧渲染完了到下一帧

解决2:文件读取函数fread 发挥作用了。

size_t   fread(   void   *buffer,   size_t   size,   size_t   count,   FILE   *stream   )

buffer   是读取的数据存放的内存的指针

size       是每次读取的字节数

count     一共要读取次数

strean   是要读取的文件的指针

例如   从文件fp里读取100个字节   可用以下3个语句

fread(buffer,100,1,fp)

fread(buffer,50,2,fp)

fread(buffer,1,100,fp)

 fread每调用一次,文件指针都会往下移动,缓冲区会更新。

A,本文的用法。

if ((fread((void *)pYBuf, 1, lenY, pFile) == 0 || fread((void *)pUBuf, 1, lenU, pFile) == 0 || fread((void *)pVBuf, 1, lenV, pFile) == 0))

YUV3个缓存分开,一次读3个缓存更新。 读取次数是一帧图像的YUV个数。

调用读Y数据,接着调用读U数据,再调用读V数据。

最终更新时候 pYBuf 有 W*H 个字节,pUBuf有 W*H/4个 字节,pVBuf有 W*H/4个 字节

然后把3个分量更新SDL_UpdateYUVTexture

下次再循环读取(fread((void *)pYBuf, 1, lenY, pFile 时候,pFile的文件指针已经指向下一帧了。

B,Tony用法

加载完YUV帧,还考虑数据对其。

C,其他文章

if (fread(buffer, 1, pixel_w*pixel_h*bpp/8, fp) != pixel_w*pixel_h*bpp/8){

// Loop

fseek(fp, 0, SEEK_SET);

i--;

continue;

}

//更新纹理数据

SDL_UpdateTexture( sdlTexture, NULL, buffer, pixel_w);

这个就是一次读取一帧,这帧包含YUV3个。 然后把这帧缓冲区放到纹理上去。

纹理一次渲染一帧,不是一个yuv3字节的点。

SDL播放YUV——循环的更多相关文章

  1. FFMPEG学习----使用SDL播放YUV数据

    命令行下配置: G:\Coding\Video\SDL\proj>tree /F 文件夹 PATH 列表 卷序列号为 0FD5-0CC8 G:. │ sdl.cpp │ SDL2.dll │ S ...

  2. 【转载】使用SDL播放YUV图像数据(转)

    SDL提供了针对YUV格式数据的直接写屏操作.废话不多说,直接上代码吧/** * file showyuv.c * author: rare * date: 2009/12/06 * email: d ...

  3. SDL 开发实战(六): 使用 SDL 实现 YUV 播放器

    前面铺垫了这么多,现在终于进入核心的主题了,那就是使用SDL播放视频,本节我们将使用SDL播放YUV视频,也就是做一个YUV播放器. 下面说明一下使用SDL播放YUV视频的基本流程,主要分为两大部分: ...

  4. 最简单的视音频播放示例3:Direct3D播放YUV,RGB(通过Surface)

    上一篇文章记录了GDI播放视频的技术.打算接下来写两篇文章记录Direct3D(简称D3D)播放视频的技术.Direct3D应该Windows下最常用的播放视频的技术.实际上视频播放只是Direct3 ...

  5. 最简单的视音频播放示例2:GDI播放YUV, RGB

    前一篇文章对“Simplest Media Play”工程作了概括性介绍.后续几篇文章打算详细介绍每个子工程中的几种技术.在记录Direct3D,OpenGL这两种相对复杂的技术之前,打算先记录一种和 ...

  6. SDL播放YUV----单帧

    用到的项目:Tocy-Android-SDLv2 C中的 入口: main.c as_lesson_XXX.c bmp_main : 在C中定义文件的路径: char *filepath = &quo ...

  7. 最简单的视音频播放演示样例3:Direct3D播放YUV,RGB(通过Surface)

    ===================================================== 最简单的视音频播放演示样例系列文章列表: 最简单的视音频播放演示样例1:总述 最简单的视音频 ...

  8. SDL开发笔记(二):音频基础介绍、使用SDL播放音频

    若该文为原创文章,未经允许不得转载原博主博客地址:https://blog.csdn.net/qq21497936原博主博客导航:https://blog.csdn.net/qq21497936/ar ...

  9. MFC中使用SDL播放音频没有声音的解决方法

    本文所说的音频是指的纯音频,不包含视频的那种. 在控制台中使用SDL播放音频,一般情况下不会有问题. 但是在MFC中使用SDL播放音频的时候,会出现没有声音的情况.经过长时间探索,没有找到特别好的解决 ...

随机推荐

  1. C#Mvc4.0IIS部署(内网)

    安装IIS(百度中搜索教程安装) 在Vs中将项目发布到文件夹 回到桌面,右键计算机=>管理=>服务和应用程序=>Internet信息服务(IIS)管理器 右键添加新网站,输入网站名称 ...

  2. javascript20150124

    表达式与运算符 表达式 与数学中的定义相似,表达式是指具有一定的值的.用运算符把常数和变量连接起来的代数式.一个表达式可以只包含一个常数或一个变量.运算符可以是四则运算符.关系运算符.位运算符.逻辑运 ...

  3. 第1次作业—— 熟悉 MoocTest环境

    2.1 Mooctest 使用心得 Mooctest很方便,可以即时测评自己写的测试代码,获得覆盖率和报告,不需要自己安装配置环境 而且安装配置插件的环境也很简单,可以专注于测试本身 2.2 Juni ...

  4. Flask项目笔记

    一.jsonify  jsonify 是flask的函数,可以将字典转换成json数据返回给浏览器二. 钩子函数 @app.before_first_request:第一次请求调用,用于初始化数据 @ ...

  5. Python 字典dict相关知识

    字典是无序的,多次print输出的结果不一样. 字典的key可以是数字.字符串.元组.布尔值(True为1,False为0,不可以和其他key值重复):列表和字典不能作为key. 字典的value可以 ...

  6. css颜色,字体大小的设置

    设置字体的颜色通过下面的代码: color : #f00; color是颜色的意思,color用来设置一个标签的前景色,表现出来也就是元素文本的颜色. 它的值,一般都是使用#加16进制的颜色值来表示. ...

  7. selenium中下拉框的定位

    from selenium import webdriverfrom selenium.webdriver.support.select import Selectimport timedriver ...

  8. .NetCore多文件上传进度的示例

    主要讲的内容有: 1-----form方式上传一组图片 2-----ajax上传一组图片 3-----ajax提交+上传进度+一组图片上传 4-----Task并行处理+ajax提交+上传进度+一组图 ...

  9. webservice和dubbo区别

    webservice  不需要搭建注册中心,是一个服务框架,主要内容有soap协议,uuid注册中心,wsdl文件. dubbo   需要搭建注册中心,可以是zookeeper,redis.它是一个分 ...

  10. [python3.6+opencv] 01 完成读取图片操作

    学习一下opencv3 奈何vs2017配的云里雾里,还是使用python吧 --人生苦短,python来凑 --使用Pycharm操作,面向界面的Pycharm好一些吧(我猜的) 新建Project ...