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();
}
目录
相关文章
|
28天前
|
存储 JavaScript 中间件
在 Redux 动态路由中进行数据预加载时,如何处理数据加载失败的情况?
【10月更文挑战第22天】在 Redux 动态路由中进行数据预加载时,数据加载失败是需要妥善处理的情况
30 4
|
28天前
|
监控 JavaScript 前端开发
在 Redux 动态路由中进行数据预加载时,如何监控数据加载进度?
【10月更文挑战第22天】可以在 Redux 动态路由的数据预加载过程中有效地监控数据加载进度,为用户提供更直观的反馈,同时也有助于开发者更好地了解数据加载的性能和状态,以便进行进一步的优化和调整。
31 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
2310 5
|
JavaScript API
更改redux 数据,页面未重新渲染
更改redux 数据,页面未重新渲染
|
JavaScript
Vue数据渲染技巧:从三种方式看后端数据的灵活处理
Vue数据渲染技巧:从三种方式看后端数据的灵活处理
188 0
|
存储 JavaScript 前端开发
Redux 状态管理库的原理及使用方式
Redux 是一种流行的状态管理库,用于在 JavaScript 应用程序中管理应用的状态。它遵循单一状态树的原则,将整个应用的状态保存在一个状态树中,并通过纯函数来修改状态。Redux 的原理和使用方式如下:
141 0