1da853ecaSopenharmony_ci/*
2da853ecaSopenharmony_ci * Copyright (C) 2023 Huawei Device Co., Ltd.
3da853ecaSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4da853ecaSopenharmony_ci * you may not use this file except in compliance with the License.
5da853ecaSopenharmony_ci * You may obtain a copy of the License at
6da853ecaSopenharmony_ci *
7da853ecaSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8da853ecaSopenharmony_ci *
9da853ecaSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10da853ecaSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11da853ecaSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12da853ecaSopenharmony_ci * See the License for the specific language governing permissions and
13da853ecaSopenharmony_ci * limitations under the License.
14da853ecaSopenharmony_ci */
15da853ecaSopenharmony_ci
16da853ecaSopenharmony_ci#include "avdemuxer_impl.h"
17da853ecaSopenharmony_ci#include <fcntl.h>
18da853ecaSopenharmony_ci#include <unistd.h>
19da853ecaSopenharmony_ci#include <functional>
20da853ecaSopenharmony_ci#include <sys/types.h>
21da853ecaSopenharmony_ci#include "securec.h"
22da853ecaSopenharmony_ci#include "avcodec_log.h"
23da853ecaSopenharmony_ci#include "buffer/avsharedmemorybase.h"
24da853ecaSopenharmony_ci#include "avcodec_trace.h"
25da853ecaSopenharmony_ci#include "meta/media_types.h"
26da853ecaSopenharmony_ci#include "avcodec_errors.h"
27da853ecaSopenharmony_ci
28da853ecaSopenharmony_cinamespace {
29da853ecaSopenharmony_ci    constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_DEMUXER, "AVDemuxerImpl"};
30da853ecaSopenharmony_ci}
31da853ecaSopenharmony_ci
32da853ecaSopenharmony_cinamespace OHOS {
33da853ecaSopenharmony_cinamespace MediaAVCodec {
34da853ecaSopenharmony_ciusing namespace Media;
35da853ecaSopenharmony_ciusing namespace Media::Plugins;
36da853ecaSopenharmony_cistd::shared_ptr<AVDemuxer> AVDemuxerFactory::CreateWithSource(std::shared_ptr<AVSource> source)
37da853ecaSopenharmony_ci{
38da853ecaSopenharmony_ci    AVCODEC_SYNC_TRACE;
39da853ecaSopenharmony_ci
40da853ecaSopenharmony_ci    std::shared_ptr<AVDemuxerImpl> demuxerImpl = std::make_shared<AVDemuxerImpl>();
41da853ecaSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(demuxerImpl != nullptr, nullptr, "New avdemuxer failed");
42da853ecaSopenharmony_ci
43da853ecaSopenharmony_ci    int32_t ret = demuxerImpl->Init(source);
44da853ecaSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(ret == AVCS_ERR_OK, nullptr, "Init avdemuxer failed");
45da853ecaSopenharmony_ci
46da853ecaSopenharmony_ci    return demuxerImpl;
47da853ecaSopenharmony_ci}
48da853ecaSopenharmony_ci
49da853ecaSopenharmony_ciint32_t AVDemuxerImpl::Init(std::shared_ptr<AVSource> source)
50da853ecaSopenharmony_ci{
51da853ecaSopenharmony_ci    AVCODEC_SYNC_TRACE;
52da853ecaSopenharmony_ci
53da853ecaSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(source != nullptr, AVCS_ERR_INVALID_VAL, "AVSource is nullptr");
54da853ecaSopenharmony_ci    AVCODEC_LOGD("Init avdemuxer for %{private}s", source->sourceUri.c_str());
55da853ecaSopenharmony_ci
56da853ecaSopenharmony_ci    mediaDemuxer_ = source->mediaDemuxer;
57da853ecaSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(mediaDemuxer_ != nullptr, AVCS_ERR_INVALID_OPERATION, "Init mediaDemuxer failed");
58da853ecaSopenharmony_ci    return AVCS_ERR_OK;
59da853ecaSopenharmony_ci}
60da853ecaSopenharmony_ci
61da853ecaSopenharmony_ciAVDemuxerImpl::AVDemuxerImpl()
62da853ecaSopenharmony_ci{
63da853ecaSopenharmony_ci    AVCODEC_LOGD("Create instances 0x%{public}06" PRIXPTR, FAKE_POINTER(this));
64da853ecaSopenharmony_ci}
65da853ecaSopenharmony_ci
66da853ecaSopenharmony_ciAVDemuxerImpl::~AVDemuxerImpl()
67da853ecaSopenharmony_ci{
68da853ecaSopenharmony_ci    if (mediaDemuxer_ != nullptr) {
69da853ecaSopenharmony_ci        mediaDemuxer_ = nullptr;
70da853ecaSopenharmony_ci    }
71da853ecaSopenharmony_ci    AVCODEC_LOGD("Destroy instances 0x%{public}06" PRIXPTR, FAKE_POINTER(this));
72da853ecaSopenharmony_ci}
73da853ecaSopenharmony_ci
74da853ecaSopenharmony_ciint32_t AVDemuxerImpl::SelectTrackByID(uint32_t trackIndex)
75da853ecaSopenharmony_ci{
76da853ecaSopenharmony_ci    AVCODEC_SYNC_TRACE;
77da853ecaSopenharmony_ci
78da853ecaSopenharmony_ci    AVCODEC_LOGD("Select track %{public}u", trackIndex);
79da853ecaSopenharmony_ci
80da853ecaSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(mediaDemuxer_ != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist");
81da853ecaSopenharmony_ci    return StatusToAVCodecServiceErrCode(mediaDemuxer_->SelectTrack(trackIndex));
82da853ecaSopenharmony_ci}
83da853ecaSopenharmony_ci
84da853ecaSopenharmony_ciint32_t AVDemuxerImpl::UnselectTrackByID(uint32_t trackIndex)
85da853ecaSopenharmony_ci{
86da853ecaSopenharmony_ci    AVCODEC_SYNC_TRACE;
87da853ecaSopenharmony_ci
88da853ecaSopenharmony_ci    AVCODEC_LOGD("Unselect track %{public}u", trackIndex);
89da853ecaSopenharmony_ci
90da853ecaSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(mediaDemuxer_ != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist");
91da853ecaSopenharmony_ci    return StatusToAVCodecServiceErrCode(mediaDemuxer_->UnselectTrack(trackIndex));
92da853ecaSopenharmony_ci}
93da853ecaSopenharmony_ci
94da853ecaSopenharmony_ciint32_t AVDemuxerImpl::ReadSampleBuffer(uint32_t trackIndex, std::shared_ptr<AVBuffer> sample)
95da853ecaSopenharmony_ci{
96da853ecaSopenharmony_ci    AVCODEC_SYNC_TRACE;
97da853ecaSopenharmony_ci
98da853ecaSopenharmony_ci    AVCODEC_LOGD("ReadSampleBuffer for track %{public}u", trackIndex);
99da853ecaSopenharmony_ci
100da853ecaSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(mediaDemuxer_ != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist");
101da853ecaSopenharmony_ci
102da853ecaSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(sample != nullptr && sample->memory_ != nullptr, AVCS_ERR_INVALID_VAL,
103da853ecaSopenharmony_ci        "Sample buffer is nullptr");
104da853ecaSopenharmony_ci
105da853ecaSopenharmony_ci    return StatusToAVCodecServiceErrCode(mediaDemuxer_->ReadSample(trackIndex, sample));
106da853ecaSopenharmony_ci}
107da853ecaSopenharmony_ci
108da853ecaSopenharmony_ciint32_t AVDemuxerImpl::ReadSample(uint32_t trackIndex, std::shared_ptr<AVSharedMemory> sample,
109da853ecaSopenharmony_ci    AVCodecBufferInfo &info, uint32_t &flag)
110da853ecaSopenharmony_ci{
111da853ecaSopenharmony_ci    AVCODEC_SYNC_TRACE;
112da853ecaSopenharmony_ci
113da853ecaSopenharmony_ci    AVCODEC_LOGD("ReadSample for track %{public}u", trackIndex);
114da853ecaSopenharmony_ci
115da853ecaSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(mediaDemuxer_ != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist");
116da853ecaSopenharmony_ci
117da853ecaSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(sample != nullptr, AVCS_ERR_INVALID_VAL, "Sample buffer is nullptr");
118da853ecaSopenharmony_ci
119da853ecaSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(sample->GetSize() > 0, AVCS_ERR_INVALID_VAL, "Sample size must be greater than 0");
120da853ecaSopenharmony_ci
121da853ecaSopenharmony_ci    std::shared_ptr<AVBuffer> buffer = AVBuffer::CreateAVBuffer(
122da853ecaSopenharmony_ci        sample->GetBase(), sample->GetSize(), sample->GetSize());
123da853ecaSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(buffer != nullptr && buffer->memory_ != nullptr, AVCS_ERR_INVALID_VAL,
124da853ecaSopenharmony_ci        "Buffer is nullptr");
125da853ecaSopenharmony_ci    Status ret = mediaDemuxer_->ReadSample(trackIndex, buffer);
126da853ecaSopenharmony_ci
127da853ecaSopenharmony_ci    info.presentationTimeUs = buffer->pts_;
128da853ecaSopenharmony_ci    info.size = buffer->memory_->GetSize();
129da853ecaSopenharmony_ci    info.offset = 0;
130da853ecaSopenharmony_ci    flag = buffer->flag_;
131da853ecaSopenharmony_ci    return StatusToAVCodecServiceErrCode(ret);
132da853ecaSopenharmony_ci}
133da853ecaSopenharmony_ci
134da853ecaSopenharmony_ciint32_t AVDemuxerImpl::ReadSample(uint32_t trackIndex, std::shared_ptr<AVSharedMemory> sample,
135da853ecaSopenharmony_ci    AVCodecBufferInfo &info, AVCodecBufferFlag &flag)
136da853ecaSopenharmony_ci{
137da853ecaSopenharmony_ci    AVCODEC_SYNC_TRACE;
138da853ecaSopenharmony_ci
139da853ecaSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(sample != nullptr, AVCS_ERR_INVALID_VAL, "Sample buffer is nullptr");
140da853ecaSopenharmony_ci    std::shared_ptr<AVBuffer> buffer = AVBuffer::CreateAVBuffer(
141da853ecaSopenharmony_ci        sample->GetBase(), sample->GetSize(), sample->GetSize());
142da853ecaSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(buffer != nullptr && buffer->memory_ != nullptr, AVCS_ERR_INVALID_VAL,
143da853ecaSopenharmony_ci        "Buffer is nullptr");
144da853ecaSopenharmony_ci
145da853ecaSopenharmony_ci    int32_t ret = ReadSampleBuffer(trackIndex, buffer);
146da853ecaSopenharmony_ci    info.presentationTimeUs = buffer->pts_;
147da853ecaSopenharmony_ci    info.size = buffer->memory_->GetSize();
148da853ecaSopenharmony_ci    info.offset = 0;
149da853ecaSopenharmony_ci
150da853ecaSopenharmony_ci    AVBufferFlag innerFlag = AVBufferFlag::NONE;
151da853ecaSopenharmony_ci    if (buffer->flag_ & (uint32_t)(AVBufferFlag::SYNC_FRAME)) {
152da853ecaSopenharmony_ci        innerFlag = AVBufferFlag::SYNC_FRAME;
153da853ecaSopenharmony_ci    } else if (buffer->flag_ & (uint32_t)(AVBufferFlag::EOS)) {
154da853ecaSopenharmony_ci        innerFlag = AVBufferFlag::EOS;
155da853ecaSopenharmony_ci    }
156da853ecaSopenharmony_ci    flag = static_cast<AVCodecBufferFlag>(innerFlag);
157da853ecaSopenharmony_ci    return ret;
158da853ecaSopenharmony_ci}
159da853ecaSopenharmony_ci
160da853ecaSopenharmony_ciint32_t AVDemuxerImpl::SeekToTime(int64_t millisecond, SeekMode mode)
161da853ecaSopenharmony_ci{
162da853ecaSopenharmony_ci    AVCODEC_SYNC_TRACE;
163da853ecaSopenharmony_ci
164da853ecaSopenharmony_ci    AVCODEC_LOGD("Seek to time: millisecond=%{public}" PRId64 "; mode=%{public}d", millisecond, mode);
165da853ecaSopenharmony_ci
166da853ecaSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(mediaDemuxer_ != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist");
167da853ecaSopenharmony_ci
168da853ecaSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(millisecond >= 0, AVCS_ERR_INVALID_VAL, "Millisecond is negative");
169da853ecaSopenharmony_ci
170da853ecaSopenharmony_ci    int64_t realTime = 0;
171da853ecaSopenharmony_ci    return StatusToAVCodecServiceErrCode(mediaDemuxer_->SeekTo(millisecond, mode, realTime));
172da853ecaSopenharmony_ci}
173da853ecaSopenharmony_ci
174da853ecaSopenharmony_ciint32_t AVDemuxerImpl::SetCallback(const std::shared_ptr<AVDemuxerCallback> &callback)
175da853ecaSopenharmony_ci{
176da853ecaSopenharmony_ci    AVCODEC_SYNC_TRACE;
177da853ecaSopenharmony_ci    AVCODEC_LOGD("AVDemuxer::SetCallback");
178da853ecaSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(mediaDemuxer_ != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist");
179da853ecaSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(callback != nullptr, AVCS_ERR_INVALID_VAL, "Callback is nullptr");
180da853ecaSopenharmony_ci    mediaDemuxer_->SetDrmCallback(callback);
181da853ecaSopenharmony_ci    return AVCS_ERR_OK;
182da853ecaSopenharmony_ci}
183da853ecaSopenharmony_ci
184da853ecaSopenharmony_ciint32_t AVDemuxerImpl::GetMediaKeySystemInfo(std::multimap<std::string, std::vector<uint8_t>> &infos)
185da853ecaSopenharmony_ci{
186da853ecaSopenharmony_ci    AVCODEC_SYNC_TRACE;
187da853ecaSopenharmony_ci    AVCODEC_LOGD("AVDemuxer::GetMediaKeySystemInfo");
188da853ecaSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(mediaDemuxer_ != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist");
189da853ecaSopenharmony_ci    mediaDemuxer_->GetMediaKeySystemInfo(infos);
190da853ecaSopenharmony_ci    return AVCS_ERR_OK;
191da853ecaSopenharmony_ci}
192da853ecaSopenharmony_ci
193da853ecaSopenharmony_ciint32_t AVDemuxerImpl::StartReferenceParser(int64_t startTimeMs)
194da853ecaSopenharmony_ci{
195da853ecaSopenharmony_ci    AVCODEC_SYNC_TRACE;
196da853ecaSopenharmony_ci    AVCODEC_LOGD("AVDemuxer::StartReferenceParser");
197da853ecaSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(mediaDemuxer_ != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist");
198da853ecaSopenharmony_ci    return StatusToAVCodecServiceErrCode(mediaDemuxer_->StartReferenceParser(startTimeMs));
199da853ecaSopenharmony_ci}
200da853ecaSopenharmony_ci
201da853ecaSopenharmony_ciint32_t AVDemuxerImpl::GetFrameLayerInfo(std::shared_ptr<AVBuffer> videoSample, FrameLayerInfo &frameLayerInfo)
202da853ecaSopenharmony_ci{
203da853ecaSopenharmony_ci    AVCODEC_SYNC_TRACE;
204da853ecaSopenharmony_ci    AVCODEC_LOGD("AVDemuxer::GetFrameLayerInfo");
205da853ecaSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(mediaDemuxer_ != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist");
206da853ecaSopenharmony_ci    return StatusToAVCodecServiceErrCode(mediaDemuxer_->GetFrameLayerInfo(videoSample, frameLayerInfo));
207da853ecaSopenharmony_ci}
208da853ecaSopenharmony_ci
209da853ecaSopenharmony_ciint32_t AVDemuxerImpl::GetGopLayerInfo(uint32_t gopId, GopLayerInfo &gopLayerInfo)
210da853ecaSopenharmony_ci{
211da853ecaSopenharmony_ci    AVCODEC_SYNC_TRACE;
212da853ecaSopenharmony_ci    AVCODEC_LOGD("AVDemuxer::GetGopLayerInfo");
213da853ecaSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(mediaDemuxer_ != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist");
214da853ecaSopenharmony_ci    return StatusToAVCodecServiceErrCode(mediaDemuxer_->GetGopLayerInfo(gopId, gopLayerInfo));
215da853ecaSopenharmony_ci}
216da853ecaSopenharmony_ci
217da853ecaSopenharmony_ciint32_t AVDemuxerImpl::GetIndexByRelativePresentationTimeUs(const uint32_t trackIndex,
218da853ecaSopenharmony_ci    const uint64_t relativePresentationTimeUs, uint32_t &index)
219da853ecaSopenharmony_ci{
220da853ecaSopenharmony_ci    AVCODEC_SYNC_TRACE;
221da853ecaSopenharmony_ci    AVCODEC_LOGD("GetIndexByRelativePresentationTimeUs");
222da853ecaSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(mediaDemuxer_ != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist");
223da853ecaSopenharmony_ci    int32_t ret = StatusToAVCodecServiceErrCode(mediaDemuxer_->GetIndexByRelativePresentationTimeUs(trackIndex,
224da853ecaSopenharmony_ci        relativePresentationTimeUs, index));
225da853ecaSopenharmony_ci    return ret;
226da853ecaSopenharmony_ci}
227da853ecaSopenharmony_ci
228da853ecaSopenharmony_ciint32_t AVDemuxerImpl::GetRelativePresentationTimeUsByIndex(const uint32_t trackIndex,
229da853ecaSopenharmony_ci    const uint32_t index, uint64_t &relativePresentationTimeUs)
230da853ecaSopenharmony_ci{
231da853ecaSopenharmony_ci    AVCODEC_SYNC_TRACE;
232da853ecaSopenharmony_ci    AVCODEC_LOGD("GetRelativePresentationTimeUsByIndex");
233da853ecaSopenharmony_ci    CHECK_AND_RETURN_RET_LOG(mediaDemuxer_ != nullptr, AVCS_ERR_INVALID_OPERATION, "MediaDemuxer does not exist");
234da853ecaSopenharmony_ci    int32_t ret = StatusToAVCodecServiceErrCode(mediaDemuxer_->GetRelativePresentationTimeUsByIndex(trackIndex,
235da853ecaSopenharmony_ci        index, relativePresentationTimeUs));
236da853ecaSopenharmony_ci    return ret;
237da853ecaSopenharmony_ci}
238da853ecaSopenharmony_ci} // namespace MediaAVCodec
239da853ecaSopenharmony_ci} // namespace OHOS