Introduction to Android Pvplayer

Source: Internet
Author: User

1 Player's composition

Opencore's player's compiled file is pvplayer/android.mk, which will generate the dynamic library file libopencoreplayer.so. The library includes two things: one is the player's engine, and the other is the player for the Android widget, which is actually an adapter (adapter). The path to the engine is Engine/player;adapter's path is Android.

  

2 Player engine section

    Opencoreof thePlayer Engineinterface with clear understanding. On top of this interface, different systems can be implemented according to their own circumstances.Player. FolderEnginesThe file structure in the following example is seen below:
engines/player/
|--android.mk
|--Build
| |--Linux_nj
| |--make
| '--makefile.conf
|--Config
| '--LINUX_NJ
|--include
| |--pv_player_datasink.h
| |--pv_player_datasinkfilename.h
| |--pv_player_datasinkpvmfnode.h
| |--pv_player_datasource.h
| |--pv_player_datasourcepvmfnode.h
| |--pv_player_datasourceurl.h
| |--Pv_player_events.h
| |--Pv_player_factory.h
| |--pv_player_interface.h
| |--pv_player_license_acquisition_interface.h
| |--pv_player_registry_interface.h
| |--pv_player_track_selection_interface.h
| '--pv_player_types.h
|--Sample_app
| |--android.mk
| |--Build
| |--Sample_player_app_release.txt
| '--src
|--SRC
| |--Pv_player_datapath.cpp
| |--PV_PLAYER_DATAPATH.H
| |--Pv_player_engine.cpp
| |--pv_player_engine.h
| |--Pv_player_factory.cpp
| |--Pv_player_node_registry.h
| '--pv_player_sdkinfo.h
'--Test
|--android.mk
|--Build
|--Config
'--src
among them, the Engines/player/include folder is the interface header file, the Engines/player/src folder source file and the private header file, the main header file features such as the following see:
   pv_player_types.h: Defines some data structures and enumeration values
   pv_player_events.h: Defines the UUID and some error values.
   pv_player_datasink.h: Datasinkis the output of the media data,Defining ClassesPvplayerdatasink,this is the base class for media data output,use as an interface
   pv_player_datasinkfilename.h:Defining ClassesPvplayerdatasinkfilenameInheritancePvplayerdatasink.
   pv_player_datasinkpvmfnode.h:Defining ClassesPvplayerdatasinkpvmfnodeInheritancePvplayerdatasink.
   pv_player_datasource.h: DataSourceis the input to the media data,Defining ClassesPvplayerdatasource, which is the base class for media data input and is used as an interface.
   pv_player_datasourcepvmfnode.h: Defines the class Pvplayerdatasourcepvmfnode inheritance Pvplayerdatasource.
   pv_player_datasourceurl.h: Defines the class Pvplayerdatasourceurl inheritance Pvplayerdatasource.
   pv_player_interface.h:definitionPlayerthe interfacePvplayerinterface,This is an interface class.
   pv_player_factory.h:Main definition Factory classpvplayerfactory, used to create and destroy Pvplayerinterface.
in fact, in ENGINES/PLAYER/SRCin the folder,the main implementation class isPv_player_engine.cpp,defines the classPvplayerengine, Pvplayerengine inherits the Pvplayerinterface, which is an implementation class that is actually created Pvplayerengine when Pvplayerfactory creates the Pvplayerinterface interface.


      in thePlayer Engineimplementation, including the codec and flow control functions, and the output of the media need to be set up from the outside. PvplayerinterfaceThe interfaces defined are basically in accordance with the order of operations, and the basic interfaces such as the following are seen:
