Android本地视频播放器开发--视频解码

来源:互联网 发布:微商城模板源码 编辑:程序博客网 时间:2024/04/30 02:28

http://blog.csdn.net/jwzhangjie/article/details/9111547

Android本地视频播放器开发--视频解码       

        分类:            android多媒体开发视频播放器制作SDL946人阅读评论(2)收藏举报
android视频播放器开发

在上一章Android本地视频播放器开发--SDL编译编译中编译出sdl的支持库,当时我们使用的2.0,但是有些api被更改了,所以在以下的使用者中我们使用SDL1.3的库,这个库我会传上源码以及编译出的库,接下来这张我们使用ffmpeg解码视频文件中的视频帧同时使用SDL去显示。

1、Decodec_Video.c 这是我视频解码的文件,其中内容如下:

[cpp] view plaincopyprint?
  1. #include <stdio.h> 
  2. #include <android/log.h> 
  3.  
  4. #ifdef __MINGW32__ 
  5. #undef main /* Prevents SDL from overriding main() */ 
  6. #endif 
  7.  
  8. #include "../SDL/include/SDL.h" 
  9. #include "../SDL/include/SDL_thread.h" 
  10.  
  11. #include "VideoPlayerDecode.h" 
  12. #include "../ffmpeg/libavutil/avutil.h" 
  13. #include "../ffmpeg/libavcodec/avcodec.h" 
  14. #include "../ffmpeg/libavformat/avformat.h" 
  15. #include "../ffmpeg/libswscale/swscale.h" 
  16.  
  17. AVFormatContext *pFormatCtx; 
  18. int             i, videoStream; 
  19. AVCodecContext  *pCodecCtx; 
  20. AVCodec         *pCodec; 
  21. AVFrame         *pFrame; 
  22. AVPacket        packet; 
  23. int             frameFinished; 
  24. float           aspect_ratio; 
  25.  
  26. staticstruct SwsContext *img_convert_ctx; 
  27. SDL_Surface     *screen; 
  28. SDL_Overlay *bmp; 
  29. SDL_Rect        rect; 
  30. SDL_Event       event; 
  31.  
  32.  
  33. JNIEXPORT jint JNICALL Java_com_zhangjie_graduation_videopalyer_jni_VideoPlayerDecode_VideoPlayer 
  34. (JNIEnv *env, jclass clz, jstring fileName) 
  35.     constchar* local_title = (*env)->GetStringUTFChars(env, fileName, NULL); 
  36.     av_register_all();//注册所有支持的文件格式以及编解码器 
  37.     if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) { 
  38.         fprintf(stderr, "Could not initialize SDL - %s\n", SDL_GetError()); 
  39.         exit(1); 
  40.     } 
  41.     if(avformat_open_input(&pFormatCtx, local_title, NULL, NULL) != 0) 
  42.                 return -1; 
  43.     if(avformat_find_stream_info(pFormatCtx, NULL) < 0) 
  44.                 return -1; 
  45.     av_dump_format(pFormatCtx, -1, local_title, 0); 
  46.     videoStream=-1; 
  47.     for(i=0; i<pFormatCtx->nb_streams; i++) 
  48.         if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) { 
  49.             videoStream=i; 
  50.             break
  51.         } 
  52.     if(videoStream==-1) 
  53.         return -1;// Didn't find a video stream 
  54.     // Get a pointer to the codec context for the video stream 
  55.     pCodecCtx=pFormatCtx->streams[videoStream]->codec; 
  56.  
  57.     // Find the decoder for the video stream 
  58.     pCodec=avcodec_find_decoder(pCodecCtx->codec_id); 
  59.     if(pCodec==NULL) { 
  60.         fprintf(stderr, "Unsupported codec!\n"); 
  61.         return -1;// Codec not found 
  62.     } 
  63.     if(avcodec_open2(pCodecCtx, pCodec, NULL) < 0)return -1; 
  64.     pFrame = avcodec_alloc_frame(); 
  65.     if(pFrame == NULL)return -1; 
  66.     // Make a screen to put our video 
  67. #ifndef __DARWIN__ 
  68.     screen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 0, 0); 
  69. #else 
  70.     screen = SDL_SetVideoMode(pCodecCtx->width, pCodecCtx->height, 24, 0); 
  71. #endif 
  72.     if(!screen) { 
  73.         fprintf(stderr, "SDL: could not set video mode - exiting\n"); 
  74.         exit(1); 
  75.     } 
  76.     // Allocate a place to put our YUV image on that screen 
  77.     bmp = SDL_CreateYUVOverlay(pCodecCtx->width, 
  78.             pCodecCtx->height, 
  79.             SDL_YV12_OVERLAY, 
  80.             screen); 
  81.     img_convert_ctx = sws_getContext(pCodecCtx->width,   
  82.                           pCodecCtx->height, pCodecCtx->pix_fmt,   
  83.                           pCodecCtx->width, pCodecCtx->height,   
  84.                           PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);   
  85.  
  86.     // Read frames and save first five frames to disk 
  87.     i=0; 
  88.     while(av_read_frame(pFormatCtx, &packet)>=0) { 
  89.         // Is this a packet from the video stream? 
  90.         if(packet.stream_index==videoStream) { 
  91.             avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet); 
  92.             // Did we get a video frame? 
  93.             if(frameFinished) { 
  94.                 SDL_LockYUVOverlay(bmp); 
  95.                  
  96.                 AVPicture *pict; 
  97.                 pict->data[0] = bmp->pixels[0]; 
  98.                 pict->data[1] = bmp->pixels[2]; 
  99.                 pict->data[2] = bmp->pixels[1]; 
  100.  
  101.                 pict->linesize[0] = bmp->pitches[0]; 
  102.                 pict->linesize[1] = bmp->pitches[2]; 
  103.                 pict->linesize[2] = bmp->pitches[1]; 
  104.                  
  105. sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pict->data, pict->linesize); 
  106.                 SDL_UnlockYUVOverlay(bmp); 
  107.  
  108.                 rect.x = 0; 
  109.                 rect.y = 0; 
  110.                 rect.w = pCodecCtx->width; 
  111.                 rect.h = pCodecCtx->height; 
  112.                 SDL_DisplayYUVOverlay(bmp, &rect); 
  113.  
  114.             } 
  115.         } 
  116.         // Free the packet that was allocated by av_read_frame 
  117.         av_free_packet(&packet); 
  118.         SDL_PollEvent(&event); 
  119.         switch(event.type) { 
  120.             case SDL_QUIT: 
  121.                 SDL_Quit(); 
  122.                 exit(0); 
  123.                 break
  124.             default
  125.                 break
  126.         } 
  127.  
  128.     } 
  129.     // Free the YUV frame 
  130.     av_free(pFrame); 
  131.  
  132.     // Close the codec 
  133.     avcodec_close(pCodecCtx); 
  134.  
  135.     // Close the video file 
  136.     av_close_input_file(pFormatCtx); 

