ffplay on SDL2 之二

本阶段完成把ffplay移植到sdl2, PC上基本测试:图片,视频OK。

api 1.2

SDL_Surface *screen;

screen = SDL_SetVideoMode(w, h, 0, flags);

SDL_WM_SetCaption

SDL_FillRect

screen->format, w, h

SDL_UpdateRect

SDL_Overlay *bmp;

SDL_CreateYUVOverlay(screen);

SDL_LockYUVOverlay

bmp->pixels[i],pitches[i] //video_thread-->queue_picture; video_image_display-->blend_subrect

//video_refresh-->video_display-->video_image_display

SDL_DisplayYUVOverlay

api 2.0

SDL_Window *win;

SDL_CreateWindow, SDL_SetWindowSize, SDL_SetWindowTitle,

SDL_GetWindowSurface(win)->format,w,h

SDL_Renderer *render;

SDL_CreateRenderer(win), SDL_RenderClear, SDL_RenderCopy, SDL_RenderPresent

SDL_Texture *texture;

SDL_CreateTexture(render), SDL_LockTexture/transform/SDL_UnlockTexture, SDL_UpdateYUVTexture,

问题

Q. YUV格式转换。

A. LockTexture得到的pixel/pitch指向Y。YUV是紧凑排列,没有align,从而可推出U,V的data/pitch。

Q. ffplay a.png输出也是yuv420p ?

A. 是的。在configure_video_filters()设置filt_out的"pix_fmts"。调了vf_scale.c?

avfilter_graph_config-->

graph_config_formats-->query_formats-->"auto-inserted scaler %d"

SDL_Window -- physical pixels you see, 对应多个

SDL_Renderer -- store settings and context,对应多个

SDL_Texture -- resource, element。

Q: texture放到另一个视图显示。

main view -- composited layers

layer view -- individual layer

A:src = SDL_GetWindowSurface(src_win);

fmt = SDL_GetWindowPixelFormat(src_win);

SDL_RenderReadPixels(src_render, 0, fmt, src->pixels, src->pitch);

SDL_UpdateTexture(dst_render, src->pixels, src->pitch);

Q: resize,blend,colorkey?

A: SDL_RenderSetScale(sx, sy)/SDL_RenderCopy with diff rect,

SDL_SetTextureAlphaMod(a)/SDL_SetRenderDrawBlendMode(blend),

Q: 绿边处理duplicate_right_border_pixels().

A: SDL2是否还存在该问题?

render to texture

direct pixels operation

Q: 使用SDL2_Image,

SDL_Surface *s = IMG_Load("in.png");

SDL_Texture *t = SDL_CreateTextureFromSurface(render, s);

SDL_FreeSurface(s);

能不能直接操作纹理?

A: [1]的例子是针对ARGB,使用SDL_UpdateTexture(t,rect, pixels, pitch);

写像素,如果想读像素呢?

SDL_LockTexture(t, rect, &pixels, &pitch);

提供一个只写的像素指针。

而SDL_LockSurface(s)可以对s->pixels进行读写。

针对render的像素读取:

SDL_RenderReadPixels(r, rect, fmt, pixels, pitch);

Q: 因为视频宽高比和窗口宽高不同,四周留黑边,要fill_border-->fill_rectangle-->SDL_Fill/UpdateRect

A: SDL_SetRenderDrawColor(render, a,r,g,b);

4次SDL_RenderFillRect(render, rect);

1次SDL_RenderPresent(render);

跟据SDL2里面的注记,SDL_RenderPresent(render) 把backbuffer显示之后,

backbuffer不再有效,因此建议在新的绘制开始前SDL_RenderClear(),即使每个像素都重写。

于是fill_border代码完全可以省略。

改造计划

====

有人说LockTexture比UpdateYUVTexture慢。

那这里引入Lock是为了直接修改像素,字幕混合blend_subrect用的。

我们不必Lock,只要把字幕当成texture即可!

其实sdl2底层对YUV的处理也是用三个纹理来搞的。

screen --> win

bmp --> texture

blend_subrect --> SDL_UpdateYUVTexture(t,rect, Ydata, Ypitch,...);

剩下的事情是考虑graphics memory 有多大,

VIDEO_PICTURE_QUEUE_SIZE, SUBPICTURE_QUEUE_SIZE配置多少。

调试

====

Q. SDL_CreateRenderer flag =SDL_RENDERER_SOFTWARE 没死, 0死在glEnable()。

A. 只能在主线程render。

video_thread-->queue_picture-->SDL_UpdateYUVTexture_REAL

移到主线程:

refresh_loop_wait_event-->video_refresh-->video_display-->video_image_display

实际上为了简单起见,在alloc_picture时就Update。

代码放在

https://github.com/DeYangLiu/ffmpeg-streaming/blob/master/ffplay2.c

TODO

全屏后左右两边是红边。

测试带字幕的视频。

ref

====

[1] http://www.programmersranch.com/2014/02/sdl2-pixel-drawing.html

时间: 2024-10-26 14:13:08

ffplay on SDL2 之二的相关文章

Win7 VS2015简单编译FFMPEG播放器FFPlay

