1 /*
2  * Copyright (c) 2024-2024 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 #define HST_LOG_TAG "MediaDemuxer"
17 #define MEDIA_ATOMIC_ABILITY
18 
19 #include "media_demuxer.h"
20 
21 #include <algorithm>
22 #include <memory>
23 #include <map>
24 
25 #include "avcodec_common.h"
26 #include "avcodec_trace.h"
27 #include "cpp_ext/type_traits_ext.h"
28 #include "buffer/avallocator.h"
29 #include "common/event.h"
30 #include "common/log.h"
31 #include "hisysevent.h"
32 #include "meta/media_types.h"
33 #include "meta/meta.h"
34 #include "osal/utils/dump_buffer.h"
35 #include "plugin/plugin_info.h"
36 #include "plugin/plugin_buffer.h"
37 #include "source/source.h"
38 #include "stream_demuxer.h"
39 #include "media_core.h"
40 #include "osal/utils/dump_buffer.h"
41 #include "demuxer_plugin_manager.h"
42 
43 namespace {
44 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_DEMUXER, "MediaDemuxer" };
45 } // namespace
46 
47 namespace OHOS {
48 namespace Media {
49 constexpr int64_t MAX_PTS_DIFFER_THRESHOLD_US = 10000000; // The maximum difference between Segment 10s.
50 constexpr int64_t INVALID_PTS_DATA = -1; // The invalid pts data -1.
51 
HandleAutoMaintainPts(uint32_t trackId,std::shared_ptr<AVBuffer> sample)52 Status MediaDemuxer::HandleAutoMaintainPts(uint32_t trackId, std::shared_ptr<AVBuffer> sample)
53 {
54     if (!isAutoMaintainPts_) {
55         return Status::OK;
56     }
57     int64_t curPacketPts = sample->pts_;
58     std::shared_ptr<MaintainBaseInfo> baseInfo = maintainBaseInfos_[trackId];
59     if (baseInfo == nullptr) {
60         MEDIA_LOG_E("BaseInfo is nullptr, track " PUBLIC_LOG_U32, trackId);
61         return Status::OK;
62     }
63     int64_t diff = 0;
64     diff = curPacketPts - baseInfo->lastPts;
65     baseInfo->lastPts = curPacketPts;
66     if (diff < 0) {
67         diff = 0 - diff;
68     }
69     if (baseInfo->segmentOffset == INVALID_PTS_DATA || diff > MAX_PTS_DIFFER_THRESHOLD_US) {
70         int64_t offset = static_cast<int64_t>(source_->GetSegmentOffset());
71         if (baseInfo->segmentOffset != offset) {
72             baseInfo->segmentOffset = offset;
73             baseInfo->basePts = curPacketPts;
74         }
75     }
76     sample->pts_ = baseInfo->segmentOffset + curPacketPts - baseInfo->basePts;
77     MEDIA_LOG_D("Success, track:" PUBLIC_LOG_U32 ", orgPts:"
78         PUBLIC_LOG_D64 ", pts:" PUBLIC_LOG_D64 ", basePts:" PUBLIC_LOG_D64, trackId,
79         curPacketPts, sample->pts_, baseInfo->basePts);
80     return Status::OK;
81 }
82 
InitPtsInfo()83 Status MediaDemuxer::InitPtsInfo()
84 {
85     if (source_ == nullptr || !source_->GetHLSDiscontinuity()) {
86         return Status::OK;
87     }
88     MEDIA_LOG_I("Enable hls disContinuity auto maintain pts");
89     isAutoMaintainPts_ = true;
90     AutoLock lock(mapMutex_);
91     for (auto it = bufferQueueMap_.begin(); it != bufferQueueMap_.end(); it++) {
92         uint32_t trackId = it->first;
93         if (maintainBaseInfos_[trackId] == nullptr) {
94             maintainBaseInfos_[trackId] = std::make_shared<MaintainBaseInfo>();
95         }
96         maintainBaseInfos_[trackId]->segmentOffset = INVALID_PTS_DATA;
97         maintainBaseInfos_[trackId]->basePts = INVALID_PTS_DATA;
98     }
99     return Status::OK;
100 }
101 
102 } // namespace Media
103 } // namespace OHOS
104