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的原始视频数据),当然需要考虑同步和缓冲相关问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值