Source code analysis of AwesomePlayer

Source: Internet
Author: User

1. AwesomeEvent is a class for synchronizing corresponding events. It works similar to logoff and handler at the framework layer. player has some asynchronous operations such as parsing files, which are time-consuming, perform asynchronous operations and then perform callback for a better user experience
Struct AwesomeEvent: public TimedEventQueue: Event
Inherited from TimedEventQueue: Event. For the internal class of c ++, refer to the previous blog. TimedEventQueue starts a thread for the post operation of the event.

 
2, AwesomeRemoteRenderer
AwesomeLocalRenderer
These two classes post data to the surface, and remote is said to be because of the use of omx node, and there is no further research, and localrenderer will call different methods based on whether there is hardware acceleration

 
3. the constructor initializes the event.
The general process of mediaplayer is
Setdatasource
PrepareAsync
Start
Now only process analysis is performed for filesource.
 
Setdatasource generally sets the file uri.
MUri = uri; set the uri.
// The actual work will be done during preparation in the call
//: Finishsetperformance_l to avoid blocking the calling thread in
// SetDataSource for any significant time.
No other operations will be performed now, because it will consume too much time and may lead to upper-layer ANR. This operation is a synchronous operation.
The most important thing is in prepareAsync. Check this function.
If (! MQueueStarted ){
MQueue. start ();
MQueueStarted = true;
} // Enable eventqueue to prepare for future event post. A thread will be created at this time.
MAsyncPrepareEvent = new AwesomeEvent (
This, & AwesomePlayer: onPrepareAsyncEvent );
MQueue. postEvent (mAsyncPrepareEvent );
// Postevent

 
To onPrepareAsyncEvent ()
If (mUri. size ()> 0 ){
Status_t err = finishsetperformance_l ();
If (err! = OK ){
AbortPrepare (err );
Return;
}
}

 
FinishSetDataSource_l (); // This is the function mentioned above. This function will create different extractor according to the source type.
For filesource, The dataSource = DataSource: CreateFromURI (mUri. string (), & mUriHeaders); // The uriheaders parameter is null.
Next, jump to source = new FileSource (uri + 7); Create filesource, it will register different extractor, sniffer different mimetype, operate filesource
Return to finishSetDataSource_l (),
Sp <MediaExtractor> extractor = MediaExtractor: Create (dataSource, mime );
At this time, datasource will sniffer different extractor, so as to establish different extractor according to the mime type
The last step is the setdatasource operation.
At this time, the audio track and viedo track will be parsed to prepare for the following codec

If (mVideoTrack! = NULL & mVideoSource = NULL ){
// Use treaty timestamps if playing
// RTSP streaming with video only content
// (No audio to drive the clock for media time)
Uint32_t flags = 0;
If (mRTSPController! = NULL & mAudioTrack = NULL ){
Flags | = OMXCodec: kUseNptTimestamp;
}
Status_t err = initVideoDecoder (flags );
If (err! = OK ){
AbortPrepare (err );
Return;
}
}
If (mAudioTrack! = NULL & mAudioSource = NULL ){
Status_t err = initAudioDecoder ();
If (err! = OK ){
AbortPrepare (err );
Return;
}
}
This is the key part of codec.
From the above, both audiotrack and videotrack will have codec initialized at this time.
InitVideoDecoder (flags );
InitAudioDecoder ();

{
MVideoSource = OMXCodec: Create (
MClient. interface (), mVideoTrack-> getFormat (),
False, // createEncoder
MVideoTrack,
NULL, flags );
OMXCodec is a key class. This is the stagefright code written a few days ago. I will continue to write that code. If it is not mentioned here, a Vide osource will be returned, this is the decoded Data Based on videotrack.
If (mVideoSource! = NULL ){
Int64_t durationUs;
If (mVideoTrack-> getFormat ()-> findInt64 (kKeyDuration, & durationUs )){
Mutex: Autolock autoLock (mMiscStateLock );
If (mDurationUs <0 | durationUs> mDurationUs ){
MDurationUs = durationUs;
}
}
CHECK (mVideoTrack-> getFormat ()-> findInt32 (kKeyWidth, & mVideoWidth ));
CHECK (mVideoTrack-> getFormat ()-> findInt32 (kKeyHeight, & mVideoHeight ));
Status_t err = mVideoSource-> start (); // at this time, both videosource and viedotrack will be ready to apply for buffer
If (err! = OK ){
MVideoSource. clear ();
Return err;
}
}
Return mVideoSource! = NULL? OK: UNKNOWN_ERROR;
}
After modification, the status will be changed and the upper-layer prepareAsync callback will be implemented.
The data has been prepared,
Play_l ()
If (mVideoSource! = NULL )&&(! MVideoBuffer ))
{
// Changes to fix Audio starts playing before video.
// First video frame is returned late as it is referenced to decode subsequent P and B frames.
// For higher resolutions (e.g. 1080 p) this returning time is significant.
// We need to trigger Video decoder earlier than audio so that Video catch up with audio in time.
MediaSource: ReadOptions options;
If (mSeeking ){
LOGV ("seeking to % lld us (%. 2f secs)", mSeekTimeUs, mSeekTimeUs/1E6 );
Options. setSeekTo (
MSeekTimeUs, MediaSource: ReadOptions: SEEK_CLOSEST_SYNC );
}
For (;;){
Status_t err = mVideoSource-> read (& mVideoBuffer, & options );
Options. clearSeekTo ();
If (err! = OK ){
CHECK_EQ (mVideoBuffer, NULL );
If (err = INFO_FORMAT_CHANGED ){
LOGV ("VideoSource signalled format change .");
If (mVideoRenderer! = NULL ){
MVideoRendererIsPreview = false;
InitRenderer_l ();
}
Continue;
}
Break;
}
 
Break;
}
}
If (mVideoSource! = NULL ){
// Kick off video playback
PostVideoEvent_l ();
}
Render the mVideoBuffer to the surface.
However, audio calls audioplayer.
MAudioPlayer = new AudioPlayer (mAudioSink, this );
MAudioPlayer-> setSource (mAudioSource );
// We 've already started the MediaSource in order to enable
// The prefetcher to read its data.
Status_t err = mAudioPlayer-> start (
True/* sourceAlreadyStarted */);
There is also the issue of Audio and Video Synchronization and seek, and we will write it again next time.

From shcalm's column

Related Article

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.