Wednesday, December 8, 2010

learning opencore through unit testing

Android 2.3 gingerbread was officially released. A big improvement is this version is in media framework, as stated in platform highlights:

Media Framework

  • New media framework fully replaces OpenCore, maintaining all previous codec/container support for encoding and decoding.
  • Integrated support for the VP8 open video compression format and the WebM open container format
  • Adds AAC encoding and AMR wideband encoding

I'm not able to find out what is the replacement for opencore yet. But before opencore is obsoleted, I still would like to share my way of learning opencore. This might be helpful for those who still have to work on legacy android platforms.

Opencore is a complicated multimedia framework. An effective way I thought a bit easier to learn it is looking at its unit testing code and debugging unit testing application. The advantages include:
  1. The code can be compiled as x86 executable, so we can run it on our pc directly, rather than on a android device or emulator.
  2. The application can be debugged with gdb 
  3. Unit tests demonstrate the simplest usage of opencore. It's particularly useful for a fresh learner to get started.
  4. Test cases each have its own concentration, and is easier to follow.
So, if we use unit testing code as a means of learning opencore, instead of trying to understand the full-featured mediaserver, things will be much easier. We can find out the simplest way to initialize opencore and play a file. For any specific requirement we need to implement, we can always find a corresponding test case in the unit test guide and refer to its source code.

How to debug opencore with gdb
Before we use gdb to debug unit testing application, we need to be aware of a helpful gdb feature: show real type of a object though pointer.
In opencore framework, it always manipulate a concrete object through an interface or base pointer. So, during debugging, we often get lost about what the actual type of the object being pointed to by the pointer is. Gdb can print the real type of object if the pointer points to it has virtual table. This feature can be turned on with "set print object" command. 
For example, if we break at the line returns a pointer in PVPlayerNodeRegistry::CreateNode function, we issue "p nodeInterface" command without print object turning on, we see:
$1 = (class PVMFNodeInterface *) 0x83c65c0
The type of the pinter is shown as PVMFNodeInterface, which isn't very informative because is the base type. If we trun print object on and run the command again, we see:
$2 = (PVMFMP4FFParserNode *) 0x83c65c0
The real type of the object is clearly printed. Very useful feature for debugging complex frameworks.
We can follow below steps to compile and debug unit testing application:
  1. Compile the app by following instructions in quick_start.txt
  2. cd to {open_core_root}/build_config/opencore_dynamic/build/pe_test. We need to start debugging here, otherwise the application may fail to find necessary libraries and media files.
  3. export LD_LIBRARY_PATH=../installed_lib/linux
  4. gdb ../bin/linux/pvplayer_engine_test
  5. set desired breakpoints
  6. run -source test.mp4 -test 1 1. The source and test case number argument can be changed accordingly.


nevil said...

StageFright is the replacement of OpenCore

rxwen said...

Thanks for the information.
I also suspect it's the replacement when I noticed it in 2.2.

rxwen said...

Exactly, I've confirmed through the source code that StageFright replaces OpenCore.