1 /*
2  * Copyright (C) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef HISTREAMER_SUBTITLE_SINK_H
17 #define HISTREAMER_SUBTITLE_SINK_H
18 #include <mutex>
19 #include "common/status.h"
20 #include "meta/meta.h"
21 #include "sink/media_synchronous_sink.h"
22 #include "media_sync_manager.h"
23 #include "buffer/avbuffer_queue.h"
24 #include "buffer/avbuffer_queue_define.h"
25 #include "filter/filter.h"
26 
27 namespace OHOS {
28 namespace Media {
29 using namespace OHOS::Media::Plugins;
30 class SubtitleSink : public std::enable_shared_from_this<SubtitleSink>, public Pipeline::MediaSynchronousSink {
31 public:
32     SubtitleSink();
33     ~SubtitleSink();
34     Status Init(std::shared_ptr<Meta>& meta, const std::shared_ptr<Pipeline::EventReceiver>& receiver);
35     sptr<AVBufferQueueProducer> GetBufferQueueProducer();
36     sptr<AVBufferQueueConsumer> GetBufferQueueConsumer();
37     Status SetParameter(const std::shared_ptr<Meta>& meta);
38     Status GetParameter(std::shared_ptr<Meta>& meta);
39     Status Prepare();
40     Status Start();
41     Status Stop();
42     Status Pause();
43     Status Resume();
44     Status Flush();
45     Status Release();
46     void DrainOutputBuffer(bool flushed);
47     void SetEventReceiver(const std::shared_ptr<Pipeline::EventReceiver>& receiver);
48     Status GetLatency(uint64_t& nanoSec);
49     void SetSyncCenter(std::shared_ptr<Pipeline::MediaSyncManager> syncCenter);
50     int64_t DoSyncWrite(const std::shared_ptr<OHOS::Media::AVBuffer>& buffer) override;
51     void ResetSyncInfo() override;
52     Status SetIsTransitent(bool isTransitent);
53     void NotifySeek();
54     Status SetSpeed(float speed);
55 protected:
56     std::atomic<OHOS::Media::Pipeline::FilterState> state_;
57 private:
58     struct SubtitleInfo {
59         std::string text_;
60         int64_t pts_;
61         int64_t duration_;
62     };
63     void NotifyRender(SubtitleInfo &subtitleInfo);
64     void RenderLoop();
65     uint64_t CalcWaitTime(SubtitleInfo &subtitleInfo);
66     uint32_t ActionToDo(SubtitleInfo &subtitleInfo);
67     void GetTargetSubtitleIndex(int64_t currentTime);
68     Status PrepareInputBufferQueue();
69     int64_t getDurationUsPlayedAtSampleRate(uint32_t numFrames);
70     int64_t GetMediaTime();
71     std::shared_ptr<Pipeline::EventReceiver> playerEventReceiver_;
72     int32_t appUid_{0};
73     int32_t appPid_{0};
74     int64_t numFramesWritten_ {0};
75     int64_t lastReportedClockTime_ {HST_TIME_NONE};
76     int64_t latestBufferPts_ {HST_TIME_NONE};
77     int64_t latestBufferDuration_ {0};
78     const std::string INPUT_BUFFER_QUEUE_NAME = "SubtitleSinkInputBufferQueue";
79     std::shared_ptr<AVBufferQueue> inputBufferQueue_;
80     sptr<AVBufferQueueProducer> inputBufferQueueProducer_;
81     sptr<AVBufferQueueConsumer> inputBufferQueueConsumer_;
82     bool isTransitent_ {false};
83     std::atomic<bool> isEos_{false};
84     std::unique_ptr<std::thread> readThread_ = nullptr;
85     std::mutex mutex_;
86     std::condition_variable updateCond_;
87     std::shared_ptr<AVBuffer> filledOutputBuffer_;
88     std::atomic<bool> isPaused_{false};
89     std::atomic<bool> isThreadExit_{false};
90     std::atomic<bool> shouldUpdate_{false};
91     float speed_ = 1.0;
92     enum SubtitleBufferState : uint32_t {
93         WAIT,
94         SHOW,
95         DROP,
96     };
97     std::vector<SubtitleInfo> subtitleInfoVec_;
98     uint32_t currentInfoIndex_ = 0;
99     std::atomic<bool> isFlush_ = false;
100     std::vector<std::shared_ptr<AVBuffer>> inputBufferVector_;
101 };
102 }
103 }
104 
105 #endif // HISTREAMER_AUDIO_SINK_H
106