• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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