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