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

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

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

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

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

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

2、编译结果如下:

[cpp] view plain copy print ?
  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 by default]
  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 plain copy print ?
  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. #make clean
  38. make -j4 install
  39. $PREBUILT/bin/arm-linux-androideabi-ar d libavcodec/libavcodec.a inverse.o
  40. $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

更多相关文章

  1. 使用Android(安卓)Studio与ArcGIS Android(安卓)SDK的开发环境部
  2. Android(安卓)app项目和开发总结
  3. Android探索与黑科技
  4. Android(安卓)开发指南文档的部分中文翻译
  5. android studio 编译的时候出现的错误和解决方法
  6. Android应用程序开发入门
  7. Android(安卓)图书总汇
  8. android studio编译android M时无法使用org.apache.http.**的解
  9. Android程序开发中关于设置全屏无效问题

随机推荐

  1. mysql参数优化辅助工具之tuning-primer.s
  2. sql 存储过程参数为空则不作为条件
  3. Python3.6实现scrapy框架爬取数据并将数
  4. >的EF6 SQL生成。
  5. Sql经纬度计算与C#经纬度计算
  6. SQL%NOTFOUND在实际中非常有用
  7. 使用desc后的sql server反向顺序
  8. 我想在每次更新或在SQL Server中插入行时
  9. PostgreSQL无法加载库未知错误14001
  10. mysql winx64安装配置方法