SDL播放YUY2

        最近搞那个SDL播放用USB摄像头采集的数据,其实YUV的数据格式有很多种,一般都要针对相应的格式取得帧数据来给SDL描绘才行。我的摄像头取得的数据是YUY2的,大概过程如下所示:

        

bool CSDL_playerDlg::InitSDL(HWND m_hWnd)
{                                              //初始化,这里主要是把SDL的窗口嵌入到MFC的控件中
   char sdl_var[64];
   sprintf(sdl_var,"SDL_WINDOWID=0x%1x",m_hWnd);//在窗口初始化时加入InitSDL(this->GetDlgItem(IDC_STATIC)->GetSafeHwnd());
   SDL_putenv(sdl_var);

   char *myvalue = SDL_getenv("SDL_WINDOWID");   //让SDL取得窗口ID

   atexit(SDL_Quit);

   pscreen = SDL_SetVideoMode(WIDTH,HEIGHT,24,SDL_SWSURFACE); //设置播放模式
	if(pscreen == NULL)
    {
		TRACE("error SDL SetVideoMode! - %s", SDL_GetError());
		return false;
	}

	poverlay = SDL_CreateYUVOverlay(WIDTH,HEIGHT,SDL_YUY2_OVERLAY,pscreen);  //创建绘制YUV数据的句柄
	if(poverlay == NULL)
	{ 
		TRACE("error SDL CreateYUVOverlay! - %s", SDL_GetError());
		return false; 
	}

	return TRUE;
}



bool CSDL_playerDlg::flip(unsigned char *src,int width,int height)  //描绘YUV数据的过程
{
	SDL_Rect rect;
	rect.w = WIDTH;
	rect.h = HEIGHT;
	rect.x = 0;
	rect.y = 0;
	SDL_LockSurface(pscreen);  
	SDL_LockYUVOverlay(poverlay);
	pbuff = (unsigned char*)poverlay->pixels[0];
        //SDL 的 YUY2 是采用的一个平面的存储方式,即 YUV 三分量交叉存放,此时只有 poverlay->pixels[0] 这个地址有效
	memcpy(pbuff,src,WIDTH*HEIGHT*2);
	SDL_UnlockYUVOverlay(poverlay);
	SDL_UnlockSurface(pscreen);
	SDL_DisplayYUVOverlay(poverlay,&rect);
	return 0;
}



int CSDL_playerDlg::DisplayYuvFile(unsigned char *frame,uint32_t frame_len )
{
	     int used_bytes = 0;
		 
	       used_bytes = dec.dec_main(frame,out_buffer,frame_len ); //这里是解码传来的一帧数据,传输用的是RTP
			flip(out_buffer,WIDTH,HEIGHT);//播放一帧数据
			 SDL_Delay(40);
		 
	return 0;
}


       其实过程什么的很简单,主要是针对对应的格式就OK了,假如是YUV420的话上述相应代码就变成

        outy = out_buffer;

        outu = out_buffer+width*height*5/4;

        outv = out_buffer+width*height;



        for(int y = 0;y < pscreen->h && y < poverlay->h; y++)

        {

                op[0] = poverlay->pixels[0]+poverlay->pitches[0]*y;

                op[1] = poverlay->pixels[1]+poverlay->pitches[1]*(y/2);

                op[2] = poverlay->pixels[2]+poverlay->pitches[2]*(y/2);

                memcpy(op[0],outy+y*width,width);

                if(y%2 == 0)

                {

                   memcpy(op[1],outu+width/2*y/2,width/2);

                   memcpy(op[2],outv+width/2*y/2,width/2);

                }

        }

 
        只要 知道你所要播放的文件的像素存储方式,正确地取出数据,其他步骤就简单了,另外数据解码用的XVID。在这里分享一下少少的经验,也给自己几天来的工作留下个纪念。

你可能感兴趣的:(SDL播放YUY2)