NuPlayer 框架

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lf12345678910/article/details/60571430

那么一个类的对外接口部分通常包括:

  • 构造函数和析构函数
  • 必须调用的接口
  • 可选的调用接口

在多媒体播放中,通过关注的点有:

  • 如何实现解复用,得到音频、视频、字幕等数据
  • 如何实现解码
  • 如何实现音视频同步
  • 如何渲染视频
  • 如何播放音频
  • 如何实现快速定位
  •  
  1. 不同格式的多媒体文件如何探测并解析的?音视频数据缓冲区在哪里?(Source)
  2. 视频如何显示的?音频如何播放的?音视频同步在哪里?(Renderer)
  3. 音频解码线程、视频解码线程在哪里? (DecoderBase)

http://www.cnblogs.com/tocy/p/5-nuplayer-GenericSource-source-code-analysis.html

ACodec与MediaCodec的通知

http://blog.csdn.net/coolcary/article/details/51939080

Renderer对video的处理是判断video是否已经延迟过长,如果是就不渲染了。
渲染开始是在ACodec的onOMXFillBufferDone,ACodec发消息到MediaCodec,MediaCodec会updateBuffers然后调用onOutputBufferAvailable中通知Decoder有可用的output buffer.
Decoder接收消息后就handleAnOutputBuffer.之后Decoder和Renderer交互,会判断是否渲染,通知Renderer会回调Decoder的onRenderBuffer(msg),然后Decoder会和MediaCodec交互,
MediaCodec判断是软件渲染或者硬件渲染,软件渲染就交给SofterwareRender,硬件渲染就交给ACodec。不管MediaCodec决定这么渲染,都会回调到ACodec中的onOutputBufferDrained(msg),继续fillbuffer,之后ACodec被OMX继续回调onOMXFillBufferDone.

http://blog.csdn.net/coolcary/article/details/51939158

Decoder会和MediaCodec做交互,做渲染。MediaCodec是判断视频渲染的关键。
交给MediaCodec的renderOutputBufferAndRelease 或者 releaseOutputBuffer;一个会真的渲染一个不渲染

这个应该是一开始就创建好的一个类!

MediaMetadataRetriever类提供了一个统一的接口用于从一个输入媒体文件中取得帧和元数据。

mediascanner----》StagefrightMediaScanner

http://blog.csdn.net/vincent_blog/article/details/9983581

实际解码过程中,无外乎获取输入的压缩数据,MediaCodec解码,返回解码之后的数据,渲染

实际的解码开始是从onSetRenderer开始,Part 4中对这个函数的实现也有介绍,循环解码的逻辑来在于onRequestInputBuffers函数,其中会调用doRequestBuffers

 
解码前的数据准备  MediaCodec::CB_INPUT_AVAILABLE handleAnInputBuffer

解码后的数据处理函数是handleAnOutputBuffer,响应MediaCodec::CB_OUTPUT_AVAILABLE消息

AVFactory::get()->createACodec();   //  MediaFilter

ACodec与MediaCodec的通知。OMX的组件解码之后,当ACodec的onOMXFillBufferDone会被回调,去取得解码后的数据。
ACodec在onOMXFillBufferDone调用后会调用notify通知MediaCodec(notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);//发给MediaCodec的消息。
MediaCodec收到ACodec发的消息之后会更新updateBuffers(kPortIndexOutput, msg),同时onOutputBufferAvailable()中通知Decoder。

frameworks/av/media/libstagefright/ACodec.cpp

显示是如何处理的。那就是handleAnOutputBuffer发送的一个kWhatRenderBuffer消息的处理

ACodec收到的消息分两种,一种是MediaCodec传过来的,一种是OMX Component传过来的。分别对应onMessageReceived和onOMXMessage

NuPlayer onStart  mRenderer = AVNuFactory::get()->createRenderer(mAudioSink, notify, flags);  mAudioDecoder->setRenderer(mRenderer);

NuPlayerRenderer  onQueueBuffer

        // Audio data starts More than 0.1 secs before video.
        // Drop some audio.

openAudioSink

onDrainAudioQueue

frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp

        mAudioOutput = new AudioOutput(mAudioSessionId, IPCThreadState::self()->getCallingUid(),
                mPid, mAudioAttributes);
        static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);

AudioTrack是硬件音频接收器,AudioSink用于内存解码或者可能的其他应用程序他们的输出并不直接输出到硬件中去

不管是不是offload模式(音频由dsp解码,不走omx框架),最终都会有AudioSink。有两类player,MediaPlayerInterface和MediaPlayerHWInterface。
andriod里面绝大数情况(phone,tv可能不是这样)用的就是MediaPlayerInterface,最终都会有AudioSink。
通过AudioSink和音频框架的交互来实现音频输出。
 

