1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
3 */
4 /*
5 * Copyright (C) 2023 Huawei Device Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19 #include "demuxer.h"
20
21 #undef LOG_TAG
22 #define LOG_TAG "Demuxer"
23
~Demuxer()24 Demuxer::~Demuxer()
25 {
26 Release();
27 }
28
Create(SampleInfo & info)29 int32_t Demuxer::Create(SampleInfo &info)
30 {
31 source_ = OH_AVSource_CreateWithFD(info.inputFd, info.inputFileOffset, info.inputFileSize);
32 CHECK_AND_RETURN_RET_LOG(source_ != nullptr, AVCODEC_SAMPLE_ERR_ERROR,
33 "Create demuxer source failed, fd: %{public}d, offset: %{public}" PRId64 ", file size: %{public}" PRId64,
34 info.inputFd, info.inputFileOffset, info.inputFileSize);
35 demuxer_ = OH_AVDemuxer_CreateWithSource(source_);
36 CHECK_AND_RETURN_RET_LOG(demuxer_ != nullptr, AVCODEC_SAMPLE_ERR_ERROR, "Create demuxer failed");
37
38 auto sourceFormat = std::shared_ptr<OH_AVFormat>(OH_AVSource_GetSourceFormat(source_), OH_AVFormat_Destroy);
39 CHECK_AND_RETURN_RET_LOG(sourceFormat != nullptr, AVCODEC_SAMPLE_ERR_ERROR, "Get source format failed");
40
41 int32_t ret = GetTrackInfo(sourceFormat, info);
42 CHECK_AND_RETURN_RET_LOG(ret == AVCODEC_SAMPLE_ERR_OK, AVCODEC_SAMPLE_ERR_ERROR, "Get video track info failed");
43
44 return AVCODEC_SAMPLE_ERR_OK;
45 }
46
ReadSample(int32_t trackId,OH_AVBuffer * buffer,OH_AVCodecBufferAttr & attr)47 int32_t Demuxer::ReadSample(int32_t trackId, OH_AVBuffer *buffer, OH_AVCodecBufferAttr &attr)
48 {
49 CHECK_AND_RETURN_RET_LOG(demuxer_ != nullptr, AVCODEC_SAMPLE_ERR_ERROR, "Demuxer is null");
50 int32_t ret = OH_AVDemuxer_ReadSampleBuffer(demuxer_, trackId, buffer);
51 CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERR_ERROR, "Read sample failed");
52 ret = OH_AVBuffer_GetBufferAttr(buffer, &attr);
53 CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERR_ERROR, "GetBufferAttr failed");
54 return AVCODEC_SAMPLE_ERR_OK;
55 }
56
Release()57 int32_t Demuxer::Release()
58 {
59 AVCODEC_SAMPLE_LOGI("====== Demuxer::Release ======");
60 if (demuxer_ != nullptr) {
61 OH_AVDemuxer_Destroy(demuxer_);
62 demuxer_ = nullptr;
63 }
64 if (source_ != nullptr) {
65 OH_AVSource_Destroy(source_);
66 source_ = nullptr;
67 }
68 return AVCODEC_SAMPLE_ERR_OK;
69 }
70
GetTrackInfo(std::shared_ptr<OH_AVFormat> sourceFormat,SampleInfo & info)71 int32_t Demuxer::GetTrackInfo(std::shared_ptr<OH_AVFormat> sourceFormat, SampleInfo &info)
72 {
73 int32_t trackCount = 0;
74 OH_AVFormat_GetIntValue(sourceFormat.get(), OH_MD_KEY_TRACK_COUNT, &trackCount);
75 OH_AVFormat_GetLongValue(sourceFormat.get(), OH_MD_KEY_DURATION, &info.duration);
76 for (int32_t index = 0; index < trackCount; index++) {
77 int trackType = -1;
78 auto trackFormat =
79 std::shared_ptr<OH_AVFormat>(OH_AVSource_GetTrackFormat(source_, index), OH_AVFormat_Destroy);
80 OH_AVFormat_GetIntValue(trackFormat.get(), OH_MD_KEY_TRACK_TYPE, &trackType);
81 if (trackType == MEDIA_TYPE_VID) {
82 OH_AVDemuxer_SelectTrackByID(demuxer_, index);
83 OH_AVFormat_GetIntValue(trackFormat.get(), OH_MD_KEY_WIDTH, &info.videoWidth);
84 OH_AVFormat_GetIntValue(trackFormat.get(), OH_MD_KEY_HEIGHT, &info.videoHeight);
85 OH_AVFormat_GetDoubleValue(trackFormat.get(), OH_MD_KEY_FRAME_RATE, &info.frameRate);
86 OH_AVFormat_GetLongValue(trackFormat.get(), OH_MD_KEY_BITRATE, &info.bitrate);
87 OH_AVFormat_GetIntValue(trackFormat.get(), OH_MD_KEY_ROTATION, &info.rotation);
88
89 char *videoCodecMime;
90 OH_AVFormat_GetStringValue(trackFormat.get(),
91 OH_MD_KEY_CODEC_MIME, const_cast<char const **>(&videoCodecMime));
92 info.videoCodecMime = videoCodecMime;
93 OH_AVFormat_GetIntValue(trackFormat.get(), OH_MD_KEY_PROFILE, &info.hevcProfile);
94 videoTrackId_ = index;
95 AVCODEC_SAMPLE_LOGI("%{public}d*%{public}d, %{public}.1ffps, %{public}" PRId64 "kbps", info.videoWidth,
96 info.videoHeight, info.frameRate, info.bitrate / 1024);
97 } else if (trackType == MEDIA_TYPE_AUD) {
98 OH_AVDemuxer_SelectTrackByID(demuxer_, index);
99 OH_AVFormat_GetIntValue(trackFormat.get(), OH_MD_KEY_AUDIO_SAMPLE_FORMAT, &info.audioSampleForamt);
100 OH_AVFormat_GetIntValue(trackFormat.get(), OH_MD_KEY_AUD_CHANNEL_COUNT, &info.audioChannelCount);
101 OH_AVFormat_GetLongValue(trackFormat.get(), OH_MD_KEY_CHANNEL_LAYOUT, &info.audioChannelLayout);
102 OH_AVFormat_GetIntValue(trackFormat.get(), OH_MD_KEY_AUD_SAMPLE_RATE, &info.audioSampleRate);
103 uint8_t *addr = nullptr;
104 OH_AVFormat_GetBuffer(trackFormat.get(), "codec_config", &addr, &info.audioCodecSize);
105
106 if (addr != nullptr && info.audioCodecConfig != nullptr) {
107 delete[] info.audioCodecConfig;
108 } else if (addr != nullptr) {
109 info.audioCodecConfig = new uint8_t[info.audioCodecSize];
110 std::memcpy(info.audioCodecConfig, addr, info.audioCodecSize);
111 }
112 char *audioCodecMime;
113 OH_AVFormat_GetStringValue(trackFormat.get(),
114 OH_MD_KEY_CODEC_MIME, const_cast<char const **>(&audioCodecMime));
115 info.audioCodecMime = audioCodecMime;
116 audioTrackId_ = index;
117 AVCODEC_SAMPLE_LOGI("Mime: %{public}s", audioCodecMime);
118 AVCODEC_SAMPLE_LOGI("audioMime:%{public}s sampleForamt:%{public}d "
119 "sampleRate:%{public}d channelCount:%{public}d channelLayout:%{public}d", info.audioCodecMime.c_str(),
120 info.audioSampleForamt, info.audioSampleRate, info.audioChannelCount, info.audioChannelLayout);
121 }
122 }
123
124 return AVCODEC_SAMPLE_ERR_OK;
125 }
126
GetVideoTrackId()127 int32_t Demuxer::GetVideoTrackId()
128 {
129 return videoTrackId_;
130 }
GetAudioTrackId()131 int32_t Demuxer::GetAudioTrackId()
132 {
133 return audioTrackId_;
134 }
135
Seek(int64_t millisecond,OH_AVSeekMode mode)136 int32_t Demuxer::Seek(int64_t millisecond, OH_AVSeekMode mode)
137 {
138 int32_t ret = OH_AVDemuxer_SeekToTime(demuxer_, millisecond, mode);
139 CHECK_AND_RETURN_RET_LOG(ret == AV_ERR_OK, AVCODEC_SAMPLE_ERR_ERROR, "seek failed");
140 return AVCODEC_SAMPLE_ERR_OK;
141 }
142