Win平台简单编译FFPlay播放器,顺便纪念下雷霄骅,一年前刚学FFMPEG时还看过他的博客,昨晚再次搜FFMPEG文章时才知道人已经走了... 做成了视频放到B站 http://www.bilibili.com/video/av8644322/ C++版本也是可以编译的,只是要修改非常多的C语言转C++的强制类型转换,这个例子是C语言写的,改扩展名为cpp后,有不少cpp关键字的参数要修正,不过基本上花点时间就能解决,没什么难度. 现在主要问题是网上能找到的例子,包括FFPlay都是基于SD

[原]零基础学习SDL开发之在Android使用SDL2.0显示BMP图

关于如何移植SDL2.0到安卓上面来参考我的上一篇文章:[原]零基础学习SDL开发之移植SDL2.0到Android 在一篇文章我们主要使用SDL2.0来加载一张BMP图来渲染显示. 博主的开发环境:Ubuntu 14.04 64位,Eclipse + CDT + ADT+NDK 博主曾经自己使用NDK编译出了libSDL2.so,然后使用共享库的方式来调用libSDL2中的函数,结果发现SDL\src\core\android\SDL_android.c 这个jni函数写的实在是不够自己另外做

FFmpeg总结(十二)用ffmpeg与nginx实现直播多路流并发播放

下载 nginx 和 nginx-rtmp源码: http://nginx.org/download/nginx-1.5.10.tar.gz https://github.com/arut/nginx-rtmp-module/archive/master.zip 编译安装: cd nginx-1.5.10 ./configure –with-http_ssl_module –add-module=../nginx-rtmp-module-master make make install 浏览器输

SDL2.0例子代码分析-----CheckKeys Project

SDL简介 SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成.SDL提供了数种控制图像.声音.输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台(Linux.Windows.Mac OS X等)的应用软件.目前SDL多用于开发游戏.模拟器.媒体播放器等多媒体应用领域. SDL1.2和SDL2的差别 SDK1.2和SDL2.1系列的API接口变动的不小,当然功能也大大增强,支持多线程窗口. 具体的change 请看 h

[原]零基础学习SDL开发之在Android使用SDL2.0显示BMP叠加图

关于如何移植在android上使用SDL,可以参考[原]零基础学习SDL开发之移植SDL2.0到Android 和 [原]零基础学习SDL开发之在Android使用SDL2.0显示BMP图 . 在一篇文章我们主要使用SDL2.0来加载一张BMP图来渲染显示,同时叠加一张图作为背景图. 博主的开发环境:Ubuntu 14.04 64位,Eclipse + CDT + ADT+NDK 在前面两篇文章我们知道了如何移植SDL2.0到android上面来,并且可以在Android上面来显示一张图片,这篇

SDL2来源分析3:渲染(SDL_Renderer)

===================================================== SDL源代码分析系列文章上市: SDL2源码分析1:初始化(SDL_Init()) SDL2源码分析2:窗体(SDL_Window) SDL2源码分析3:渲染器(SDL_Renderer) SDL2源码分析4:纹理(SDL_Texture) SDL2源码分析5:更新纹理(SDL_UpdateTexture()) SDL2源码分析6:拷贝到渲染器(SDL_RenderCopy()) SDL2

[原]如何在Android用FFmpeg+SDL2.0解码图像线程

关于如何在Android上用FFmpeg+SDL2.0解码显示图像参考[原]如何在Android用FFmpeg+SDL2.0解码显示图像 ,关于如何在Android使用FFmpeg+SDL2.0解码声音参考[原]如何在Android用FFmpeg+SDL2.0解码声音.但是该文章有一个问题,就是解码出来的声音有很大的噪音,基本无法听清,这是由于对于声音的处理有问题.故本文参考ffmpeg-sdl音频播放分析声音解码的处理,解码出来的声音就正常了. 博主的开发环境:Ubuntu 14.04 64位

[原]零基础学习SDL开发之在Android使用SDL2.0加载字体

在上一篇文章我们知道了如何在android使用SDL2.0来渲染显示一张png图,而且在上上一篇我们知道如何使用sdl来渲染输出bmp图,那么sdl是否可以渲染输出自己喜爱的字体库的字体呢?答案是当然可以. 我们需要移植SDL_ttf字体库来支持相应的字体的渲染输出. 一.移植SDL_ttf库: 使用如下命令,从SDL Mercurial获取SDL_image的源码: hg clone https://hg.libsdl.org/SDL_ttf/ 将SDL_ttf拷贝到在上一篇文章中的andro

SDL2源代码分析3:渲染器(SDL_Renderer)

上一篇文章分析了SDL中创建窗口的函数SDL_CreateWindow().这篇文章继续分析SDL的源代码.本文分析SDL的渲染器(SDL_Renderer). SDL播放视频的代码流程如下所示. 初始化:  SDL_Init(): 初始化SDL. SDL_CreateWindow(): 创建窗口(Window). SDL_CreateRenderer(): 基于窗口创建渲染器(Render). SDL_CreateTexture(): 创建纹理(Texture). 循环渲染数据:  SDL_U