SimpleSoftOMXComponent

11.编解码的配置文件

MediaPlayerService::getOMX (new OMX)

OMX.cpp  allocateNode(mMaster->makeComponentInstance)

OMXMaster

addVendorPlugin  oem解码器

addPlugin  谷歌解码器

/etc/media_codecs.xml, media_profile.xml,开机就解析。

MediaPlayer.java:提供了视频、音频、数据流的播放控制等操作的接口。
MediaRecorder.java:提供了视频、音频录制的接口。
AudioManager.java: 提供了音频音量,以及播放模式(静音、震动等)的控制。
RingtoneManager.java、Ringtone.java: 提供了提醒、闹钟、事件等声音的播放控制。
MediaScanner*.java: 提供了媒体扫描接口的支持。
AudioTrack.java:SoundPool.java 播放androidapplication的生音资源。
AudioRecord.java: 为android applicatio提供录音设置(sample、chanel等)的接口;

stagefrightmediascanner.cpp

metadataretrieverclient.cpp

之前我们分析了NuPlayer的实现代码,本文将重点聚焦于其中的一部分——渲染器(Renderer)。
从功能安排来说,Renderer的主要功能有:

  • 音视频原始数据缓存操作
  • 音频播放(到声卡)
  • 视频显示(到显卡)
  • 音视频同步
  • 其他辅助播放器控制的操作
  • 其他获取渲染状态/属性的接口

先回顾下NuPlayer源码解析中的调用接口。

  • 构造/析构函数
  • 设置播放控制参数——setPlaybackSettings/getPlaybackSettings/setVideoFrameRate/setSyncSettings/getSyncSettings
  • AudioSink相关——openAudioSink/closeAudioSink
  • 控制接口——pause/flush/resume/queueEOS
  • 音频状态更新——signalEnableOffloadAudio/signalDisableOffloadAudio
  • 音视频原始数据输入——queueBuffer
    NuPlayer中并未显示调用,而是将Renderer设置给ADecoder使用

http://www.cnblogs.com/tocy/p/4-nuplayer-renderer-source-code-analysis.html

03-09 15:35:12.686   548   548 V MediaExtractor: Autodetected media content as 'audio/midi' with confidence 0.80
03-09 15:35:12.686   548   548 I ExtendedExtractor: QTIParser is prefered
03-09 15:35:12.686   548   548 I QComExtractorFactory: QTI parser is not preferred for mime: audio/midi
03-09 15:35:12.686   548   548 E QCExtractor:  ExtendedExtractor failed to instantiate extractor
03-09 15:35:12.686   548   548 I ExtendedExtractor: ExtendedExtractor::create 0x0
03-09 15:35:12.686   548   548 I MediaExtractor: extractor created in uid: 1013 (media)
03-09 15:35:12.687  5810  6480 I DpmTcmClient: RegisterTcmMonitor from: com.android.okhttp.TcmIdleTimerMonitor
03-09 15:35:12.693   501   949 D audio_hw_extn: audio_extn_get_parameters: returns
03-09 15:35:12.693   501   949 I hash_map_utils: key: 'is_hw_dec_session_available' value: 'audio/raw'
03-09 15:35:12.697   548  6501 I MediaPlayerService: MediaPlayerService::getOMX
03-09 15:35:12.698   548  6501 I OMXClient: MuxOMX ctor
03-09 15:35:12.699   534   534 I OMXMaster: makeComponentInstance(OMX.google.raw.decoder) in mediacodec process
03-09 15:35:12.703   534   874 E OMXNodeInstance: setConfig(2160032:google.raw.decoder, ConfigPriority(0x6f800002)) ERROR: Undefined(0x80001001)
03-09 15:35:12.704   548  6501 I ACodec  : codec does not support config priority (err -2147483648)
03-09 15:35:12.705   534  4842 E OMXNodeInstance: setConfig(2160032:google.raw.decoder, ConfigPriority(0x6f800002)) ERROR: Undefined(0x80001001)
03-09 15:35:12.705   548  6501 I ACodec  : codec does not support config priority (err -2147483648)
03-09 15:35:12.707   548  6501 I MediaCodec: MediaCodec will operate in async mode
03-09 15:35:12.744   548  4745 V StagefrightMetadataRetriever: extractAlbumArt (extractor: YES)
03-09 15:35:12.745   548  4745 E MetadataRetrieverClient: failed to extract an album art
03-09 15:35:12.745   548   548 V StagefrightMetadataRetriever: ~StagefrightMetadataRetriever()