In the implementation of player engine, including codec and flow control functions, and the output of the media need to be set up from the outside. The interfaces defined by Pvplayerinterface are basically in accordance with the order of operations, and the basic interfaces such as the following are seen:
pvcommandid AddDatasource (pvplayerdatasource& adatasource, const osclany* Acontextdata = NULL);
Pvcommandid Init (const osclany* acontextdata = NULL);
Pvcommandid Adddatasink (pvplayerdatasink& adatasink, const osclany* acontextdata = NULL);
Pvcommandid Prepare (const osclany* acontextdata = NULL);
Pvcommandid Start (const osclany* acontextdata = NULL);
Pvcommandid Pause (const osclany* acontextdata = NULL);
Pvcommandid Resume (const osclany* acontextdata = NULL);
Pvcommandid Stop (const osclany* acontextdata = NULL);
Pvcommandid Removedatasink (pvplayerdatasink& adatasink, const osclany* acontextdata = NULL);
Pvcommandid Reset (const osclany* acontextdata = NULL);
Pvcommandid Removedatasource (pvplayerdatasource& adatasource, const osclany* acontextdata = NULL);
The Datasink may include both the output of video and the output of audio. In the Pv_player_types.h file, the player's state machine is defined, starting with Pvp_state_, as seen in the following:
typedef enum
{
Pvp_state_idle = 1,
pvp_state_initialized = 2,
pvp_state_prepared = 3,
pvp_state_started = 4,
pvp_state_paused = 5,
Pvp_state_error = 6
} pvplayerstate;
Each operation in the Pvplayerinterface is assumed to be successful and can change the player's state machine: The player is pvp_state_idle state when initialized, and enters pvp_state_initialized state after calling Init Call Adddatasink, enter pvp_state_prepared state, call prepare, enter pvp_state_prepared state, call start and enter pvp_state_started state, You can then call pause to enter the pvp_state_paused state.
The pvp_state_started and pvp_state_paused states are in the playback state and can be toggled in both states using the start and pause functions.
During playback, call stop can return the pvp_state_initialized state, and return the Pvp_state_idle state in the call Removedatasource.

3 Android Player Adapter

The adapter that is defined as the player in the Android folder, this folder mainly includes files such as the following:
  Android
  |--android.mk
  |--Android_audio_mio.cpp
  |--android_audio_mio.h
  |--Android_audio_output.cpp
  |--android_audio_output.h
  |--Android_audio_output_threadsafe_callbacks.cpp
  |--Android_audio_output_threadsafe_callbacks.h
  |--Android_audio_stream.cpp
  |--android_audio_stream.h
  |--Android_log_appender.h
  |--Android_surface_output.cpp
  |--android_surface_output.h
  |--Mediascanner.cpp
  |--Metadatadriver.cpp
  |--Metadatadriver.h
  |--Playerdriver.cpp
  |--Playerdriver.h
  '--Thread_init.cpp
The Android player's "adapter" needs to invoke the interface of Opencore's player engine to implement the interface required by the Android Media Player's service, that is, to finally implement a pvplayer, and Pvplayer actually inherits Mediaplayerinterface.
In the implementation process, the first implementation of a playerdriver, and then use Pvplayer,pvplayer by calling Playerdriver to complete the detailed function. The entire implementation of the structure diagram sees:


