@startuml
set namespaceSeparator .
'left to right direction'
'skinparam linetype polyline'
skinparam linetype ortho
'libmedia___SO <-[#green]- libstagefright_nuplayer___LIB'
package MediaPlayer_jni___SO{
class JNI{
android_media_MediaPlayer_setDataSourceFD();
android_media_MediaPlayer_setDataSourceCallback ();
android_media_MediaPlayer_setVideoSurface();
android_media_MediaPlayer_prepare();
android_media_MediaPlayer_prepareAsync();
android_media_MediaPlayer_start();
android_media_MediaPlayer_stop();
android_media_MediaPlayer_getVideoWidth();
android_media_MediaPlayer_getVideoHeight();
android_media_MediaPlayer_native_getMetrics();
android_media_MediaPlayer_setPlaybackParams();
android_media_MediaPlayer_getPlaybackParams();
android_media_MediaPlayer_setSyncParams();
android_media_MediaPlayer_getSyncParams();
android_media_MediaPlayer_seekTo();
android_media_MediaPlayer_notifyAt();
android_media_MediaPlayer_pause();
android_media_MediaPlayer_isPlaying();
android_media_MediaPlayer_getCurrentPosition();
android_media_MediaPlayer_getDuration();
android_media_MediaPlayer_release();
android_media_MediaPlayer_reset();
android_media_MediaPlayer_setAudioStreamType();
android_media_MediaPlayer_getAudioStreamType();
android_media_MediaPlayer_setParameter();
android_media_MediaPlayer_setLooping();
android_media_MediaPlayer_isLooping();
android_media_MediaPlayer_setVolume();
android_media_MediaPlayer_invoke();
android_media_MediaPlayer_setMetadataFilter();
android_media_MediaPlayer_getMetadata();
android_media_MediaPlayer_native_init();
android_media_MediaPlayer_native_setup();
android_media_MediaPlayer_native_finalize();
android_media_MediaPlayer_get_audio_session_id();
android_media_MediaPlayer_set_audio_session_id();
android_media_MediaPlayer_setAuxEffectSendLevel();
android_media_MediaPlayer_attachAuxEffect();
android_media_MediaPlayer_pullBatteryData();
android_media_MediaPlayer_setRetransmitEndpoint();
android_media_MediaPlayer_setNextMediaPlayer();
android_media_MediaPlayer_applyVolumeShaper();
android_media_MediaPlayer_getVolumeShaperState();
android_media_MediaPlayer_prepareDrm();
android_media_MediaPlayer_releaseDrm();
android_media_MediaPlayer_setOutputDevice();
android_media_MediaPlayer_getRoutedDeviceId();
android_media_MediaPlayer_enableDeviceCallback();
}
}
package MediaplayerInterface___h{
class MediaPlayerInterface{}
abstract MediaPlayerBase{
{abstract} initCheck() = 0;
{abstract} hardwareOutput() = 0;
...
{abstract} getParameter() = 0;
{abstract} invoke() = 0;
}
abstract MediaPlayerBase::AudioSink{
{abstract} ready() = 0;
{abstract} bufferSize() = 0;
...
{abstract} getRoutedDeviceId() = 0;
{abstract} enableAudioDeviceCallback() = 0;
}
abstract MediaPlayerBase::Listener{
{abstract} notify() = 0;
}
}
package IMediaPlayer___h{
abstract BnMediaPlayer{
onTransact();
}
abstract IMediaPlayer{
{abstract} disconnect() = 0;
{abstract} setDataSource() = 0;
...
{abstract} getRoutedDeviceId() = 0;
{abstract} enableAudioDeviceCallback() = 0;
}
}
package NuPlayerSource___h{
abstract NuPlayer::Source{}
}
package MediaBufferBase___h{
abstract MediaBufferObserver{}
}
package libmedia___SO{
class BpMediaPlayer{}
}
package libstagefright_nuplayer___LIB{
class NuPlayer #00FF7F{
status_t NuPlayer::setSyncSettings(const AVSyncSettings &sync, float videoFpsHint) //设置 AVsync 模式和配置
}
class NuPlayerDriver #00FF7F{
构造函数中通过 new NuPlayer(pid, mMediaClock) 初始化一个 NuPlayer
}
class NuPlayer::Decoder #00FF7F{
<font size=15 color=red> handleAnInputBuffer() //Inputbufferavaliable处理回调 </font>
<font size=15 color=red> handleAnOutputBuffer() //Outputbufferavaliable处理回调 </font>
}
class NuPlayer::CCDecoder{}
class NuPlayer::Renderer #00FF7F{
音画同步的逻辑所在
}
class NuPlayer::GenericSource{}
class NuPlayer::HTTPLiveSource #00FF7F{
大部分情况都是这个
}
class NuPlayer::RTSPSource{}
abstract NuPlayer::DecoderBase{}
}
package libstagefright___so{
class MediaClock{}
class LiveSession{}
class MediaCodec{}
}
package libmediaplayerservice___SO{
class MediaPlayerFactory{
{static} sp<MediaPlayerBase> createPlayer(player_type playerType,const sp<MediaPlayerBase::Listener> &listener,pid_t pid);
}
abstract MediaPlayerFactory::IFactory{
{abstract} sp<MediaPlayerBase> createPlayer(pid_t pid) = 0;
}
class NuPlayerFactory{
sp<MediaPlayerBase> createPlayer(pid_t pid); //return new NuPlayerDriver()
}
class MediaPlayerService::Client #00FF7F{
作为Binder Native端,接收消息,其中就有通过 setDataSource 使用MediaPlayerFactory创建PlayerDriver
}
}
package Other{
abstract BnInterface{}
}
MediaPlayerBase <|-- MediaPlayerInterface
MediaPlayerInterface <|.. NuPlayerDriver
MediaPlayerBase::AudioSink <--* NuPlayer
NuPlayer::Source <--* NuPlayer
MediaPlayerBase::AudioSink <--* NuPlayerDriver
NuPlayerDriver <--o "wp" NuPlayer
NuPlayer <--* "const sp" NuPlayerDriver
MediaPlayerBase::Listener <--* MediaPlayerBase
MediaPlayerBase::AudioSink <--* MediaPlayerInterface
MediaPlayerFactory::IFactory <--* "n" MediaPlayerFactory
MediaPlayerFactory::IFactory <|.. NuPlayerFactory
NuPlayerFactory "create" --> NuPlayerDriver
BnMediaPlayer <|.. MediaPlayerService::Client
BnInterface <|-- BnMediaPlayer
IMediaPlayer <|-- BnMediaPlayer
MediaPlayerFactory <-- MediaPlayerService::Client
JNI "function call" --> BpMediaPlayer
BpMediaPlayer "Binder" --> "Binder" BnMediaPlayer
NuPlayer::Source <|.. NuPlayer::GenericSource
NuPlayer::Source <|.. NuPlayer::HTTPLiveSource
NuPlayer::Source <|.. NuPlayer::RTSPSource
MediaBufferObserver <|.. NuPlayer::GenericSource
NuPlayer::DecoderBase <|.. NuPlayer::Decoder
NuPlayer::DecoderBase <--* "mVideoDecoder" NuPlayer
NuPlayer::DecoderBase <--* "mAudioDecoder" NuPlayer
NuPlayer::CCDecoder <--* "mCCDecoder" NuPlayer
NuPlayer::Renderer <--* "mRenderer" NuPlayer
MediaClock <--* NuPlayer
LiveSession <--* NuPlayer::HTTPLiveSource
MediaCodec <--* NuPlayer::Decoder
note as N_handleAnInputBuffer
handleAnInputBuffer() 中填充buffer的时候可以指定 resume-at-mediaTimeUs 来要求
handleAnOutputBuffer() 在指定mediaTime之前把所有帧都discard掉,这样有助于精准seek
endnote
N_handleAnInputBuffer..NuPlayer::Decoder
@enduml
[Android] 媒体播放框架(Media JAVA/NATIVE/JNI libmedia libmediaservice Nuplayer)
最新推荐文章于 2025-05-09 09:19:25 发布