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 #include "reader.h"
17
18 #include "track_factory.h"
19
20 namespace OHOS {
21 namespace CameraStandard {
22 namespace DeferredProcessing {
23 namespace {
24 constexpr int32_t DEFAULT_INT_VAL = 0;
25 constexpr double DEFAULT_DOUBLE_VAL = 0.0;
26 constexpr int32_t FPS_30 = 30;
27 constexpr int32_t FPS_60 = 60;
28 constexpr double FACTOR = 1.1;
29 }
30
~Reader()31 Reader::~Reader()
32 {
33 tracks_.clear();
34 }
35
Create(int32_t inputFd)36 MediaManagerError Reader::Create(int32_t inputFd)
37 {
38 DP_DEBUG_LOG("entered.");
39 DP_CHECK_ERROR_RETURN_RET_LOG(inputFd == INVALID_FD, ERROR_FAIL, "inputFd is invalid: %{public}d.", inputFd);
40
41 auto off = lseek(inputFd, DEFAULT_OFFSET, SEEK_END);
42 DP_CHECK_ERROR_RETURN_RET_LOG(off == static_cast<off_t>(ERROR_FAIL), ERROR_FAIL, "Reader lseek failed.");
43 source_ = MediaAVCodec::AVSourceFactory::CreateWithFD(inputFd, DEFAULT_OFFSET, off);
44 DP_CHECK_ERROR_RETURN_RET_LOG(source_ == nullptr, ERROR_FAIL, "Create avsource failed.");
45
46 auto ret = GetSourceFormat();
47 DP_CHECK_ERROR_RETURN_RET_LOG(ret != OK, ERROR_FAIL, "Get avsource format failed.");
48
49 ret = GetUserMeta();
50 DP_CHECK_ERROR_RETURN_RET_LOG(ret != OK, ERROR_FAIL, "Get user format failed.");
51
52 ret = InitTracksAndDemuxer();
53 DP_CHECK_ERROR_RETURN_RET_LOG(ret != OK, ERROR_FAIL, "Init tracks and demuxer failed.");
54 return OK;
55 }
56
GetSourceFormat()57 MediaManagerError Reader::GetSourceFormat()
58 {
59 DP_DEBUG_LOG("entered.");
60 DP_CHECK_ERROR_RETURN_RET_LOG(source_ == nullptr, ERROR_FAIL, "AVSource is nullptr.");
61
62 Format sourceFormat;
63 auto ret = source_->GetSourceFormat(sourceFormat);
64 DP_CHECK_ERROR_RETURN_RET_LOG(ret != static_cast<int32_t>(OK), ERROR_FAIL, "Get avsource format failed.");
65 sourceFormat_ = std::make_shared<Format>(sourceFormat);
66 return OK;
67 }
68
GetUserMeta()69 MediaManagerError Reader::GetUserMeta()
70 {
71 DP_DEBUG_LOG("entered.");
72 DP_CHECK_ERROR_RETURN_RET_LOG(source_ == nullptr, ERROR_FAIL, "AVSource is nullptr.");
73
74 Format userFormat;
75 auto ret = source_->GetUserMeta(userFormat);
76 DP_CHECK_ERROR_RETURN_RET_LOG(ret != static_cast<int32_t>(OK), ERROR_FAIL, "Get user format failed.");
77 userFormat_ = std::make_shared<Format>(userFormat);
78 return OK;
79 }
80
InitTracksAndDemuxer()81 MediaManagerError Reader::InitTracksAndDemuxer()
82 {
83 DP_DEBUG_LOG("entered.");
84 DP_CHECK_ERROR_RETURN_RET_LOG(!sourceFormat_->GetIntValue(Tag::MEDIA_TRACK_COUNT, trackCount_), ERROR_FAIL,
85 "Get track count failed.");
86
87 for (int32_t index = 0; index < trackCount_; ++index) {
88 auto track = TrackFactory::GetInstance().CreateTrack(source_, index);
89 DP_LOOP_CONTINUE_LOG(track == nullptr, "Track index: %{public}d is nullptr.", index);
90 tracks_.emplace(std::pair(track->GetType(), track));
91 }
92 DP_DEBUG_LOG("TrackCount num: %{public}d, trackMap size: %{public}d",
93 trackCount_, static_cast<int32_t>(tracks_.size()));
94 inputDemuxer_ = std::make_shared<Demuxer>();
95 auto ret = inputDemuxer_->Create(source_, tracks_);
96 DP_CHECK_ERROR_RETURN_RET_LOG(ret != OK, ERROR_FAIL, "Audio demuxer init failed.");
97 return OK;
98 }
99
Read(Media::Plugins::MediaType trackType,std::shared_ptr<AVBuffer> & sample)100 MediaManagerError Reader::Read(Media::Plugins::MediaType trackType, std::shared_ptr<AVBuffer>& sample)
101 {
102 DP_CHECK_ERROR_RETURN_RET_LOG(inputDemuxer_ == nullptr, ERROR_FAIL, "Demuxer is nullptr.");
103 auto ret = inputDemuxer_->ReadStream(trackType, sample);
104 DP_CHECK_ERROR_RETURN_RET_LOG(ret == ERROR_FAIL, ERROR_FAIL,
105 "Read sample failed, track type: %{public}d", trackType);
106 DP_CHECK_RETURN_RET_LOG(ret == EOS, EOS, "Reading finished.");
107 return ret;
108 }
109
GetMediaInfo(std::shared_ptr<MediaInfo> & mediaInfo)110 MediaManagerError Reader::GetMediaInfo(std::shared_ptr<MediaInfo>& mediaInfo)
111 {
112 GetSourceMediaInfo(mediaInfo);
113 mediaInfo->streamCount = trackCount_;
114
115 auto it = tracks_.find(Media::Plugins::MediaType::VIDEO);
116 DP_CHECK_ERROR_RETURN_RET_LOG(it == tracks_.end(), ERROR_FAIL, "Not find video track.");
117
118 auto videoFormat = it->second->GetFormat();
119 GetTrackMediaInfo(videoFormat, mediaInfo);
120 return OK;
121 }
122
Reset(int64_t resetPts)123 MediaManagerError Reader::Reset(int64_t resetPts)
124 {
125 DP_DEBUG_LOG("entered.");
126 DP_CHECK_ERROR_RETURN_RET_LOG(resetPts < 0, ERROR_FAIL, "Invalid reset pts.");
127 DP_CHECK_ERROR_RETURN_RET_LOG(inputDemuxer_ == nullptr, ERROR_FAIL, "Demuxer is null.");
128
129 auto ret = inputDemuxer_->SeekToTime(resetPts);
130 DP_CHECK_ERROR_RETURN_RET_LOG(ret != OK, ERROR_FAIL, "Reset pts failed.");
131 return OK;
132 }
133
GetSourceMediaInfo(std::shared_ptr<MediaInfo> & mediaInfo) const134 void Reader::GetSourceMediaInfo(std::shared_ptr<MediaInfo>& mediaInfo) const
135 {
136 CheckAndGetValue(sourceFormat_, Tag::MEDIA_CREATION_TIME, mediaInfo->creationTime);
137 CheckAndGetValue(sourceFormat_, Tag::MEDIA_DURATION, mediaInfo->codecInfo.duration);
138 CheckAndGetValue(sourceFormat_, Tag::MEDIA_LATITUDE, mediaInfo->latitude);
139 CheckAndGetValue(sourceFormat_, Tag::MEDIA_LONGITUDE, mediaInfo->longitude);
140 CheckAndGetValue(userFormat_, LIVE_PHOTO_COVERTIME, mediaInfo->livePhotoCovertime);
141 DP_INFO_LOG("MediaInfo creationTime: %{public}s, duration: %{public}" PRId64 ", livePhotoCovertime: %{public}f",
142 mediaInfo->creationTime.c_str(), mediaInfo->codecInfo.duration, mediaInfo->livePhotoCovertime);
143 }
144
GetTrackMediaInfo(const TrackFormat & trackFormat,std::shared_ptr<MediaInfo> & mediaInfo) const145 MediaManagerError Reader::GetTrackMediaInfo(const TrackFormat& trackFormat,
146 std::shared_ptr<MediaInfo>& mediaInfo) const
147 {
148 auto& format = trackFormat.format;
149 CheckAndGetValue(format, Tag::MIME_TYPE, mediaInfo->codecInfo.mimeType);
150 CheckAndGetValue(format, Tag::MEDIA_PROFILE, mediaInfo->codecInfo.profile);
151 CheckAndGetValue(format, Tag::MEDIA_LEVEL, mediaInfo->codecInfo.level);
152 CheckAndGetValue(format, Tag::VIDEO_WIDTH, mediaInfo->codecInfo.width);
153 CheckAndGetValue(format, Tag::VIDEO_HEIGHT, mediaInfo->codecInfo.height);
154 CheckAndGetValue(format, Tag::VIDEO_ROTATION, mediaInfo->codecInfo.rotation);
155 CheckAndGetValue(format, Tag::VIDEO_ENCODE_BITRATE_MODE, mediaInfo->codecInfo.bitMode);
156 CheckAndGetValue(format, Tag::MEDIA_BITRATE, mediaInfo->codecInfo.bitRate);
157
158 int32_t intVal {DEFAULT_INT_VAL};
159 if (CheckAndGetValue(format, Tag::VIDEO_COLOR_RANGE, intVal)) {
160 mediaInfo->codecInfo.colorRange = static_cast<ColorRange>(intVal);
161 }
162 if (CheckAndGetValue(format, Tag::VIDEO_PIXEL_FORMAT, intVal)) {
163 mediaInfo->codecInfo.pixelFormat = static_cast<Media::Plugins::VideoPixelFormat>(intVal);
164 }
165 if (CheckAndGetValue(format, Tag::VIDEO_COLOR_PRIMARIES, intVal)) {
166 mediaInfo->codecInfo.colorPrimary = static_cast<Media::Plugins::ColorPrimary>(intVal);
167 }
168 if (CheckAndGetValue(format, Tag::VIDEO_COLOR_TRC, intVal)) {
169 mediaInfo->codecInfo.colorTransferCharacter = static_cast<Media::Plugins::TransferCharacteristic>(intVal);
170 }
171 if (CheckAndGetValue(format, Tag::VIDEO_IS_HDR_VIVID, intVal)) {
172 mediaInfo->codecInfo.isHdrvivid = static_cast<bool>(intVal);
173 }
174
175 double doubleVal {DEFAULT_DOUBLE_VAL};
176 if (CheckAndGetValue(format, Tag::VIDEO_FRAME_RATE, doubleVal)) {
177 mediaInfo->codecInfo.fps = FixFPS(doubleVal);
178 }
179
180 DP_INFO_LOG("TrackMediaInfo colorRange: %{public}d, pixelFormat: %{public}d, colorPrimary: %{public}d, "
181 "transfer: %{public}d, profile: %{public}d, level: %{public}d, bitRate: %{public}" PRId64 ", "
182 "fps: %{public}d, rotation: %{public}d, mime: %{public}s, isHdrvivid: %{public}d",
183 mediaInfo->codecInfo.colorRange, mediaInfo->codecInfo.pixelFormat, mediaInfo->codecInfo.colorPrimary,
184 mediaInfo->codecInfo.colorTransferCharacter, mediaInfo->codecInfo.profile, mediaInfo->codecInfo.level,
185 mediaInfo->codecInfo.bitRate, mediaInfo->codecInfo.fps, mediaInfo->codecInfo.rotation,
186 mediaInfo->codecInfo.mimeType.c_str(), mediaInfo->codecInfo.isHdrvivid);
187 return OK;
188 }
189
FixFPS(const double fps)190 inline int32_t Reader::FixFPS(const double fps)
191 {
192 return fps < static_cast<double>(FPS_30) * FACTOR ? FPS_30 : FPS_60;
193 }
194 } // namespace DeferredProcessing
195 } // namespace CameraStandard
196 } // namespace OHOS
197