android yuv数据处理_Android SDL移植 显示YUV数据 | 学步园
SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台)的应用软件。目前SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。在1.3的版本已经可以完美兼容AndroidSDL1.3的源码可以到这个网址下载:http://download
SDL(Simple DirectMedia Layer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函数,让开发者只要用相同或是相似的代码就可以开发出跨多个平台)的应用软件。目前SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。
在1.3的版本已经可以完美兼容Android
SDL1.3的源码可以到这个网址下载:http://download.csdn.net/detail/yqiang5152/5017621。
YUV测试序列下载地址:
下面是具体步骤:
1.将下载下来的zip包,解压,将文件名改为SDL,将SDL文件夹中的android-project拷贝出来。将SDL中的src和include以及根目录下的Android.mk文件,拷贝到android-project/jni 中。
2.将yuv测试序列拷贝到虚拟机或手机的sdcard上
3.通过分析SDL/src/main/SDL_android_main.cpp文件,我们可以发现,在java层调用nativeInit时,c层会执行SDL_main(),方法,而这个方法是在SDL_main.h中,将我们写的main函数重定义为SDL_main(),所以,我们自己的C代码中的main函数,即是入口。
4.播放yuv数据的C函数如下,写好的文件放在 android-project/jni/src中
#include "SDL.h"
#include
#include
#include
#include
#include
#include
#include
#include "MySDL.h"
#define LOG_TAG "JNI MYSDL"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
extern SDL_Surface* screen = NULL;
extern SDL_Overlay* overlay = NULL;
int play_SDL(int w, int h, char* pYuv, int zoom,int cutedW,int cutedH,int offsetX,int offsetY) {
//播放一帧的YUV数据,这里的yuv数据只的是YUV420
if (NULL == pYuv || w <= 0 || h <= 0)
{
return -1;
}
SDL_Rect rectSrc;
if(cutedW>0 || cutedH>0)
{
change_Overlay(cutedW,cutedH);
}
SDL_LockSurface(screen);
SDL_LockYUVOverlay(overlay);
if(cutedW==0 && cutedH==0)
{
memcpy(overlay->pixels[0], pYuv, w * h);
memcpy(overlay->pixels[2], pYuv + w * h, w * h / 4);
memcpy(overlay->pixels[1], pYuv + w * h + w * h / 4, w * h / 4);
rectSrc.w = w*zoom;
rectSrc.h = h*zoom;
rectSrc.x = rectSrc.y = 0;
}
else
{
int count=0,count1=0,count2=0;
int x=0,xU=0,xV=0;
int len=0,len1=0,len2=0;
char tempY[cutedW*cutedH];
char tempU[cutedW*cutedH/4];
char tempV[cutedW*cutedH/4];
x=w*offsetY+offsetX;
for(count;count
{
memcpy(tempY+len, pYuv+x,cutedW);
x+=w;
len+=cutedW;
}
xU=w/2*offsetY/2+offsetX/2;
for(count1;count1
{
memcpy(tempU+len1, pYuv+w*h+xU,cutedW/2);
xU+=w/2;
len1+=cutedW/2;
}
xV=w/2*offsetY/2+offsetX/2;
for(count2;count2
{
memcpy(tempV+len2, pYuv+w*h+w*h/4+xV,cutedW/2);
xV+=w/2;
len2+=cutedW/2;
}
memcpy(overlay->pixels[0], (const char *)tempY, cutedW * cutedH);
memcpy(overlay->pixels[2], (const char *)tempU, cutedW * cutedH/4);
memcpy(overlay->pixels[1], (const char *)tempV, cutedW * cutedH/4);
rectSrc.w = cutedW*zoom;
rectSrc.h = cutedH*zoom;
rectSrc.x = rectSrc.y = 0;
}
SDL_UnlockYUVOverlay(overlay);
SDL_UnlockSurface(screen);
SDL_DisplayYUVOverlay(overlay, &rectSrc);
return 0;
}
int init_SDL(int w, int h, char* pYuv, int swidth, int sheight, int zoom) {//初始化SDL 注意SDLScreen 如果创建后再更改会各种出问题,
//我建议直接创建手机或虚拟机屏幕大小,后面改变overlay就可以了
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
fprintf(stderr, "can not initialize SDL:%s\n", SDL_GetError());
LOGI("can not initialize SDL");
exit(1);
}
atexit(SDL_Quit);
screen = SDL_SetVideoMode(swidth, sheight, 0, 0); //创建屏幕
LOGI("2!\n");
LOGI("screen creat success");
if (screen == NULL ) {
LOGI("create surface error!\n");
exit(1);
}
overlay = SDL_CreateYUVOverlay(w, h, SDL_YV12_OVERLAY, screen);
LOGI("overlay creat success");
if (overlay == NULL ) {
fprintf(stderr, "create overlay error!\n");
exit(1);
}
return 0;
}
int change_Overlay(int newWidth, int newHeight) {
if (overlay) {
SDL_FreeYUVOverlay(overlay);
}
overlay = SDL_CreateYUVOverlay(newWidth, newHeight, SDL_YV12_OVERLAY, screen);
return 0;
}
int release_SDL() {
if (overlay) {
SDL_FreeYUVOverlay(overlay);
}
if (screen) {
SDL_FreeSurface(screen);
}
LOGI("RELEASE SUCCESS");
return 2;
}
5.在int main()函数中,读取sdcard中的yuv测试序列,传入相关的宽高,如果需要切割部分图片,可以传入offetX、Y cutedX、Y。
6.修改android-project/jni/src中的Android.mk文件,将yoursoruce.c 替换为自己写的C文件名即可。
7. 命令行进入工程根目录,ndk-build 成功后会生成两个库 libSDL.so和libMain.so,如第二次编译不成功先把根目录下的obj文件删了试试
注:移植后,曾想将SDL库和main库分开编译,这样便于移植和管理。但是,由于main库编译的时候需要SDL库中的内容,没有找到在Android.mk文件中,直接指向动态库的方法,所以放弃了,有高人懂的,可以告诉我不胜感激。

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)