The various operations on Pvplayerdriver are completed using a variety of commands, which are defined in the Playerdriver.h.
Enum Player_command_type {
Player_quit = 1,
Player_setup = 2,
Player_set_data_source = 3,
Player_set_video_surface = 4,
Player_set_audio_sink = 5,
Player_init = 6,
Player_prepare = 7,
Player_start = 8,
Player_stop = 9,
Player_pause = 10,
Player_reset = 11,
Player_set_loop = 12,
Player_seek = 13,
Player_get_position = 14,
Player_get_duration = 15,
Player_get_status = 16,
Player_remove_data_source = 17,
Player_cancel_all_commands = 18,
};
These commands generally implement a simple encapsulation of the various interfaces of the pvplayerinterface, for example, for a simpler pause operation, the entire system is running steps such as the following:
1. The pause function in Pvplayer (in the Playerdriver.cpp file)
status_t Pvplayer::p ause ()
{
LOGV ("pause");
Return Mplayerdriver->enqueuecommand (New Playerpause (0,0));
}
This is called the function of its member mplayerdriver (playerdriver type), adding a command sequence to a playerpause command, with detailed command functions in the Playerdriver.h file.
2. The Enqueuecommand of the Playerdriver class will indirectly invoke each function that starts with handle, and for the Playerpause command, the function that is called is Handlepause
void Playerdriver::handlepause (playerpause* EC)
{
LOGV ("Call pause");
Mplayer->pause (0);
Finishsynccommand (EC);
}
The mplayer here is a pvplayerinterface type pointer that is used to invoke the Pvplayerengine class in Opencore's Player engine.
In the implementation of this player adapter, one of the main tasks is to convert the output of the media defined in the Android framework (including the output of audio and the output of video) into the form required by the Opencore Playerengine. Here two important classes are the Androidaudiooutput implementations of the androidsurfaceoutput,android_audio_output.cpp implementation of the Android_surface_output.cpp.
For the setup process of the video output, 3 members are defined in class Playerdriver:
Pvplayerdatasink *mvideosink;
Pvmfnodeinterface *mvideonode;
Pvmimiocontrol *mvideooutputmio;
The type of Mvideosink here is Pvplayerdatasink, which is the class interface defined in Playerengine, the Mvideonode type is Vmfnodeinterface, pvmi/pvmf/include in PVMF As defined in _node_interface.h, this is the unified interface that all PVMF node needs to inherit, and the Mvideooutputmio type is Pvmimiocontrol also defined in Pvmi/pvmf/include, This is the interface class for media graphics output control.
1. The Pvplayer setvideosurface is used to set up a video output interface, where the type of the reference is ISurface pointer:
status_t pvplayer::setvideosurface (const sp<isurface>& surface)
{
LOGV ("Setvideosurface (%p)", Surface.get ());
Msurface = surface;
return OK;
}
The Setvideosurface function sets a member of the Pvplayer in Msurface, and the function of the interface that truly sets the video output is implemented in the Run_set_video_surface () function:
void Pvplayer::run_set_video_surface (status_t s, void *cookie)
{
LOGV ("Run_set_video_surface s=%d", s);
if (s = = No_error) {
Pvplayer *p = (pvplayer*) cookie;
if (P->msurface = = NULL) {
Run_set_audio_output (S, cookies);
} else {
P->mplayerdriver->enqueuecommand (New Playersetvideosurface (P->msurface, Run_set_audio_output, Cookie));
}
}
}
The command used at this point is playersetvideosurface and will finally be called to the Handlesetvideosurface function in Playerdriver.
2. The implementation of the Handlesetvideosurface function is seen in the following example:
void Playerdriver::handlesetvideosurface (playersetvideosurface* EC)
{
int error = 0;
Mvideooutputmio = new Androidsurfaceoutput (Ec->surface ());
Mvideonode = Pvmediaoutputnodefactory::createmediaoutputnode (Mvideooutputmio);
Mvideosink = new Pvplayerdatasinkpvmfnode;
( (Pvplayerdatasinkpvmfnode *) mvideosink)->setdatasinknode (Mvideonode);
((Pvplayerdatasinkpvmfnode *) mvideosink)->setdatasinkformattype (pvmf_yuv420);
oscl_try (Error, Mplayer->adddatasink (*mvideosink, EC));
Oscl_first_catch_any (Error, commandfailed (EC));
}
Here the first created member Mvideooutputmio (type Pvmimiocontrol), the class is the class Androidsurfaceoutput, this class inherits Pvmimiocontrol, So it can be used as a pvmimiocontrol. Then call Pvmediaoutputnodefactory::createmediaoutputnode to establish the Pvmfnodeinterface type of Mvideonode. Subsequent creation of the Pvplayerdatasinkpvmfnode type Mvideosink,pvplayerdatasinkpvmfnode itself inherits the Pvplayerdatasink, So it can be used as a pvplayerdatasink. Call the Setdatasinknode function to set Mvideonode to Mvideosink's data output node.


In fact, for the video output, the basic functions are in the class Androidsurfaceoutput, in this class, where the basic work is the Android ISurface output as the output of playerengine. Finally, Adddatasink is called to add Mvideosink to pvplayerinterface output.
The class Androidsurfaceoutput is implemented in the Android_surface_output.cpp file, which is equivalent to a opencoreplayer engine's video output and an "adapter" for Android output. The Androidsurfaceoutput class itself inherits the class Pvmimiocontrol, and its constructors take the ISurface type as the parameter. The implementation of this class is to implement the various interfaces of Pvmimiocontrol using ISurface.

Introduction to Android Pvplayer

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.