NuPlayer渲染和同步模块

简介: NuPlayer渲染和同步模块

NuPlayer的解码模块相对比较简单,统一使用了一个基类NuPlayerDecoderBase管理,该类中包含了一个MediaCodec的对象,实际解码工作全靠MediaCodec。


如果你不会知道MediaCodec是什么,推荐去官网看看:MediaCodec

那他的主要功能有哪些呢?


将音视频的原始数据缓存到队列

音频数据消耗播放

视频数据消耗显示

音视频同步

播放器控制

void NuPlayer::Renderer::onQueueBuffer(const sp<AMessage> &msg) {
    int32_t audio;
    CHECK(msg->findInt32("audio", &audio));
    if (dropBufferIfStale(audio, msg)) {
        return;
    }
    if (audio) {
        mHasAudio = true; //音频
    } else {
        mHasVideo = true; //视频
    }
    if (mHasVideo) {
        if (mVideoScheduler == NULL) {
            mVideoScheduler = new VideoFrameScheduler();  //视频渲染调整
           mVideoScheduler->init();
        }
    }
    sp<ABuffer> buffer;
    CHECK(msg->findBuffer("buffer", &buffer));
    sp<AMessage> notifyConsumed;
    CHECK(msg->findMessage("notifyConsumed", &notifyConsumed));
    QueueEntry entry;
    entry.mBuffer = buffer;
    entry.mNotifyConsumed = notifyConsumed;
    entry.mOffset = 0;
   entry.mFinalResult = OK;
   entry.mBufferOrdinal = ++mTotalBuffersQueued;
   if (audio) {
       Mutex::Autolock autoLock(mLock);
        mAudioQueue.push_back(entry);
        postDrainAudioQueue_l(); //刷新音频
    } else {
        mVideoQueue.push_back(entry);
       postDrainVideoQueue(); //刷新视频
   }
    Mutex::Autolock autoLock(mLock);
    if (!mSyncQueues || mAudioQueue.empty() || mVideoQueue.empty()) {
        return;
    }
    sp<ABuffer> firstAudioBuffer = (*mAudioQueue.begin()).mBuffer;
    sp<ABuffer> firstVideoBuffer = (*mVideoQueue.begin()).mBuffer;
    if (firstAudioBuffer == NULL || firstVideoBuffer == NULL) {
        // EOS signalled on either queue.
        syncQueuesDone_l();
        return;
    }
   int64_t firstAudioTimeUs;
    int64_t firstVideoTimeUs;
    CHECK(firstAudioBuffer->meta()
            ->findInt64("timeUs", &firstAudioTimeUs));
    CHECK(firstVideoBuffer->meta()
            ->findInt64("timeUs", &firstVideoTimeUs));
    int64_t diff = firstVideoTimeUs - firstAudioTimeUs;
    ALOGV("queueDiff = %.2f secs", diff / 1E6);
    if (diff > 100000ll) {
        // Audio data starts More than 0.1 secs before video.
       // Drop some audio.
       (*mAudioQueue.begin()).mNotifyConsumed->post();
       mAudioQueue.erase(mAudioQueue.begin());
        return;
    }
    syncQueuesDone_l();
}
目录
相关文章
|
7月前
|
JavaScript 前端开发 开发者
Vue的事件处理机制提供了灵活且强大的方式来响应用户的操作和组件间的通信
【5月更文挑战第16天】Vue事件处理包括v-on(@)指令用于绑定事件监听器,如示例中的按钮点击事件。事件修饰符如.stop和.prevent简化逻辑,如阻止表单默认提交。自定义事件允许组件间通信,子组件通过$emit触发事件,父组件用v-on监听并响应。理解这些机制有助于掌握Vue应用的事件控制。
69 4
|
5月前
|
开发框架 JavaScript 前端开发
基于Vue的工作流项目模块中,使用动态组件的方式统一呈现不同表单数据的处理方式
基于Vue的工作流项目模块中,使用动态组件的方式统一呈现不同表单数据的处理方式
|
7月前
|
前端开发
在有状态组件中使用forceUpdate()方法重新渲染
在React类组件中使用`forceUpdate()`重新渲染的步骤包括:继承`React.Component`,定义`updateComponent`方法调用`forceUpdate`,并在模块热替换回调中调用此方法。示例代码展示了如何实现。注意,这种方式需要手动创建和管理组件实例,不适合React Hooks,应优先考虑使用`useState`或`useReducer`来更新状态并触发渲染。
|
7月前
在Vuex中,如何处理不同模块之间的状态同步?
在Vuex中,如何处理不同模块之间的状态同步?
64 1
|
缓存 前端开发 JavaScript
如何减少React中无关组件的重渲染
你是否同我一样,总是会遇到一些莫名其妙的渲染问题,有时为了解决bug,需要耗费相当气力来debug呢?快来一起学习下react re-render 这些小技巧吧,或许能帮你减少组件树中无关组件的重渲染及重挂载,可以提升性能,同时也能提高用户体验哟。 案例代码:https://github.com/buzingar/re-render-demos
2311 5
|
JavaScript API
更改redux 数据,页面未重新渲染
更改redux 数据,页面未重新渲染
|
JSON 前端开发 API
🚀🚀🚀 量大管饱,一次性推荐20个React组件库!!
🚀🚀🚀 量大管饱,一次性推荐20个React组件库!!
|
JavaScript
Vue数据渲染技巧:从三种方式看后端数据的灵活处理
Vue数据渲染技巧:从三种方式看后端数据的灵活处理
188 0
|
存储 JavaScript 前端开发
Redux 状态管理库的原理及使用方式
Redux 是一种流行的状态管理库,用于在 JavaScript 应用程序中管理应用的状态。它遵循单一状态树的原则,将整个应用的状态保存在一个状态树中,并通过纯函数来修改状态。Redux 的原理和使用方式如下:
141 0