Creating A Hardware Decoder Integrating FFmpeg With MediaCodec
Creating A Hardware Decoder Integrating FFmpeg With MediaCodec
Background
Google created MediaPlayer as a simpler way to control audio and video playback. However,
MediaPlayer is limited in that it offers only three media formats: mp4, 3gpp, and mkv
(beginning with Android 4.0). However, most online video ISVs use other video formats like
FLV, etc. To play unsupported formats and be compatible with the greatest number of
Android devices in the market, online video developers have adopted FFmpeg as their
software decoder of choice. Alternatively, some developers integrate OpenMAX* (a wellknown standard in the media industry) to access Androids low-level hardware decoder for
Android 2.3 devices, a codec to enable Android 4.0 devices, and MediaCodec to enable
Android 4.1+ devices. They had to buy most of the popular Android devices in the market for
testing. Even then, they still had some compatibility problems, so they had to adopt FFmpeg
for backup.
One solution is to integrate FFmpeg with MediaCodec, which will support all the different
kinds of video formats and create a hardware decoder for Intel Atom-based Android
platforms.
The solution is shown in the following diagram:
In this solution, FFmpeg unpacks the video container as separate raw video data and audio
data in a native layer. Then, the raw video data is transferred into MediaCodecs APIs in the
Java layer for hardware decoder. The audio data is decoded by FFmpeg directly, which does
not cost much CPU workload. Finally, FFmpeg syncs the audio and video by time stamp.
This solution supports some other popular video formats that arent supported by
MediaPlayer, and online video ISVs are finding it helpful.
tar
xvf
ffmpeg-2.2.4.tar.bz2
4. Copy the following configuration file to ~/ffmpeg-2.2.4 and add the "run" permissions:
wangsy@ubuntu:~/Desktop$
cp
config_build_x86.sh
a+x
~/ffmpeg-2.2.4
~/ffmpeg-
5. Run the configuration script and build using the make and make install commands:
wangsy@ubuntu:~/Desktop/ffmpeg-2.2.4$
make
wangsy@ubuntu:~/Desktop/ffmpeg-2.2.4$
make install
Demo code: Accessing the MediaCodec class from the native layer:
struct classname
{
const char *name;
int offset;
};
static const struct classname classes[] = {
{ "android/media/MediaCodecList", OFF(media_codec_list_class) },
{ "android/media/MediaCodec", OFF(media_codec_class) },
{ "android/media/MediaFormat", OFF(media_format_class) },
{ "android/media/MediaFormat", OFF(media_format_class) },
{ "android/media/MediaCodec$BufferInfo", OFF(buffer_info_class) },
{ "java/nio/ByteBuffer", OFF(byte_buffer_class) },
{ NULL, 0 },
};
JNIEnv* env = NULL;
ATTACH_THREAD;
if ((*env)->ExceptionOccurred(env)) {
msg_Warn(p_dec, "Unable to find class %s",
classes[i].name);
(*env)->ExceptionClear(env);
goto error;
}
}
Demo code: Accessing the MediaCodec functions from the native layer:
struct member
{
const char *name;
const char *sig;
const char *class;
int offset;
int type;
};
static const struct member members[] = {
{ "toString", "()Ljava/lang/String;", "java/lang/Object",
OFF(tostring), METHOD },
{ "createByCodecName",
"(Ljava/lang/String;)Landroid/media/MediaCodec;",
"android/media/MediaCodec", OFF(create_by_codec_name), STATIC_METHOD },
{ "configure",
"(Landroid/media/MediaFormat;Landroid/view/Surface;Landroid/media/Media
Crypto;I)V", "android/media/MediaCodec", OFF(configure), METHOD },
{ "start", "()V", "android/media/MediaCodec", OFF(start), METHOD },
{ "createVideoFormat",
"(Ljava/lang/String;II)Landroid/media/MediaFormat;",
"android/media/MediaFormat", OFF(create_video_format), STATIC_METHOD },
{ "setInteger", "(Ljava/lang/String;I)V",
"android/media/MediaFormat", OFF(set_integer), METHOD },
{ "getInteger", "(Ljava/lang/String;)I",
"android/media/MediaFormat", OFF(get_integer), METHOD },
{ "setByteBuffer", "(Ljava/lang/String;Ljava/nio/ByteBuffer;)V",
"android/media/MediaFormat", OFF(set_bytebuffer), METHOD },
{ "allocateDirect", "(I)Ljava/nio/ByteBuffer;",
"java/nio/ByteBuffer", OFF(allocate_direct), STATIC_METHOD },
{ "limit", "(I)Ljava/nio/Buffer;", "java/nio/ByteBuffer",
OFF(limit), METHOD },
if ((*env)->ExceptionOccurred(env)) {
msg_Warn(p_dec, "Unable to find class %s",
members[i].class);
(*env)->ExceptionClear(env);
goto error;
}
Using the method above, developers can parse the MediaCodec class and functions from
native layer. For more information on how to use them, go to
http://developer.android.com/reference/android/media/MediaCodec.html.
Summary
The Intel optimization method was developed to help developers integrate FFmpeg with
MediaCodec to support many different types of video formats and create a hardware decoder
for Intel Atom-based Android platforms.
Related Articles
High Quality Video Compression: Integrating an H.265/HEVC Solution for Intel Atom-Based
Android* Platforms: https://software.intel.com/en-us/android/articles/high-quality-videocompression-integrating-an-h265hevc-solution-for-intel-atom-based-android-platforms
Android* Hardware CodecMediaCodec: https://software.intel.com/enus/android/articles/android-hardware-codec-mediacodec
References
[1]
FFmpeg: http://www.ffmpeg.org/index.html
[2]
[3]
[4]
us/articles/performance-tools-for-software-developers-intel-compiler-options-for-sse-generationand-processor-specific-optimizations.
Notices
INFORMATION IN THIS DOCUMENT IS PROVIDED IN CONNECTION WITH INTEL PRODUCTS. NO LICENSE,
EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, TO ANY INTELLECTUAL PROPERTY RIGHTS IS GRANTED BY
THIS DOCUMENT. EXCEPT AS PROVIDED IN INTEL'S TERMS AND CONDITIONS OF SALE FOR SUCH PRODUCTS,
INTEL ASSUMES NO LIABILITY WHATSOEVER AND INTEL DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY,
RELATING TO SALE AND/OR USE OF INTEL PRODUCTS INCLUDING LIABILITY OR WARRANTIES RELATING TO
FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR INFRINGEMENT OF ANY PATENT, COPYRIGHT OR
OTHER INTELLECTUAL PROPERTY RIGHT.
UNLESS OTHERWISE AGREED IN WRITING BY INTEL, THE INTEL PRODUCTS ARE NOT DESIGNED NOR INTENDED
FOR ANY APPLICATION IN WHICH THE FAILURE OF THE INTEL PRODUCT COULD CREATE A SITUATION WHERE
PERSONAL INJURY OR DEATH MAY OCCUR.
Intel may make changes to specifications and product descriptions at any time, without notice. Designers must not
rely on the absence or characteristics of any features or instructions marked "reserved" or "undefined." Intel
reserves these for future definition and shall have no responsibility whatsoever for conflicts or incompatibilities
arising from future changes to them. The information here is subject to change without notice. Do not finalize a
design with this information.
The products described in this document may contain design defects or errors known as errata which may cause
the product to deviate from published specifications. Current characterized errata are available on request.
Contact your local Intel sales office or your distributor to obtain the latest specifications and before placing your
product order.
Copies of documents which have an order number and are referenced in this document or other Intel literature
may be obtained by calling 1-800-548-4725 or going to http://www.intel.com/design/literature.htm
Any software source code reprinted in this document is furnished under a software license and may only be used or
copied in accordance with the terms of that license.
Intel, the Intel logo, and Atom are trademarks of Intel Corporation in the U.S. and/or other countries.
Copyright 2014 Intel Corporation. All rights reserved.
*Other names and brands may be claimed as the property of others.