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