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