/* * Copyright (C) 2014-2025 Amlogic, Inc. All rights reserved. * * All information contained herein is Amlogic confidential. * * This software is provided to you pursuant to Software License Agreement * (SLA) with Amlogic Inc ("Amlogic"). This software may be used * only in accordance with the terms of this agreement. * * Redistribution and use in source and binary forms, with or without * modification is strictly prohibited without prior written permission from * Amlogic. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #pragma once #include #include // maybe we can use std::chrono::steady_clock // how to program it with longlong time? #include #include #include #include "Parser.h" #include "Render.h" #include "ai_translation/SubtitleAiTranslation.h" using android::Looper; using android::Message; using android::Mutex; using android::sp; class Presentation : public ParserSubdataNotifier, public SubtitleAiTranslation::ISubtitleAiTranslationObserver { public: explicit Presentation(bool registeredOnDataCB); virtual ~Presentation(); bool notifyStartTimeStamp(int64_t startpts); bool syncCurrentPresentTime(int64_t pts); bool startPresent(std::shared_ptr parser); bool stopPresent(); bool resetForSeek(); bool combineSamePtsSubtitle(std::shared_ptr spu1, std::shared_ptr spu2); bool show(); bool hide(); virtual void notifySubdataAdded(); void dump(int fd, const char* prefix); // This is the trigger of Ai translation bool setSubTranslationLanguage(const std::string& srcLang, const std::string& dstLang); // ISubtitleAiTranslationObserver void onReceiveTranslatedText(const std::shared_ptr& item) override; void onError(const std::string& reason) override; private: class MessageProcess : public android::MessageHandler { public: static const int MSG_PTS_TIME_UPDATED = 0xBB10100; static const int MSG_PTS_TIME_CHECK_SPU = 0xBB10101; static const int MSG_RESET_MESSAGE_QUEUE = 0xCB10100; MessageProcess(Presentation* present, bool isExtSub); virtual ~MessageProcess(); void looperLoop(); void join(); bool notifyMessage(int what); private: std::shared_ptr mLooperThread; Presentation* mPresent; // this use shared_ptr, decouple with sp raw pointer here bool mIsExtSub; bool mRequestThreadExit; void handleMessage(const Message& message); void handleExtSub(const Message& message); void handleStreamSub(const Message& message); std::shared_ptr mLastShowingSpu; sp mLooper; }; int64_t mCurrentPresentRelativeTime = 0; int64_t mStartPresentMonoTimeNs = 0; int64_t mOrigStartTimeModifier = 0; int64_t mStartTimeModifier = 0; bool mRegisteredOnDataCB = false; std::shared_ptr mParser; std::shared_ptr mRender; // for present subtitle. std::list> mEmittedShowingSpu; std::list> mEmittedFaddingSpu; /* this use android sp, so de-couple with shared_ptr */ sp mMsgProcess; // since mMsgProcess is a pointer here // we need a mutex to protect it std::mutex mMutex; std::unique_ptr mAiTranslation; std::mutex mRenderMutex; void send2RenderDisplay(std::shared_ptr spu); void showSubtitleItem(const std::shared_ptr& spu, int type); void hideSubtitleItem(const std::shared_ptr& spu); void removeSubtitleItem(const std::shared_ptr& spu); void resetSubtitleItem(); // There is a latency delay between media sync and display as the MEMC feature in T5M, // the actual delay time is calculated in display module, the latency delay is around: // actual_delay = actual_delay + frc_delay (frc_delay = 3.5 * vpp_vsync) // This function is to get the frc_delay minisecond from /dev/frc, which is used to adjust the // subtitle presentation time. // FRC = Frequency Rate Convert // MEMC = Motion Estimation and Motion Compensation int mLatestFrcTimeMs = 0; // FRC latency time will be stable and fixed in 1 second after playback. bool mIsFrcDelayTimeDoubleConfirmed = false; uint64_t mFrcUpdateClock = 0; void adjustStartTimeByFrcIfNeed(); int getFrcDelayTimeMs(); };