The simplest mobile-based ffmpeg example: Android Video Decoder

Source: Internet
Author: User
<span id="Label3"></p>This document records a video decoder based on FFmpeg on an android platform. The source code for the video decoder C language comes from the simplest ffmpeg+sdl-based video player. The related concepts are no longer duplicated.<br><br>The directory structure of the source code Project. The Java source code is in the SRC directory, and the C code is in the JNI directory.<br>The Java-side code for the Android program is located in src\com\leixiaohua1020\sffmpegandroiddecoder\mainactivity.java, as shown below.<br><pre name="code" class="java">/** * Simplest FFmpeg based video decoder-android * simplest FFmpeg android Decoder * * Lei hua Lei Xiaohua * [email protected] * Communication university/digital TV Technology * Communication University of china/digital TV technology * http://blog.csdn.net/leixiaohua1020 * * This program is the simplest FF based on the Android platform MPEG Video Decoder. It can decode the input video data into YUV pixel Data. * * This software are the simplest decoder based on FFmpeg in ANDROID. It can decode video stream * to Raw YUV Data. * */package Com.leixiaohua1020.sffmpegandroiddecoder;import Android.os.bundle;import Android.os.Environment;import Android.app.activity;import Android.text.editable;import Android.util.log;import Android.view.Menu;import Android.view.view;import Android.view.view.onclicklistener;import Android.widget.button;import Android.widget.edittext;import Android.widget.textview;public class Mainactivity extends Activity {@Override Protec Ted void OnCreate (Bundle Savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (r.layout.activity_main); Button Startbutton = (Button) This.findviewbyid (r.id.button_start), final EditText urledittext_input= (EditText) This.findviewbyid ( r.id.input_url); final EditText urledittext_output= (EditText) This.findviewbyid (r.id.output_url); Startbutton.setonclicklistener (new onclicklistener () {public void OnClick (View arg0) {String folderurl= Environment.getexternalstoragedirectory (). GetPath (); String urltext_input=urledittext_input.gettext (). toString (); String inputurl=folderurl+ "/" +urltext_input; String urltext_output=urledittext_output.gettext (). toString (); String outputurl=folderurl+ "/" +urltext_output; LOG.I ("inputurl", inputurl); LOG.I ("outputurl", outputurl); Decode (inputurl,outputurl); }}); } @Override public boolean oncreateoptionsmenu (menu Menu) {//inflate The menu, this adds items to the Actio n Bar if it is Present. Getmenuinflater (). Inflate (r.menu.main, menu); Return true; }//jni Public native int decoDe (string inputurl, string outputurl); Static{system.loadlibrary ("avutil-54"); System.loadlibrary ("swresample-1"); System.loadlibrary ("avcodec-56"); System.loadlibrary ("avformat-56"); System.loadlibrary ("swscale-3"); System.loadlibrary ("postproc-53"); System.loadlibrary ("avfilter-5"); System.loadlibrary ("avdevice-56"); System.loadlibrary ("sffdecoder"); }}</pre><br>The C-language side source code is located in jni/simplest_ffmpeg_decoder.c, as shown below.<br><pre name="code" class="cpp">/** * Simplest FFmpeg based video decoder-android * simplest FFmpeg android Decoder * * Lei hua Lei Xiaohua * [email protected] * Communication university/digital TV Technology * Communication University of china/digital TV technology * http://blog.csdn.net/leixiaohua1020 * * This program is the simplest under the Android platform based on FFMP Eg's Video Decoder. It can decode the input video data into YUV pixel Data. * * This software are the simplest decoder based on FFmpeg in ANDROID. It can decode video stream * to Raw YUV Data. * */#include <stdio.h> #include <time.h> #include "libavcodec/avcodec.h" #include "libavformat/avformat.h" #include "libswscale/swscale.h" #include "libavutil/log.h" #ifdef android#include <jni.h> #include <android/ log.h> #define LOGE (format, ...) __android_log_print (android_log_error, "(>_<)", format, # #__VA_ARGS__) #define Logi (format, ...) __android_log_print (android_log_info, "(=_=)", format, # #__VA_ARGS__) #else # define LOGE (format, ...) printf ("(>_<)" format "\ n", # #__VA_ARGS__) #define Logi (format, ...) printf ("(^_^)" format "\ n", # #__VA_ARGS__) #endif//output FFmPeg ' s av_log () void custom_log (void *ptr, int level, const char* fmt, va_list vl) {FILE *fp=fopen ("/storage/emulated/0/av_l Og.txt "," A + "), if (fp) {vfprintf (fp,fmt,vl); fflush (fp); fclose (fp);}} Jniexport jint jnicall java_com_leixiaohua1020_sffmpegandroiddecoder_mainactivity_decode (JNIEnv *env, jobject obj, Jstring input_jstr, jstring output_jstr) {avformatcontext*pformatctx;inti, videoindex; avcodeccontext*pcodecctx; avcodec*pcodec; avframe*pframe,*pframeyuv;uint8_t *out_buffer; Avpacket *packet;int y_size;int ret, got_picture;struct swscontext *img_convert_ctx; FILE *fp_yuv;int frame_cnt;clock_t time_start, time_finish;double time_duration = 0.0;char Input_str[500]={0};char Output_str[500]={0};char info[1000]={0};sprintf (input_str, "%s", (*env)->getstringutfchars (env,input_jstr, NULL ); sprintf (output_str, "%s", (*env)->getstringutfchars (env,output_jstr, NULL));//ffmpeg av_log () callback Av_log_ Set_callback (custom_log); av_register_all (); avformat_network_init ();p formatctx = Avformat_alloc_contExt (); If (avformat_open_input (&pformatctx,input_str,null,null)!=0) {LOGE ("couldn ' t open input stream.\n"); return-1;} If (avformat_find_stream_info (pformatctx,null) <0) {LOGE ("couldn ' t find stream information.\n"); return-1;} Videoindex=-1;for (i=0; i<pformatctx->nb_streams; I++) if (pformatctx->streams[i]->codec->codec_type ==avmedia_type_video) {videoindex=i;break;} If (videoindex==-1) {LOGE ("couldn ' t find a video stream.\n"); return-1;} Pcodecctx=pformatctx->streams[videoindex]->codec;pcodec=avcodec_find_decoder (pCodecCtx->codec_id); if ( Pcodec==null) {LOGE ("couldn ' t find codec.\n"); return-1;} If (avcodec_open2 (pcodecctx, pcodec,null) <0) {LOGE ("couldn ' t open codec.\n"); return-1;} Pframe=av_frame_alloc ();p frameyuv=av_frame_alloc (); out_buffer= (uint8_t *) av_malloc (avpicture_get_size (PIX_FMT_ yuv420p, pcodecctx->width, pcodecctx->height)); avpicture_fill ((avpicture *) pframeyuv, out_buffer, PIX_FMT_ yuv420p, pcodecctx->width, pcodecctx->height);p acket= (avpacket *) AV_malloc (sizeof (avpacket)); img_convert_ctx = sws_getcontext (pcodecctx->width, pcodecctx->height, pCodecCtx- >pix_fmt, pcodecctx->width, pcodecctx->height, pix_fmt_yuv420p, sws_bicubic, null, null, and null); sprintf (info, "[Input]%s\n", input_str); sprintf (info, "%s[output]%s\n", info,output_str); sprintf (info, "%s[format]%s\n", info, pformatctx->iformat->name); sprintf (info, "%s[codec]%s\n", info, pcodecctx->codec->name); sprintf (info, "%s[resolution]%dx%d\n", info, pcodecctx->width,pcodecctx->height); Fp_yuv=fopen (output_str, "wb+"); If (fp_yuv==null) {printf ("cannot open output file.\n"); return-1;} Frame_cnt=0;time_start = Clock (), while (av_read_frame (pformatctx, packet) >=0) {if (packet->stream_index== Videoindex) {ret = Avcodec_decode_video2 (pcodecctx, pframe, &got_picture, packet); if (ret < 0) {LOGE ("decode Error . \ n "); return-1;} If (got_picture) {sws_scale (img_convert_ctx, (const uint8_t* const*) pframe->data, Pframe->linesize, 0, pcodecctx->height, pframeyuv->data, pframeyuv->linesize); y_size=pcodecctx->width*pcodecctx- >height; Fwrite (pframeyuv->data[0],1,y_size,fp_yuv); Y fwrite (pframeyuv->data[1],1,y_size/4,fp_yuv); Ufwrite (pframeyuv->data[2],1,y_size/4,fp_yuv); V//output Infochar pictype_str[10]={0};switch (pframe->pict_type) {case av_picture_type_i:sprintf (pictype_str, "I"); break; Case av_picture_type_p:sprintf (pictype_str, "P"), break;case av_picture_type_b:sprintf (pictype_str, "B"); default:sprintf (pictype_str, "other"); Logi ("Frame Index:%5d. type:%s ", frame_cnt,pictype_str); frame_cnt++;}} Av_free_packet (packet);} Flush Decoder//fix:flush Frames remained in codecwhile (1) {ret = Avcodec_decode_video2 (pcodecctx, pframe, &got_pic ture, packet); If (ret < 0) break;if (!got_picture) break;sws_scale (img_convert_ctx, (const uint8_t* const*) pframe- >data, pframe->linesize, 0, pcodecctx->height, pframeyuv->data, pframeyuv->linesize); int Y_size=pcodecctx->width*pcodecctx->height; Fwrite (pframeyuv->data[0],1,y_size,fp_yuv); Y fwrite (pframeyuv->data[1],1,y_size/4,fp_yuv); Ufwrite (pframeyuv->data[2],1,y_size/4,fp_yuv); V//output Infochar pictype_str[10]={0};switch (pframe->pict_type) {case av_picture_type_i:sprintf (pictype_str, "I"); break; Case av_picture_type_p:sprintf (pictype_str, "P"), break;case av_picture_type_b:sprintf (pictype_str, "B"); default:sprintf (pictype_str, "other"); Logi ("Frame Index:%5d. type:%s ", frame_cnt,pictype_str); frame_cnt++;} Time_finish = Clock (); time_duration= (double) (time_finish-time_start); sprintf (info, "%s[time]%fms\n", info,time_duration); sprintf (info, "%s[count]%d\n", info,frame_cnt); Sws_freecontext (img_convert_ctx); Fclose (fp_yuv); av_frame_free (&pframeyuv); av_frame_free (&pframe); avcodec_close (pcodecctx); avformat_ Close_input (&pformatctx); return 0;}</pre><br>The Android.mk file is located in jni/android.mk, as shown below.<br><pre name="code" class="plain"># android.mk for ffmpeg## Lei Xiaohua Lei hua # [email protected]# http://blog.csdn.net/leixiaohua1020# local_path: = $ (c All My-dir) # FFmpeg Libraryinclude $ (clear_vars) local_module: = Avcodeclocal_src_files: = Libavcodec-56.soinclude $ ( Prebuilt_shared_library) include $ (clear_vars) local_module: = Avdevicelocal_src_files: = Libavdevice-56.soinclude $ ( Prebuilt_shared_library) include $ (clear_vars) local_module: = Avfilterlocal_src_files: = Libavfilter-5.soinclude $ ( Prebuilt_shared_library) include $ (clear_vars) local_module: = Avformatlocal_src_files: = Libavformat-56.soinclude $ ( Prebuilt_shared_library) include $ (clear_vars) local_module: = Avutillocal_src_files: = Libavutil-54.soinclude $ ( Prebuilt_shared_library) include $ (clear_vars) local_module: = Postproclocal_src_files: = Libpostproc-53.soinclude $ ( Prebuilt_shared_library) include $ (clear_vars) local_module: = Swresamplelocal_src_files: = Libswresample-1.soinclude $ (prebuilt_shared_library) include $ (clear_vars) local_module: = swscalelocal_sRc_files: = libswscale-3.soinclude $ (prebuilt_shared_library) # programinclude $ (clear_vars) LOCAL_MODULE: = Sffdecoderlocal_src_files: =simplest_ffmpeg_decoder.clocal_c_includes + = $ (local_path)/includeLOCAL_LDLIBS: =-llog -lzlocal_shared_libraries: = Avcodec avdevice avfilter avformat avutil postproc swresample swscaleinclude $ (BUILD_SHARED _library)</pre><br>The results of running the results app on your phone are as shown in.<br><br>The stand-alone "Start" button allows you to decode the video files stored in the Kagan directory into YUV files (which need to wait a while to complete the decoding). Note that the decoded YUV file size is huge and may consume a lot of memory card space.<br><br>Download<br><strong><strong>simplest ffmpeg Mobile<br><br>Project Home</strong></strong><br><p><p></p></p><p><p>Github:https://github.com/leixiaohua1020/simplest_ffmpeg_mobile</p></p><p><p>Open Source China: https://git.oschina.net/leixiaohua1020/simplest_ffmpeg_mobile</p></p><br><p><p>CSDN project: http://download.csdn.net/detail/leixiaohua1020/8924391</p></p><br>This solution contains various examples of using FFMPEG to process multimedia on the mobile side:<br> <blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"> <blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"> [Android] <br>Simplest_android_player: Android interface-based Video player <br>Simplest_ffmpeg_android_helloworld: ffmpeg-based HelloWorld program under Android platform <br>Simplest_ffmpeg_android_decoder: The simplest ffmpeg-based video decoder on the Android platform <br>Simplest_ffmpeg_android_decoder_onelib: The simplest ffmpeg-based video decoder on the Android Platform-library edition <br>Simplest_ffmpeg_android_streamer: The simplest ffmpeg-based push-to-flow device under the Android platform <br>Simplest_ffmpeg_android_transcoder: FFmpeg command-line tool ported under Android platform <br>Simplest_sdl_android_helloworld: the simplest program for porting SDL to the Android platform <br>[IOS] <br>Simplest_ios_player: Video player based on iOS interface <br>HelloWorld program based on FFmpeg under the Simplest_ffmpeg_ios_helloworld:ios platform <br>The simplest ffmpeg-based video decoder under the Simplest_ffmpeg_ios_decoder:ios platform <br>The simplest ffmpeg based on the Simplest_ffmpeg_ios_streamer:ios platform <br>FFMPEG.C command-line tool ported under Simplest_ffmpeg_ios_transcoder:ios Platform <br>Simplest_sdl_ios_helloworld: The simplest program to migrate SDL to the iOS platform </blockquote> </blockquote><br><br><br><br><br> <p style="font-size:12px;"><p style="font-size:12px;">Copyright Notice: This article for Bo Master original article, without Bo Master permission not Reproduced.</p></p> <p><p>The simplest mobile-based ffmpeg example: Android Video Decoder</p></p></span>

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.