[Android] 媒体播放框架(Media JAVA/NATIVE/JNI libmedia libmediaservice Nuplayer)

文章详细介绍了Android多媒体框架中NuPlayer组件的工作原理,包括NuPlayer如何处理输入和输出缓冲区以实现音画同步,以及与MediaPlayer接口的交互,如通过JNI调用、Binder通信实现数据源设置和播放控制等操作。
摘要由CSDN通过智能技术生成
@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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值