SDL使用

     近期在研究怎样使用SDL显示ffmpeg库解码后的YUV数据,在网上有很多的文章介绍调用SDL的步骤:

1 绑定显示窗口的句柄到SDL上

2 初始化SDL

3 设置显示的surface

4 设置Overlay表面

5 显示YUV数据大小进行自适应的显示


1 并且SDL调用分为两种显示模式,一种为windib,另一种为DX5

 当SDL显示使用的windib模式时,SDL_SetVideoModel中的参数需要对图片的长宽和屏幕分辨率进行比较,取较大值作为该接口的长宽设置参数,才能使图像随窗口变化;使用DX5时,只需要传进原始图像的长宽即可

当对听一个视频文件进行窗口大小的变化时,不需要在变化时再次对SDL进行初始化,只需在SDL_DisplayYUVOverlay时,要显示一帧时,将窗口大小参数每次都将为参数穿进去就可以了,但是在播放器中难免要切换视频文件,如果文件的分辨率不一致,就要对SDL再次进行初始化了,由于SDL_SetVideoModel创建的Surface不再适用,所以切换后的视频文件可能会显示不正常。

2 在对YUV分量分辨进行拷贝赋值时,起初的版本是:

char *pbuf;  //YUV数据

memcpy(u,pbuf,w*h);

memcpy(v,pubf+w*h*5/4,w*h/4);

memcpy(v,pubf+w*h,w*h/4);

       通过这样的拷贝赋值后,在调用Display接口进行显示,发现在两台相同分辨率的电脑上,一台显示正常,另一台会出现花屏的现象,开始以为是初始化时创建的Suface的长宽值不对应造成的,最后经过检查,并不是这个问题导致的了,将以上的赋值代码修改为网上常见的版本:

{

SDL_Overlay overlay = SDL_CreateYUVOverlay(w, h, SDL_YV12_OVERLAY, screen);

char *outy = buffer;
char *outv = buffer+w*h;
char *outu= buffer+w*h*5/4;
for(y=0;y<screen->h ;y++)
{
     op[0]=overlay->pixels[0]+overlay->pitches[0]*y;
  op[1]=overlay->pixels[1]+overlay->pitches[1]*(y/2);
  op[2]=overlay->pixels[2]+overlay->pitches[2]*(y/2); 
memcpy(op[0],outy+y*w,w);
if(y%2 == 0)
{
         memcpy(op[1],outu+w/2*y/2,w/2);
memcpy(op[2],outv+w/2*y/2,w/2);    
        }

}

 其实两段代码对于YUV分量的拷贝过程基本是相同的,但是SDL做了一个处理很关键,对于overlay->pitches[0]这个参数,他决定了在拷贝分量时,能在拷贝完一行的像素点后,确定下一行的起始位置。

     如果屏幕的分辨率要大于图片宽度,则会选择将差值的宽度值留空,可能不做赋值处理(处理有待考究),这样保证图片的一行像素拷贝在屏幕的对应行上,而起始的那段代码会出现由于不能确定第一行复制的结束为止,而会紧接着继续拷贝分量值,从而在某些电脑会出现花屏问题了。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值