--------------------------------------------------

ERROR_UNSUPPORTED   error (1, -1010)

01-22 07:29:01.505   551  9096 I MediaPlayerService: MediaPlayerService::getOMX
01-22 07:29:01.506   551  9096 I OMXClient: MuxOMX ctor
01-22 07:29:01.507   543  4767 I OMXMaster: makeComponentInstance(OMX.google.raw.decoder) in mediacodec process
01-22 07:29:01.510   543   543 E OMXNodeInstance: setConfig(21f0044:google.raw.decoder, ConfigPriority(0x6f800002)) ERROR: Undefined(0x80001001)
01-22 07:29:01.511   551  9096 I ACodec  : codec does not support config priority (err -2147483648)
01-22 07:29:01.514   543   810 E OMXNodeInstance: setConfig(21f0044:google.raw.decoder, ConfigPriority(0x6f800002)) ERROR: Undefined(0x80001001)
01-22 07:29:01.514   551  9096 I ACodec  : codec does not support config priority (err -2147483648)
01-22 07:29:01.524   551  9096 I MediaCodec: MediaCodec will operate in async mode
01-22 07:29:01.549   551  9095 E NuPlayerDecoder: Stream error for OMX.google.raw.decoder (err=-1010), EOS successfully queued
01-22 07:29:01.549   551  9090 E NuPlayer: received error(0xfffffc0e) from audio decoder, flushing(0), now shutting down
01-22 07:29:01.549   551  9090 D NuPlayerDriver: notifyListener_l(0xb4607000), (100, 1, -1010), loop setting(0, 0)
01-22 07:29:01.551  7442  7990 E MediaPlayer: error (1, -1010)
01-22 07:29:01.553   551  9095 E NuPlayerDecoder: Stream error for OMX.google.raw.decoder (err=-1010), EOS successfully queued
01-22 07:29:01.553   551  9095 E NuPlayerDecoder: Stream error for OMX.google.raw.decoder (err=-1010), EOS successfully queued
01-22 07:29:01.554   551  9095 E NuPlayerDecoder: Stream error for OMX.google.raw.decoder (err=-1010), EOS successfully queued
01-22 07:29:01.554   551  9090 E NuPlayer: received error(0xfffffc0e) from audio decoder, flushing(2), now shutting down
01-22 07:29:01.554   551  9090 D NuPlayerDriver: notifyListener_l(0xb4607000), (100, 1, -1010), loop setting(0, 0)
01-22 07:29:01.554   551  9090 E NuPlayer: received error(0xfffffc0e) from audio decoder, flushing(2), now shutting down
01-22 07:29:01.554   551  9090 D NuPlayerDriver: notifyListener_l(0xb4607000), (100, 1, -1010), loop setting(0, 0)
01-22 07:29:01.554  7442  7453 E MediaPlayer: error (1, -1010)
01-22 07:29:01.554   551  9090 E NuPlayer: received error(0xfffffc0e) from audio decoder, flushing(2), now shutting down
01-22 07:29:01.554   551  9090 D NuPlayerDriver: notifyListener_l(0xb4607000), (100, 1, -1010), loop setting(0, 0)
01-22 07:29:01.554  7442  7453 E MediaPlayer: error (1, -1010)
01-22 07:29:01.555  7442  7453 E MediaPlayer: error (1, -1010)
01-22 07:29:01.555  7442  7442 D skia    : ---- fAsset->read(8192) returned 0
01-22 07:29:01.555  7442  7442 D skia    : --- SkAndroidCodec::NewFromStream returned null
01-22 07:29:01.564   551  9090 W AMessage: failed to post message as target looper for handler 0 is gone.
01-22 07:29:01.577  7442  7442 E MediaPlayer: invoke failed: wrong state 0, mPlayer(0xaaeae5c0)
01-22 07:29:01.610  7442  7479 D skia    : ---- fAsset->read(8192) returned 0
01-22 07:29:01.610  7442  7479 D skia    : --- SkAndroidCodec::NewFromStream returned null
01-22 07:29:01.622  7442  7442 E MediaPlayer: Error (1,-1010)
01-22 07:29:01.622  7442  7442 E MultiPlayer: Error: 1,-1010
01-22 07:29:01.624   551  7930 D NuPlayerDriver: reset(0xb4607000) at state 5
01-22 07:29:01.624   551  7930 D NuPlayerDriver: notifyListener_l(0xb4607000), (8, 0, 0), loop setting(0, 0)
01-22 07:29:01.624   551  9090 D NuPlayerDriver: notifyResetComplete(0xb4607000)

猜你喜欢

转载自blog.csdn.net/lf12345678910/article/details/60571430