• Android下基于SDL的YUV渲染


    实战篇

    本文主要参考我之前整理的文章windows下使用SDL进行YUV渲染
    相对于之前写的位图渲染部分(http://www.cnblogs.com/tocy/p/android-sdl-bitmap-render-coding.html),yuv渲染主要是增加了yuv加载、texture更新部分。注意本部分的介绍内容是在Android位图渲染框架下增加的YUV渲染部分(具体参考Android下基于SDL的位图渲染(二)理论篇)。
    主要执行流程如下:

    1. 初始化SDL window和render
    2. 加载yuv数据
    3. 创建SDL texture
    4. 使用yuv数据更新texture
    5. texture通过render渲染到window上
    6. 资源销毁及释放
    7. 调用SDL_Quit通知Activity退出

    实现的代码如下:

    extern "C" int yuv_main(int argc, char *argv[]) 
    {
        // init sdl
        if (!init())
        {
            LOGE("%s %d SDL init failed", __FUNCTION__, __LINE__);
            deinit();
            return -1;
        }  
    
        // load yuv
        const char *yuv_path = "/sdcard/test_720x576.yuv";
        LOGI("natvie_SDL %s", yuv_path);
        yuv_frame.width = 720;
        yuv_frame.height = 576;
    	if (!load_yuv(yuv_path))
        {
            LOGE("%s %d load yuv failed", __FUNCTION__, __LINE__);
            deinit();
            return -2;
        }   
    
        // texture operation
        texture_create(yuv_frame.width, yuv_frame.height);
        texture_update();
        texture_render();    
    
        SDL_Delay(2000);
        
    
        // free resources
        unload_yuv();
        texture_destory();
        deinit();
    
        // Quit SDL
        SDL_Quit();
    
        return 0;
    }
    

    其中texture_update实现代码如下:

    static void texture_update()
    {
        void * pixel = NULL;
    	int pitch = 0;
    	if(0 == SDL_LockTexture(texture, NULL, &pixel, &pitch))
    	{
    		// 如果不考虑数据对齐,直接拷贝YUV数据是没有问题的
    		if (pitch == yuv_frame.width)
    		{
    			memcpy(pixel, yuv_frame.data[0], yuv_frame.frame_size);
    		}
    		else // 可能发生pitch > width的情况
    		{
    			// 如果有数据对齐的情况,单独拷贝每一行数据
    			// for Y
    			int h = yuv_frame.height;
    			int w = yuv_frame.width;
    			unsigned char * dst = reinterpret_cast<unsigned char *>(pixel);
    			unsigned char * src = yuv_frame.data[0];
    
    			for (int i = 0; i < h; ++i)
    			{
    				memcpy(dst, src, w);
    				dst += pitch;
    				src += w;
    			}
    
    			h >>= 1;
    			w >>= 1;
    			pitch >>= 1;			
    
    			// for U
    			src = yuv_frame.data[1];
    			for (int i = 0; i < h; ++i)
    			{
    				memcpy(dst, src, w);
    				dst += pitch;
    				src += w;
    			}
    
    			// for V
    			src = yuv_frame.data[2];
    			for (int i = 0; i < h; ++i)
    			{
    				memcpy(dst, src, w);
    				dst += pitch;
    				src += w;
    			}
    		}
    
    		SDL_UnlockTexture(texture);
    	}
    }
    

    关于texture也可以调用SDL_UpdateTexture

    附加说明

    源码下载

    本文中涉及所有源码可以从我的git@OSC,下载之后需要切换到yuv_render的tag即可。

    其他

    本文主要目的是说明如何通过SDL在Android下渲染yuv数据。
    重复调用texture_update()和texture_render()并更新yuv数据即可实现YUV视频序列的渲染。
    如果配合ffmpeg的解码器就可以实现视频播放器的功能(ffmpeg解码器多数输出是基于YUV420的原始视频数据),当然需要考虑同步和缓冲相关问题。

  • 相关阅读:
    复制excel表中的数据
    微信H5页面分享获取JS-SDK
    JS中let、var、const的区别
    JS-对象常用方法整理
    JS-数组常用方法整理
    掌握一门新技术/语言需要哪些步骤?
    浅谈JavaScript中的内存管理
    js对象模型2
    ts中的装饰器
    ts中的泛型
  • 原文地址:https://www.cnblogs.com/tocy/p/android-sdl-yuv-render.html
Copyright © 2020-2023  润新知