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();
}
目录
相关文章
|
3月前
|
JavaScript
如何使用requestAnimationFrame实现DOM组件的同步更新?
【5月更文挑战第29天】如何使用requestAnimationFrame实现DOM组件的同步更新?
26 1
|
3月前
|
前端开发
在有状态组件中使用forceUpdate()方法重新渲染
在React类组件中使用`forceUpdate()`重新渲染的步骤包括:继承`React.Component`,定义`updateComponent`方法调用`forceUpdate`,并在模块热替换回调中调用此方法。示例代码展示了如何实现。注意,这种方式需要手动创建和管理组件实例,不适合React Hooks,应优先考虑使用`useState`或`useReducer`来更新状态并触发渲染。
|
3月前
|
数据采集 资源调度 前端开发
React的服务器端渲染:使用ReactDOMServer进行高效页面预渲染
【4月更文挑战第25天】使用ReactDOMServer,React支持服务器端渲染以实现高效预渲染。通过在Node.js环境中将React组件转化为HTML字符串,减少客户端JavaScript负载和渲染时间。优点包括更快首屏加载、改善SEO和兼容无JavaScript环境,但也会增加服务器负载、复杂性和状态管理挑战。开发者需根据项目需求平衡SSR和CSR。
|
3月前
在Vuex中,如何处理不同模块之间的状态同步?
在Vuex中,如何处理不同模块之间的状态同步?
36 1
|
10月前
|
JSON 前端开发 API
🚀🚀🚀 量大管饱,一次性推荐20个React组件库!!
🚀🚀🚀 量大管饱,一次性推荐20个React组件库!!
|
缓存 前端开发 JavaScript
如何减少React中无关组件的重渲染
你是否同我一样,总是会遇到一些莫名其妙的渲染问题,有时为了解决bug,需要耗费相当气力来debug呢?快来一起学习下react re-render 这些小技巧吧,或许能帮你减少组件树中无关组件的重渲染及重挂载,可以提升性能,同时也能提高用户体验哟。 案例代码:https://github.com/buzingar/re-render-demos
2224 5
函数方式渲染页面
函数方式渲染页面
38 0
|
JavaScript
Vue数据渲染技巧:从三种方式看后端数据的灵活处理
Vue数据渲染技巧:从三种方式看后端数据的灵活处理
170 0
|
JavaScript
解决uniapp分段器参数改变不渲染,适用所有组件
解决uniapp分段器参数改变不渲染,适用所有组件
491 0