1 /*
2 * Copyright (c) 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 "frame_detector.h"
17
18 #include <algorithm>
19 #include <memory>
20
21 namespace OHOS {
22 namespace Media {
23 using namespace std;
24
GetFrameDetector(CodeType type)25 std::shared_ptr<FrameDetector> FrameDetector::GetFrameDetector(CodeType type)
26 {
27 switch (type) {
28 case CodeType::H264:
29 static std::shared_ptr<FrameDetectorH264> frameDetectorH264 = make_shared<FrameDetectorH264>();
30 return frameDetectorH264;
31 case CodeType::H265:
32 static std::shared_ptr<FrameDetectorH265> frameDetectorH265 = make_shared<FrameDetectorH265>();
33 return frameDetectorH265;
34 default:
35 return nullptr;
36 }
37 }
38
IsContainIdrFrame(const uint8_t * buff,size_t bufSize)39 bool FrameDetector::IsContainIdrFrame(const uint8_t* buff, size_t bufSize)
40 {
41 if (buff == nullptr) {
42 return false;
43 }
44 using FirstByteInNalu = uint8_t;
45 list<pair<size_t, FirstByteInNalu>> posOfNalUnit;
46 size_t pos = 0;
47 while (pos < bufSize) {
48 auto pFound = search(buff + pos, buff + bufSize, begin(START_CODE), end(START_CODE));
49 pos = static_cast<size_t>(distance(buff, pFound));
50 if (pos == bufSize || pos + START_CODE_LEN >= bufSize) { // fail to find startCode or just at the end
51 break;
52 }
53 posOfNalUnit.emplace_back(pos, buff[pos + START_CODE_LEN]);
54 pos += START_CODE_LEN;
55 }
56 for (auto it = posOfNalUnit.begin(); it != posOfNalUnit.end(); ++it) {
57 auto nex = next(it);
58 NALUInfo nal {
59 .startPos = it->first,
60 .endPos = (nex == posOfNalUnit.end()) ? (bufSize) : (nex->first),
61 .nalType = GetNalType(it->second),
62 };
63 if (IsIDR(nal.nalType)) {
64 return true;
65 }
66 }
67 return false;
68 }
69
GetNalType(uint8_t byte)70 uint8_t FrameDetectorH264::GetNalType(uint8_t byte)
71 {
72 return byte & 0b0001'1111;
73 }
74
IsPPS(uint8_t nalType)75 bool FrameDetectorH264::IsPPS(uint8_t nalType)
76 {
77 return nalType == H264NalType::PPS;
78 }
79
IsVCL(uint8_t nalType)80 bool FrameDetectorH264::IsVCL(uint8_t nalType)
81 {
82 return nalType >= H264NalType::NON_IDR && nalType <= H264NalType::IDR;
83 }
84
IsIDR(uint8_t nalType)85 bool FrameDetectorH264::IsIDR(uint8_t nalType)
86 {
87 return nalType == H264NalType::IDR;
88 }
89
GetNalType(uint8_t byte)90 uint8_t FrameDetectorH265::GetNalType(uint8_t byte)
91 {
92 return (byte & 0b0111'1110) >> 1;
93 }
94
IsPPS(uint8_t nalType)95 bool FrameDetectorH265::IsPPS(uint8_t nalType)
96 {
97 return nalType == H265NalType::HEVC_PPS_NUT;
98 }
99
IsVCL(uint8_t nalType)100 bool FrameDetectorH265::IsVCL(uint8_t nalType)
101 {
102 return nalType >= H265NalType::HEVC_TRAIL_N && nalType <= H265NalType::HEVC_CRA_NUT;
103 }
104
IsIDR(uint8_t nalType)105 bool FrameDetectorH265::IsIDR(uint8_t nalType)
106 {
107 return nalType == H265NalType::HEVC_IDR_W_RADL ||
108 nalType == H265NalType::HEVC_IDR_N_LP ||
109 nalType == H265NalType::HEVC_CRA_NUT;
110 }
111
IsPrefixSEI(uint8_t nalType)112 bool FrameDetectorH265::IsPrefixSEI(uint8_t nalType)
113 {
114 return nalType == H265NalType::HEVC_PREFIX_SEI_NUT;
115 }
116 } // namespace Media
117 } // namespace OHOS