Reference: http://blog.csdn.net/wstarx/archive/2008/12/17/3541458.aspx
Directory structure <br/> the opencore code is in the following directory: external/opencore /. This directory is the root directory of opencore, and contains the following sub-directories: <br/> * Android: an upper-layer library, it implements a player and author for Android based on the pvplayer and pvauthor sdks. <Br/> * baselibs: underlying library containing data structures and thread security <br/> * codecs_v2: This is a library with many contents and mainly includes the implementation of codec, and an openmax implementation <br/> * engines: including pvplayer and pvauthor engine implementation <br/> * extern_libs_v2: contains the openmax header file of khronos <br/> * fileformats: file Format data parsing (parser) class <br/> * nodes: each node class of codec and file parsing. <Br/> * oscl: operating system compatibility library <br/> * pvmi: abstract interface of input/output control <br/> * protocols: mainly related to network-related RTSP, RTP, HTTP and other protocols <br/> * pvcommon: Android of the pvcommon library file. MK file, no source file. <Br/> * pvplayer: Specifies the Android. mk file of the pvplayer library. No source file exists. <Br/> * pvauthor: Specifies the Android. mk file of the pvauthor library file. There is no source file. <Br/> * tools_v2: compilation tool and some registrable modules. <Br/> definition and initialization of splitter <br/> take the wav splitter as an example. The fileformats directory contains the pvwavfileparser for parsing the wav file format. CPP file, including pvmf_wavffparser_factory.cpp, pvmf_wavffparser_node.h, and pvmf_wavffparser_port.h In the nodes directory. <Br/> from the bottom up, vwavfileparser. in CPP, the pv_wav_parser class includes initwavparser (), getpcmdata (), retrievefileinfo (), and other member functions that parse WAV format. This class should be the final parsing class. We can find out where the pv_wav_parser class is used. In the pvmfwavffparsernode class, there is a pointer member variable of pv_wav_parser. The pvmfwavffparsernode class is generated through the createpvmfwavffparsernode () member function of pvmfwavffparsernodefactory. The aggregate () function is registered to the vector of oscl_vector <pvplayernodeinfo, osclmemallocator> In the pvplayernoderegistry: pvplayernoderegistry () Class constructor. In this constructor, nodes such as AMR and MP3 are also registered. <Br/> as you can see, the management of splitter in opencore is similar to FFMPEG and is registered during framework initialization, but opencore registers the factory function of each splitter. <Br/> review the definition and initialization process of splitter: <br/> Each splitter has a corresponding subdirectory under the fileformats Directory, which has its own parsing class. <Br/> Each splitter has corresponding sub-directories under the nodes directory, and each of them has its own unified interface node class and node factory class. <Br/> the pvplayerengine class includes the pvplayernoderegistry iplayernoderegistry member variable. <Br/> In the pvplayernoderegistry constructor, set AMR, AAC, the input and output types of splitter such as MP3 and the create node and release Delete interfaces in the node factory class are pushed to the oscl_vector <pvplayernodeinfo, osclmemallocator> itype member variables through the pvplayernodeinfo class. <Br/> current splitter matching process <br/> pvmfstatus matching: queryregistry (pvmfformattype & ainputtype, pvmfformattype & aoutputtype, oscl_vector <pvuuid, osclmemallocator> & auuids) the function is used to find a matched node in the registered node Vector Based on the input and output types. If yes, it returns its unique identification ID pvuuid. <Br/> from the queryregistry function to the bottom-up search, the matching process of splitter in Android is as follows: <br/> A jninativemethod (Java local call method) is defined in android_media_mediaplayer.cpp) type array gmethods, which is used to find the corresponding C ++ function when calling the setdatasource member function of multiplayer class in Java code <br/> {"setdatasource ", "(ljava/lang/string;) V", (void *) android_media_mediaplayer_setdatasource}, <br/> static void android_media_mediaplayer_setdatasource (jnienv * ENV, jobject thiz, jstring) <br/> in this function Obtain the current mediaplayer instance, call its setdatasource function, and pass in the path <br/> status_t mediaplayer: setdatasource (const char * URL) <br/> call getmediaplayerservice () to obtain the current mediaplayerservice, const sp <imediaplayerservice> & Service (getmediaplayerservice (); <br/> then create an imediaplayer variable, sp <imediaplayer> player (Service-> Create (getpid (), this, FD, offset, length); <br/> in sp <imediaplayer> mediaplayerservice :: create (pid_t PID, Co In NST sp <imediaplayerclient> & client, const char * URL), <br/> call the status_t mediaplayerservice: Client: setdatasource (const char * URL) function, the client is an internal class of mediaplayerservice. <Br/> In mediaplayerservice: Client: setdatasource, call sp <mediaplayerbase> mediaplayerservice: Client: createplayer (player_type playertype) <br/> Generate a pvplayer instance that inherits from mediaplayerbase. <br/> the inheritance relationship of pvplayer is as follows: <br/> pvplayer --> mediaplayerinterface --> mediaplayerbase <br/> call the setdatasource () function of pvplayer. <br/> status_t pvplayer: setdatasource (const char * URL) <br/> status_t pvplayer: Prepare () <br/> This function starts with ret = Mplayerdriver-> enqueuecommand (New playersetdatasource (mexcepcepath,); <br/> Add the command class of playersetdatasource to the command processing queue of playerdriver. <br/> in void playerdriver:: Run () function to process this command and call the following handlesetdatasource function. <Br/> void playerdriver: handlesetdatasource (playersetdatasource * EC) <br/> pvcommandid pvplayerengine: adddatasource (pvplayerdatasource & adatasource, const osclany * acontextdata) <br/> This function allows a player data source to be specified for playback. this function must be called <br/> pvmfstatus pvplayerengine: doadddatasource (pvplayerenginecommand & acmd) <br/> pvmfstatus pvplayerengine: dosetupsourcenode (pvcommandid acmdid, osclany * acmdcontext)
The above is a clue from the predecessors, but it is not comprehensive, at least for my current job.
It uses the WAV format as a breakthrough and stops at createpvmfwavffparsernode (). The final code is located in external/opencore/engines/player/config/linux_nj/pv_player_node_registry.cpp.
We already know that the 3GP format is supported, but the android Code does not explicitly parse the 3GP file node or code. In the pvplayer method, enqueuecommand (), in run () of playerdriver, dequeuecommand () and perform corresponding operations according to command-> code.
Handlesetdatasource () appears to be related to File Format Parsing.
In handlesetdatasource (), the adddatasource () method in pv_player_engine.cpp is called and a command is sent: "pvp_engine_command_add_data_source" to the queue,
Run doadddatasource () in the switch (...) Statement in run ().
If (isourceformat = sourceformat_unknown)
{
Retval = doquerysourceformat (...);
}
Else
{
...
}
In doquerysourceformat (), the iplayerrecognizerregistry parameter debuted. Its type is pvplayerrecognizerregistry.
Iplayerrecognizerregistry. queryformattype (idatasource-> getdatasourceurl (), * This, (osclany *) context ));
In queryformattype (), a pvmidatastreamsyncinterfacereffacloud object is created using the input file path and forcibly converted to pvmfdatastreamfactory *. use pvmfrecognizerregistry: Recognize (irecsessionid, * ifiledatastreamfactory, null, irecognizerresult, null); it will continue to call pvmfrecognizerregistryimpl: Recognize (...), save the parameter and regenerate it into a cmd: pvmfrecreg_command_recognize. Then, in pvmfrecognizerregistryimpl: Run (), switch (...) execute dorecognize ().
It can be understood that all parsed nodes are saved in irecognizerpluginfactorylist, and then traversed in dorecognaize () to obtain the appropriate node (I am not sure! XD)
Which of the following can be ignored?
/*************************************** **************************************** ************
The initialization location is in pvplayerengine: populaterecognizerregistry (...) is populateallregistries (...) call, while populateallregistries (...) called in construct () of playerengine, And it is calling populaterecognizerregistry (...) previously, a populatenoderegistry (...), populateallregistries (...) go back to populaterecognizerregistry (...) first, read the config file (/system/etc/pvplayer. conf), load the dynamic library with the same UUID as pv_recognizer_interface in... (Why is a uuid specified here? The UUID corresponds to libopencoremp4reg. So in the config file. That is to say, the format of the uuid is unknown, which is used for identification ?... ). This library itself is a node of opencore and generates its Android. MK is located in "external/opencore/tools_v2/build/modules/linux_mp4/node_registry". It can be seen that it is actually nodes/pvmp4ffparsernode. At this point, the dynamic library for File Parsing has also been loaded. let's continue looking at it tomorrow. Let's review the process today and think about it...
**************************************** **************************************** *************/
Well, in fact, Android does not support .mp4because the audio part of my .mp4 file uses AAC encoding, while Android itself only supports WAV audio encoding... so, although it can be identified as video/MP4, it will lead to the player die (because my player has not corrected it)