In the previous chapter, Android Local Video Player Development-SDL compilation was used to compile the SDL support library. At that time, we used 2.0, but some apis were changed, therefore, we use the sdl1.3 library among the following users. I will upload the source code and the compiled library to this library, next, we use FFMPEG to decode the video frames in the video file and Use SDL to display them at the same time.
1. decodec_video.c: This is the video decoding file. The content is as follows:
# Include <stdio. h> # include <Android/log. h> # ifdef _ mingw32 __# UNDEF main/* prevents SDL from overriding main () */# endif # include ".. /SDL/include/SDL. H "# include ".. /SDL/include/sdl_thread.h "# include" videoplayerdecode. H "# include ".. /FFMPEG/libavutil/avutil. H "# include ".. /FFMPEG/libavcodec/avcodec. H "# include ".. /FFMPEG/libavformat/avformat. H "# include ".. /FFMPEG/libswscale/swscale. H "avformatcontext * pf Ormatctx; int I, videostream; avcodeccontext * pcodecctx; avcodec * pcodec; avframe * pframe; avpacket packet; int framefinished; float metadata; static struct swscontext * img_convert_ctx; sdl_surface * Screen; sdl_overlay * BMP; sdl_rect rect; sdl_event event; jniexport jint jnicall encode (jnienv * ENV, jclass clz, jstring filename) {const char * Local_title = (* env)-> getstringutfchars (ENV, filename, null); av_register_all (); // register all supported file formats and CODEC if (sdl_init (sdl_init_video | sdl_init_audio | sdl_init_timer) {fprintf (stderr, "cocould not initialize SDL-% s \ n ", sdl_geterror (); exit (1);} If (avformat_open_input (& pformatctx, local_title, null, null )! = 0) Return-1; if (avformat_find_stream_info (pformatctx, null) <0) Return-1; av_dump_format (pformatctx,-1, local_title, 0); videostream =-1; for (I = 0; I <pformatctx-> nb_streams; I ++) if (pformatctx-> streams [I]-> codec-> codec_type = avmedia_type_video) {videostream = I; break;} If (videostream =-1) Return-1; // didn't find a video stream // get a pointer to the codec context for the video streampcodecctx = pformatc TX-> streams [videostream]-> codec; // find the decoder for the video streampcodec = avcodec_find_decoder (pcodecctx-> codec_id); If (pcodec = NULL) {fprintf (stderr, "unsupported codec! \ N "); Return-1; // codec not found} If (avcodec_open2 (pcodecctx, pcodec, null) <0) Return-1; pframe = avcodec_alloc_frame (); if (pframe = NULL) Return-1; // make a screen to put our video # ifndef _ Darwin _ screen = sdl_setvideomode (pcodecctx-> width, pcodecctx-> height, 0, 0); # elsescreen = sdl_setvideomode (pcodecctx-> width, pcodecctx-> height, 24, 0); # endifif (! Screen) {fprintf (stderr, "SDL: cocould not set video mode-exiting \ n"); exit (1 );} // allocate a place to put our YUV image on that screenbmp = sdl_createyuvoverlay (pcodecctx-> width, pcodecctx-> height, height, screen); img_convert_ctx = sws_getcontext (pcodecctx-> width, pcodecctx-> height, pcodecctx-> pix_fmt, pcodecctx-> width, pcodecctx-> height, pix_fmt_rgb24, sws_bicubic, null, null); // re Ad frames and save first five frames to diski = 0; while (av_read_frame (pformatctx, & Packet)> = 0) {// is this a packet from the video stream? If (packet. stream_index = videostream) {avcodec_decode_video2 (pcodecctx, pframe, & framefinished, & Packet); // did we get a video frame? If (framefinished) {sdl_lockyuvoverlay (BMP); avpicture * PICT; PICT-> data [0] = BMP-> pixels [0]; PICT-> data [1] = BMP-> pixels [2]; PICT-> data [2] = BMP-> pixels [1]; PICT-> linesize [0] = BMP-> pitches [0]; PICT-> linesize [1] = BMP-> pitches [2]; PICT-> linesize [2] = BMP-> pitches [1]; sws_scale (img_convert_ctx, pframe-> data, pframe-> linesize, 0, pcodecctx-> height, PICT-> data, PICT-> linesize); sdl_unlockyuvoverlay (BMP); rect. X = 0; rect. y = 0; rect. W = pcodecctx-> width; rect. H = pcodecctx-> height; sdl_displayyuvoverlay (BMP, & rect) ;}// free the packet that was allocated by av_read_frameav_free_packet (& Packet); sdl_pollevent (& event ); switch (event. type) {Case sdl_quit: sdl_quit (); exit (0); break; default: Break ;}// free the YUV frameav_free (pframe ); // close the codecavcodec_close (pcodecctx); // close the video fileav_close_input_file (pformatctx );}
2. The compilation result is as follows:
root@zhangjie:/Graduation/jni# ndk-buildInstall : libSDL.so => libs/armeabi/libSDL.soInstall : libffmpeg-neon.so => libs/armeabi/libffmpeg-neon.soCompile arm : ffmpeg-test-neon <= Decodec_Video.c/Graduation/jni/jniffmpeg/Decodec_Video.c: In function 'Java_com_zhangjie_graduation_videopalyer_jni_VideoPlayerDecode_VideoPlayer':/Graduation/jni/jniffmpeg/Decodec_Video.c:106:1: warning: passing argument 2 of 'sws_scale' from incompatible pointer type [enabled by default]/Graduation/jni/jniffmpeg/../ffmpeg/libswscale/swscale.h:237:5: note: expected 'uint8_t const * const*' but argument is of type 'uint8_t **'/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]SharedLibrary : libffmpeg-test-neon.soInstall : libffmpeg-test-neon.so => libs/armeabi/libffmpeg-test-neon.so
3. sdl1.3 source code
Http://download.csdn.net/detail/jwzhangjie/5596453
4. I used to develop a local Android video player-ndk compiling FFMPEG without adding the swscale function. So I need to re-compile FFMPEG. The script is as follows:
NDK=/opt/android-ndk-r8dPLATFORM=$NDK/platforms/android-8/arch-arm/PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86LOCAL_ARM_NEON=trueCPU=armv7-aOPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=neon -marm -mcpu=cortex-a8"PREFIX=./android/$CPU./configure --target-os=linux \ --prefix=$PREFIX \ --enable-cross-compile \ --arch=arm \ --enable-nonfree \ --enable-asm \ --cpu=cortex-a8 \ --enable-neon \ --cc=$PREBUILT/bin/arm-linux-androideabi-gcc \ --cross-prefix=$PREBUILT/bin/arm-linux-androideabi- \ --nm=$PREBUILT/bin/arm-linux-androideabi-nm \ --sysroot=$PLATFORM \ --extra-cflags=" -O3 -fpic -DANDROID -DHAVE_SYS_UIO_H=1 $OPTIMIZE_CFLAGS " \ --disable-shared \ --enable-static \ --extra-ldflags="-Wl,-rpath-link=$PLATFORM/usr/lib -L$PLATFORM/usr/lib -nostdlib -lc -lm -ldl -llog" \ --disable-ffmpeg \ --disable-ffplay \ --disable-ffprobe \ --disable-ffserver \ --disable-encoders \ --enable-avformat \ --disable-optimizations \ --disable-doc \ --enable-pthreads \ --disable-yasm \ --enable-zlib \ --enable-pic \ --enable-small#make cleanmake -j4 install$PREBUILT/bin/arm-linux-androideabi-ar d libavcodec/libavcodec.a inverse.o$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