2、编译结果如下:

[cpp] view plaincopyprint?
  1. root@zhangjie:/Graduation/jni# ndk-build 
  2. Install        : libSDL.so => libs/armeabi/libSDL.so 
  3. Install        : libffmpeg-neon.so => libs/armeabi/libffmpeg-neon.so 
  4. Compile arm    : ffmpeg-test-neon <= Decodec_Video.c 
  5. /Graduation/jni/jniffmpeg/Decodec_Video.c: In function 'Java_com_zhangjie_graduation_videopalyer_jni_VideoPlayerDecode_VideoPlayer'
  6. /Graduation/jni/jniffmpeg/Decodec_Video.c:106:1: warning: passing argument 2 of'sws_scale' from incompatible pointer type [enabled bydefault
  7. /Graduation/jni/jniffmpeg/../ffmpeg/libswscale/swscale.h:237:5: note: expected'uint8_t const * const*' but argument is of type'uint8_t **' 
  8. /Graduation/jni/jniffmpeg/Decodec_Video.c:137:2: warning: 'av_close_input_file' is deprecated (declared at /Graduation/jni/jniffmpeg/../ffmpeg/libavformat/avformat.h:1533) [-Wdeprecated-declarations] 
  9. SharedLibrary  : libffmpeg-test-neon.so 
  10. Install        : libffmpeg-test-neon.so => libs/armeabi/libffmpeg-test-neon.so 
3、SDL1.3源码

http://download.csdn.net/detail/jwzhangjie/5596453

4、之前在Android本地视频播放器开发--NDK编译FFmpeg中没有添加swscale功能,所以需要重新编译ffmpeg,其脚本如下:

[plain] view plaincopyprint?
  1. NDK=/opt/android-ndk-r8d 
  2. PLATFORM=$NDK/platforms/android-8/arch-arm/ 
  3. PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86 
  4. LOCAL_ARM_NEON=true 
  5. CPU=armv7-a 
  6. OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=neon -marm -mcpu=cortex-a8" 
  7. PREFIX=./android/$CPU 
  8. ./configure --target-os=linux \ 
  9.     --prefix=$PREFIX \ 
  10.     --enable-cross-compile \ 
  11.     --arch=arm \ 
  12.     --enable-nonfree \ 
  13.     --enable-asm \ 
  14.     --cpu=cortex-a8 \ 
  15.     --enable-neon \ 
  16.     --cc=$PREBUILT/bin/arm-linux-androideabi-gcc \ 
  17.     --cross-prefix=$PREBUILT/bin/arm-linux-androideabi- \ 
  18.     --nm=$PREBUILT/bin/arm-linux-androideabi-nm \ 
  19.     --sysroot=$PLATFORM \ 
  20.     --extra-cflags=" -O3 -fpic -DANDROID -DHAVE_SYS_UIO_H=1 $OPTIMIZE_CFLAGS " \ 
  21.     --disable-shared \ 
  22.     --enable-static \ 
  23.     --extra-ldflags="-Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib  -nostdlib -lc -lm -ldl -llog" \ 
  24.     --disable-ffmpeg \ 
  25.     --disable-ffplay \ 
  26.     --disable-ffprobe \ 
  27.     --disable-ffserver \ 
  28.     --disable-encoders \ 
  29.     --enable-avformat \ 
  30.     --disable-optimizations \ 
  31.     --disable-doc \ 
  32.     --enable-pthreads \ 
  33.     --disable-yasm \ 
  34.     --enable-zlib \ 
  35.     --enable-pic \ 
  36.     --enable-small 
  37.  
  38. #make clean 
  39. make  -j4 install 
  40.  
  41. $PREBUILT/bin/arm-linux-androideabi-ar d libavcodec/libavcodec.a inverse.o 
  42.  
  43. $PREBUILT/bin/arm-linux-androideabi-ld -rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib  -soname libffmpeg-neon.so -shared -nostdlib  -z noexecstack -Bsymbolic --whole-archive --no-undefined -o $PREFIX/libffmpeg-neon.so libavcodec/libavcodec.a libavformat/libavformat.a libavutil/libavutil.a  libavfilter/libavfilter.a libswresample/libswresample.a libswscale/libswscale.a libavdevice/libavdevice.a -lc -lm -lz -ldl -llog  --warn-once  --dynamic-linker=/system/bin/linker $PREBUILT/lib/gcc/arm-linux-androideabi/4.4.3/libgcc.a 

 

原创粉丝点击