1 /*
2  * Copyright (c) 2021-2021 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 #define HST_LOG_TAG "FfmpegUtils"
17 
18 #include <algorithm>
19 #include <functional>
20 #include <unordered_map>
21 #include "common/log.h"
22 #include "meta/mime_type.h"
23 #include "ffmpeg_utils.h"
24 
25 namespace {
26 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, LOG_DOMAIN_SYSTEM_PLAYER, "HiStreamer" };
27 }
28 
29 #define AV_CODEC_TIME_BASE (static_cast<int64_t>(1))
30 #define AV_CODEC_NSECOND AV_CODEC_TIME_BASE
31 #define AV_CODEC_USECOND (static_cast<int64_t>(1000) * AV_CODEC_NSECOND)
32 #define AV_CODEC_MSECOND (static_cast<int64_t>(1000) * AV_CODEC_USECOND)
33 #define AV_CODEC_SECOND (static_cast<int64_t>(1000) * AV_CODEC_MSECOND)
34 
35 namespace OHOS {
36 namespace Media {
37 namespace Plugins {
38 namespace Ffmpeg {
Mime2CodecId(const std::string & mime,AVCodecID & codecId)39 bool Mime2CodecId(const std::string &mime, AVCodecID &codecId)
40 {
41     /* MIME to AVCodecID */
42     static const std::unordered_map<std::string, AVCodecID> table = {
43         {MimeType::AUDIO_MPEG, AV_CODEC_ID_MP3},
44         {MimeType::AUDIO_AAC, AV_CODEC_ID_AAC},
45         {MimeType::AUDIO_AMR_NB, AV_CODEC_ID_AMR_NB},
46         {MimeType::AUDIO_AMR_WB, AV_CODEC_ID_AMR_WB},
47         {MimeType::AUDIO_RAW, AV_CODEC_ID_PCM_U8},
48         {MimeType::AUDIO_G711MU, AV_CODEC_ID_PCM_MULAW},
49         {MimeType::VIDEO_MPEG4, AV_CODEC_ID_MPEG4},
50         {MimeType::VIDEO_AVC, AV_CODEC_ID_H264},
51         {MimeType::VIDEO_HEVC, AV_CODEC_ID_HEVC},
52         {MimeType::IMAGE_JPG, AV_CODEC_ID_MJPEG},
53         {MimeType::IMAGE_PNG, AV_CODEC_ID_PNG},
54         {MimeType::IMAGE_BMP, AV_CODEC_ID_BMP},
55         {MimeType::TIMED_METADATA, AV_CODEC_ID_FFMETADATA},
56     };
57     auto it = table.find(mime);
58     if (it != table.end()) {
59         codecId = it->second;
60         return true;
61     }
62     return false;
63 }
64 
Raw2CodecId(AudioSampleFormat sampleFormat,AVCodecID & codecId)65 bool Raw2CodecId(AudioSampleFormat sampleFormat, AVCodecID &codecId)
66 {
67     static const std::unordered_map<AudioSampleFormat, AVCodecID> table = {
68         {AudioSampleFormat::SAMPLE_U8, AV_CODEC_ID_PCM_U8},
69         {AudioSampleFormat::SAMPLE_S16LE, AV_CODEC_ID_PCM_S16LE},
70         {AudioSampleFormat::SAMPLE_S24LE, AV_CODEC_ID_PCM_S24LE},
71         {AudioSampleFormat::SAMPLE_S32LE, AV_CODEC_ID_PCM_S32LE},
72         {AudioSampleFormat::SAMPLE_F32LE, AV_CODEC_ID_PCM_F32LE},
73     };
74     auto it = table.find(sampleFormat);
75     if (it != table.end()) {
76         codecId = it->second;
77         return true;
78     }
79     return false;
80 }
81 
AVStrError(int errnum)82 std::string AVStrError(int errnum)
83 {
84     char errbuf[AV_ERROR_MAX_STRING_SIZE] = {0};
85     av_strerror(errnum, errbuf, AV_ERROR_MAX_STRING_SIZE);
86     return std::string(errbuf);
87 }
88 
ConvertTimeFromFFmpeg(int64_t pts,AVRational base)89 int64_t ConvertTimeFromFFmpeg(int64_t pts, AVRational base)
90 {
91     int64_t out;
92     if (pts == AV_NOPTS_VALUE) {
93         out = -1;
94     } else {
95         AVRational bq = {1, AV_CODEC_SECOND};
96         out = av_rescale_q(pts, base, bq);
97     }
98     MEDIA_LOG_D("Base: [" PUBLIC_LOG_D32 "/" PUBLIC_LOG_D32 "], time convert ["
99         PUBLIC_LOG_D64 "]->[" PUBLIC_LOG_D64 "].", base.num, base.den, pts, out);
100     return out;
101 }
102 
ConvertPts(int64_t pts,int64_t startTime)103 int64_t ConvertPts(int64_t pts, int64_t startTime)
104 {
105     int64_t inputPts;
106     if (startTime >= 0 && (pts < INT64_MIN + startTime)) {
107         inputPts = AV_NOPTS_VALUE;
108         MEDIA_LOG_D("pts is anomalous, pts: " PUBLIC_LOG_D64, pts);
109         return inputPts;
110     } else if (startTime < 0 && (pts > INT64_MAX + startTime)) {
111         inputPts = AV_NOPTS_VALUE;
112         MEDIA_LOG_D("pts is anomalous, pts: " PUBLIC_LOG_D64, pts);
113         return inputPts;
114     }
115     inputPts = pts - startTime;
116 
117     return inputPts;
118 }
119 
ConvertTimeToFFmpeg(int64_t timestampNs,AVRational base)120 int64_t ConvertTimeToFFmpeg(int64_t timestampNs, AVRational base)
121 {
122     int64_t result;
123     if (base.num == 0) {
124         result = AV_NOPTS_VALUE;
125     } else {
126         AVRational bq = {1, AV_CODEC_SECOND};
127         result = av_rescale_q(timestampNs, bq, base);
128     }
129     MEDIA_LOG_D("Base: [" PUBLIC_LOG_D32 "/" PUBLIC_LOG_D32 "], time convert ["
130         PUBLIC_LOG_D64 "]->[" PUBLIC_LOG_D64 "].", base.num, base.den, timestampNs, result);
131     return result;
132 }
133 
ConvertTimeToFFmpegByUs(int64_t timestampUs,AVRational base)134 int64_t ConvertTimeToFFmpegByUs(int64_t timestampUs, AVRational base)
135 {
136     int64_t result;
137     if (base.num == 0) {
138         result = AV_NOPTS_VALUE;
139     } else {
140         AVRational bq = {1, AV_CODEC_MSECOND};
141         result = av_rescale_q(timestampUs, bq, base);
142     }
143     MEDIA_LOG_D("Base: [" PUBLIC_LOG_D32 "/" PUBLIC_LOG_D32 "], time convert ["
144         PUBLIC_LOG_D64 "]->[" PUBLIC_LOG_D64 "].", base.num, base.den, timestampUs, result);
145     return result;
146 }
147 
ConvertFFmpegMediaTypeToString(AVMediaType mediaType)148 std::string_view ConvertFFmpegMediaTypeToString(AVMediaType mediaType)
149 {
150     static const std::unordered_map<AVMediaType, std::string_view> table = {
151         {AVMediaType::AVMEDIA_TYPE_VIDEO, "video"},
152         {AVMediaType::AVMEDIA_TYPE_AUDIO, "audio"},
153         {AVMediaType::AVMEDIA_TYPE_DATA, "data"},
154         {AVMediaType::AVMEDIA_TYPE_SUBTITLE, "subtitle"},
155         {AVMediaType::AVMEDIA_TYPE_ATTACHMENT, "attachment"},
156         {AVMediaType::AVMEDIA_TYPE_TIMEDMETA, "timedmetadata"}
157     };
158     auto it = table.find(mediaType);
159     if (it == table.end()) {
160         return "unknow";
161     }
162     return it->second;
163 }
164 
StartWith(const char * name,const char * chars)165 bool StartWith(const char* name, const char* chars)
166 {
167     if (name == nullptr || chars == nullptr) {
168         return false;
169     }
170     MEDIA_LOG_D("[" PUBLIC_LOG_S "] start with [" PUBLIC_LOG_S "].", name, chars);
171     return !strncmp(name, chars, strlen(chars));
172 }
173 
ConvertFlagsFromFFmpeg(const AVPacket & pkt,bool memoryNotEnough)174 uint32_t ConvertFlagsFromFFmpeg(const AVPacket& pkt, bool memoryNotEnough)
175 {
176     uint32_t flags = (uint32_t)(AVBufferFlag::NONE);
177     if (static_cast<uint32_t>(pkt.flags) & static_cast<uint32_t>(AV_PKT_FLAG_KEY)) {
178         flags |= (uint32_t)(AVBufferFlag::SYNC_FRAME);
179         flags |= (uint32_t)(AVBufferFlag::CODEC_DATA);
180     }
181     if (static_cast<uint32_t>(pkt.flags) & static_cast<uint32_t>(AV_PKT_FLAG_DISCARD)) {
182         flags |= (uint32_t)(AVBufferFlag::DISCARD);
183     }
184     if (memoryNotEnough) {
185         flags |= (uint32_t)(AVBufferFlag::PARTIAL_FRAME);
186     }
187     return flags;
188 }
189 
CalculateTimeByFrameIndex(AVStream * avStream,int keyFrameIdx)190 int64_t CalculateTimeByFrameIndex(AVStream* avStream, int keyFrameIdx)
191 {
192     FALSE_RETURN_V_MSG_E(avStream != nullptr, 0, "Track is nullptr.");
193 #if defined(LIBAVFORMAT_VERSION_INT) && defined(AV_VERSION_INT)
194 #if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(58, 78, 0) // 58 and 78 are avformat version range
195     FALSE_RETURN_V_MSG_E(avformat_index_get_entry(avStream, keyFrameIdx) != nullptr, 0, "Track is nullptr.");
196     return avformat_index_get_entry(avStream, keyFrameIdx)->timestamp;
197 #elif LIBAVFORMAT_VERSION_INT == AV_VERSION_INT(58, 76, 100) // 58, 76 and 100 are avformat version range
198     return avStream->index_entries[keyFrameIdx].timestamp;
199 #elif LIBAVFORMAT_VERSION_INT > AV_VERSION_INT(58, 64, 100) // 58, 64 and 100 are avformat version range
200     FALSE_RETURN_V_MSG_E(avStream->internal != nullptr, 0, "Track is nullptr.");
201     return avStream->internal->index_entries[keyFrameIdx].timestamp;
202 #else
203     return avStream->index_entries[keyFrameIdx].timestamp;
204 #endif
205 #else
206     return avStream->index_entries[keyFrameIdx].timestamp;
207 #endif
208 }
209 
ReplaceDelimiter(const std::string & delimiters,char newDelimiter,std::string & str)210 void ReplaceDelimiter(const std::string &delimiters, char newDelimiter, std::string &str)
211 {
212     for (char &it : str) {
213         if (delimiters.find(newDelimiter) != std::string::npos) {
214             it = newDelimiter;
215         }
216     }
217 }
218 
SplitString(const char * str,char delimiter)219 std::vector<std::string> SplitString(const char* str, char delimiter)
220 {
221     std::vector<std::string> rtv;
222     if (str) {
223         SplitString(std::string(str), delimiter).swap(rtv);
224     }
225     return rtv;
226 }
227 
SplitString(const std::string & str,char delimiter)228 std::vector<std::string> SplitString(const std::string& str, char delimiter)
229 {
230     if (str.empty()) {
231         return {};
232     }
233     std::vector<std::string> rtv;
234     std::string::size_type startPos = 0;
235     std::string::size_type endPos = str.find_first_of(delimiter, startPos);
236     while (startPos != endPos) {
237         rtv.emplace_back(str.substr(startPos, endPos - startPos));
238         if (endPos == std::string::npos) {
239             break;
240         }
241         startPos = endPos + 1;
242         endPos = str.find_first_of(delimiter, startPos);
243     }
244     return rtv;
245 }
246 
ColorPrimary2AVColorPrimaries(ColorPrimary primary)247 std::pair<bool, AVColorPrimaries> ColorPrimary2AVColorPrimaries(ColorPrimary primary)
248 {
249     static const std::unordered_map<ColorPrimary, AVColorPrimaries> table = {
250         {ColorPrimary::BT709, AVCOL_PRI_BT709},
251         {ColorPrimary::UNSPECIFIED, AVCOL_PRI_UNSPECIFIED},
252         {ColorPrimary::BT470_M, AVCOL_PRI_BT470M},
253         {ColorPrimary::BT601_625, AVCOL_PRI_BT470BG},
254         {ColorPrimary::BT601_525, AVCOL_PRI_SMPTE170M},
255         {ColorPrimary::SMPTE_ST240, AVCOL_PRI_SMPTE240M},
256         {ColorPrimary::GENERIC_FILM, AVCOL_PRI_FILM},
257         {ColorPrimary::BT2020, AVCOL_PRI_BT2020},
258         {ColorPrimary::SMPTE_ST428, AVCOL_PRI_SMPTE428},
259         {ColorPrimary::P3DCI, AVCOL_PRI_SMPTE431},
260         {ColorPrimary::P3D65, AVCOL_PRI_SMPTE432},
261     };
262     auto it = table.find(primary);
263     if (it != table.end()) {
264         return { true, it->second };
265     }
266     return { false, AVCOL_PRI_UNSPECIFIED };
267 }
268 
ColorTransfer2AVColorTransfer(TransferCharacteristic transfer)269 std::pair<bool, AVColorTransferCharacteristic> ColorTransfer2AVColorTransfer(TransferCharacteristic transfer)
270 {
271     static const std::unordered_map<TransferCharacteristic, AVColorTransferCharacteristic> table = {
272         {TransferCharacteristic::BT709, AVCOL_TRC_BT709},
273         {TransferCharacteristic::UNSPECIFIED, AVCOL_TRC_UNSPECIFIED},
274         {TransferCharacteristic::GAMMA_2_2, AVCOL_TRC_GAMMA22},
275         {TransferCharacteristic::GAMMA_2_8, AVCOL_TRC_GAMMA28},
276         {TransferCharacteristic::BT601, AVCOL_TRC_SMPTE170M},
277         {TransferCharacteristic::SMPTE_ST240, AVCOL_TRC_SMPTE240M},
278         {TransferCharacteristic::LINEAR, AVCOL_TRC_LINEAR},
279         {TransferCharacteristic::LOG, AVCOL_TRC_LOG},
280         {TransferCharacteristic::LOG_SQRT, AVCOL_TRC_LOG_SQRT},
281         {TransferCharacteristic::IEC_61966_2_4, AVCOL_TRC_IEC61966_2_4},
282         {TransferCharacteristic::BT1361, AVCOL_TRC_BT1361_ECG},
283         {TransferCharacteristic::IEC_61966_2_1, AVCOL_TRC_IEC61966_2_1},
284         {TransferCharacteristic::BT2020_10BIT, AVCOL_TRC_BT2020_10},
285         {TransferCharacteristic::BT2020_12BIT, AVCOL_TRC_BT2020_12},
286         {TransferCharacteristic::PQ, AVCOL_TRC_SMPTE2084},
287         {TransferCharacteristic::SMPTE_ST428, AVCOL_TRC_SMPTE428},
288         {TransferCharacteristic::HLG, AVCOL_TRC_ARIB_STD_B67},
289     };
290     auto it = table.find(transfer);
291     if (it != table.end()) {
292         return { true, it->second };
293     }
294     return { false, AVCOL_TRC_UNSPECIFIED };
295 }
296 
ColorMatrix2AVColorSpace(MatrixCoefficient matrix)297 std::pair<bool, AVColorSpace> ColorMatrix2AVColorSpace(MatrixCoefficient matrix)
298 {
299     static const std::unordered_map<MatrixCoefficient, AVColorSpace> table = {
300         {MatrixCoefficient::IDENTITY, AVCOL_SPC_RGB},
301         {MatrixCoefficient::BT709, AVCOL_SPC_BT709},
302         {MatrixCoefficient::UNSPECIFIED, AVCOL_SPC_UNSPECIFIED},
303         {MatrixCoefficient::FCC, AVCOL_SPC_FCC},
304         {MatrixCoefficient::BT601_625, AVCOL_SPC_BT470BG},
305         {MatrixCoefficient::BT601_525, AVCOL_SPC_SMPTE170M},
306         {MatrixCoefficient::SMPTE_ST240, AVCOL_SPC_SMPTE240M},
307         {MatrixCoefficient::YCGCO, AVCOL_SPC_YCGCO},
308         {MatrixCoefficient::BT2020_NCL, AVCOL_SPC_BT2020_NCL},
309         {MatrixCoefficient::BT2020_CL, AVCOL_SPC_BT2020_CL},
310         {MatrixCoefficient::SMPTE_ST2085, AVCOL_SPC_SMPTE2085},
311         {MatrixCoefficient::CHROMATICITY_NCL, AVCOL_SPC_CHROMA_DERIVED_NCL},
312         {MatrixCoefficient::CHROMATICITY_CL, AVCOL_SPC_CHROMA_DERIVED_CL},
313         {MatrixCoefficient::ICTCP, AVCOL_SPC_ICTCP},
314     };
315     auto it = table.find(matrix);
316     if (it != table.end()) {
317         return { true, it->second };
318     }
319     return { false, AVCOL_SPC_UNSPECIFIED };
320 }
321 
GenerateAACCodecConfig(int32_t profile,int32_t sampleRate,int32_t channels)322 std::vector<uint8_t> GenerateAACCodecConfig(int32_t profile, int32_t sampleRate, int32_t channels)
323 {
324     const std::unordered_map<AACProfile, int32_t> profiles = {
325         {AAC_PROFILE_LC, 1},
326         {AAC_PROFILE_ELD, 38},
327         {AAC_PROFILE_ERLC, 1},
328         {AAC_PROFILE_HE, 4},
329         {AAC_PROFILE_HE_V2, 28},
330         {AAC_PROFILE_LD, 22},
331         {AAC_PROFILE_MAIN, 0},
332     };
333     const std::unordered_map<uint32_t, uint32_t> sampleRates = {
334         {96000, 0}, {88200, 1}, {64000, 2}, {48000, 3},
335         {44100, 4}, {32000, 5}, {24000, 6}, {22050, 7},
336         {16000, 8}, {12000, 9}, {11025, 10}, {8000,  11},
337         {7350,  12},
338     };
339     uint32_t profileVal = FF_PROFILE_AAC_LOW;
340     auto it1 = profiles.find(static_cast<AACProfile>(profile));
341     if (it1 != profiles.end()) {
342         profileVal = it1->second;
343     }
344     uint32_t sampleRateIndex = 0x10;
345     uint32_t baseIndex = 0xF;
346     auto it2 = sampleRates.find(sampleRate);
347     if (it2 != sampleRates.end()) {
348         sampleRateIndex = it2->second;
349     }
350     it2 = sampleRates.find(sampleRate / 2); // 2: HE-AAC require divide base sample rate
351     if (it2 != sampleRates.end()) {
352         baseIndex = it2->second;
353     }
354     std::vector<uint8_t> codecConfig;
355     if (profile == AAC_PROFILE_HE || profile == AAC_PROFILE_HE_V2) {
356         // HE-AAC v2 only support stereo and only one channel exist
357         uint32_t realCh = (profile == AAC_PROFILE_HE_V2) ? 1 : static_cast<uint32_t>(channels);
358         codecConfig = {0, 0, 0, 0, 0};
359         // 5 bit AOT(0x03:left 3 bits for sample rate) + 4 bit sample rate idx(0x01: 4 - 0x03)
360         codecConfig[0] = ((profileVal + 1) << 0x03) | ((baseIndex & 0x0F) >> 0x01);
361         // 0x07: left 7bits for other, 4 bit channel cfg,0x03:left for other
362         codecConfig[1] = ((baseIndex & 0x01) << 0x07) | ((realCh & 0x0F) << 0x03) | ((sampleRateIndex & 0x0F) >> 1) ;
363         // 4 bit ext sample rate idx(0x07: left 7 bits for other) + 4 bit aot(2: LC-AAC, 0x02: left for other)
364         codecConfig[2] = ((sampleRateIndex & 0x01) << 0x07) | (2 << 0x02);
365     } else {
366         codecConfig = {0, 0, 0x56, 0xE5, 0};
367         codecConfig[0] = ((profileVal + 1) << 0x03) | ((sampleRateIndex & 0x0F) >> 0x01);
368         codecConfig[1] = ((sampleRateIndex & 0x01) << 0x07) | ((channels & 0x0F) << 0x03);
369     }
370 
371     return codecConfig;
372 }
373 
FfmpegLogPrint(void * avcl,int level,const char * fmt,va_list vl)374 void FfmpegLogPrint(void* avcl, int level, const char* fmt, va_list vl)
375 {
376     (void)avcl;
377     char buf[500] = {0}; // 500
378     int ret = vsnprintf_s(buf, sizeof(buf), sizeof(buf), fmt, vl);
379     if (ret < 0) {
380         return;
381     }
382     switch (level) {
383         case AV_LOG_WARNING:
384             MEDIA_LOG_D("[FFmpeg Log " PUBLIC_LOG_D32 " WARN] " PUBLIC_LOG_S, level, buf);
385             break;
386         case AV_LOG_ERROR:
387             MEDIA_LOG_D("[FFmpeg Log " PUBLIC_LOG_D32 " ERROR] " PUBLIC_LOG_S, level, buf);
388             break;
389         case AV_LOG_FATAL:
390             MEDIA_LOG_D("[FFmpeg Log " PUBLIC_LOG_D32 " FATAL] " PUBLIC_LOG_S, level, buf);
391             break;
392         case AV_LOG_INFO:
393             MEDIA_LOG_D("[FFmpeg Log " PUBLIC_LOG_D32 " INFO] " PUBLIC_LOG_S, level, buf);
394             break;
395         case AV_LOG_DEBUG:
396             MEDIA_LOG_D("[FFmpeg Log " PUBLIC_LOG_D32 " DEBUG] " PUBLIC_LOG_S, level, buf);
397             break;
398         default:
399             break;
400     }
401 }
402 
FindNaluSpliter(int size,const uint8_t * data)403 int FindNaluSpliter(int size, const uint8_t* data)
404 {
405     int naluPos = -1;
406     if (size >= 4 && data[0] == 0x00 && data[1] == 0x00) { // 4: least size
407         if (data[2] == 0x01) { // 2: next index
408             naluPos = 3; // 3: the actual start pos of nal unit
409         } else if (size >= 5 && data[2] == 0x00 && data[3] == 0x01) { // 5: least size, 2, 3: next indecies
410             naluPos = 4; // 4: the actual start pos of nal unit
411         }
412     }
413     return naluPos;
414 }
415 
CanDropAvcPkt(const AVPacket & pkt)416 bool CanDropAvcPkt(const AVPacket& pkt)
417 {
418     const uint8_t *data = pkt.data;
419     int size = pkt.size;
420     int naluPos = FindNaluSpliter(size, data);
421     if (naluPos < 0) {
422         MEDIA_LOG_D("pkt->data starts with error start code!");
423         return false;
424     }
425     int nalRefIdc = (data[naluPos] >> 5) & 0x03; // 5: get H.264 nal_ref_idc
426     int nalUnitType = data[naluPos] & 0x1f; // get H.264 nal_unit_type
427     bool isCodedSliceData = nalUnitType == 1 || nalUnitType == 2 || // 1: non-IDR, 2: partiton A
428         nalUnitType == 3 || nalUnitType == 4 || nalUnitType == 5; // 3: partiton B, 4: partiton C, 5: IDR
429     return nalRefIdc == 0 && isCodedSliceData;
430 }
431 
CanDropHevcPkt(const AVPacket & pkt)432 bool CanDropHevcPkt(const AVPacket& pkt)
433 {
434     const uint8_t *data = pkt.data;
435     int size = pkt.size;
436     int naluPos = FindNaluSpliter(size, data);
437     if (naluPos < 0) {
438         MEDIA_LOG_D("pkt->data starts with error start code!");
439         return false;
440     }
441     int nalUnitType = (data[naluPos] >> 1) & 0x3f; // get H.265 nal_unit_type
442     return nalUnitType == 0 || nalUnitType == 2 || nalUnitType == 4 || // 0: TRAIL_N, 2: TSA_N, 4: STSA_N
443         nalUnitType == 6 || nalUnitType == 8; // 6: RADL_N, 8: RASL_N
444 }
445 
SetDropTag(const AVPacket & pkt,std::shared_ptr<AVBuffer> sample,AVCodecID codecId)446 void SetDropTag(const AVPacket& pkt, std::shared_ptr<AVBuffer> sample, AVCodecID codecId)
447 {
448     sample->meta_->Remove(Media::Tag::VIDEO_BUFFER_CAN_DROP);
449     bool canDrop = false;
450     if (codecId == AV_CODEC_ID_HEVC) {
451         canDrop = CanDropHevcPkt(pkt);
452     } else if (codecId == AV_CODEC_ID_H264) {
453         canDrop = CanDropAvcPkt(pkt);
454     }
455     if (canDrop) {
456         sample->meta_->SetData(Media::Tag::VIDEO_BUFFER_CAN_DROP, true);
457     }
458 }
459 
IsInputFormatSupported(const char * name)460 bool IsInputFormatSupported(const char* name)
461 {
462     MEDIA_LOG_D("Check support " PUBLIC_LOG_S " or not.", name);
463     if (!strcmp(name, "audio_device") || StartWith(name, "image") ||
464         !strcmp(name, "mjpeg") || !strcmp(name, "redir") || StartWith(name, "u8") ||
465         StartWith(name, "u16") || StartWith(name, "u24") ||
466         StartWith(name, "u32") ||
467         StartWith(name, "s8") || StartWith(name, "s16") ||
468         StartWith(name, "s24") ||
469         StartWith(name, "s32") || StartWith(name, "f32") ||
470         StartWith(name, "f64") ||
471         !strcmp(name, "mulaw") || !strcmp(name, "alaw")) {
472         return false;
473     }
474     if (!strcmp(name, "sdp") || !strcmp(name, "rtsp") || !strcmp(name, "applehttp")) {
475         return false;
476     }
477     return true;
478 }
479 
AvTime2Us(int64_t hTime)480 int64_t AvTime2Us(int64_t hTime)
481 {
482     return hTime / AV_CODEC_USECOND;
483 }
484 } // namespace Ffmpeg
485 } // namespace Plugins
486 } // namespace Media
487 } // namespace OHOS
488