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 "codec_drm_decrypt.h"
17 #include "avcodec_errors.h"
18 #include "avcodec_log.h"
19 #include "securec.h"
20 #ifdef SUPPORT_DRM
21 #include "i_keysession_service.h"
22 #include "i_mediadecryptmodule_service.h"
23 #endif
24
25 namespace {
26 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_FRAMEWORK, "CodecDrmDecrypt"};
27 } // namespace
28
29 namespace OHOS {
30 namespace MediaAVCodec {
31
32 #ifdef SUPPORT_DRM
33 using DrmBuffer = DrmStandard::IMediaDecryptModuleService::DrmBuffer;
34 #endif
35 #define DRM_VIDEO_FRAME_ARR_LEN 3
36 #define DRM_AMBIGUITY_ARR_LEN 3
37 #define DRM_USER_DATA_REGISTERED_UUID_SIZE 16
38 constexpr uint32_t DRM_LEGACY_LEN = 3;
39 constexpr uint32_t DRM_AES_BLOCK_SIZE = 16;
40 constexpr uint8_t DRM_AMBIGUITY_START_NUM = 0x00;
41 constexpr uint8_t DRM_AMBIGUITY_END_NUM = 0x03;
42 constexpr uint32_t DRM_CRYPT_BYTE_BLOCK = 1;
43 constexpr uint32_t DRM_SKIP_BYTE_BLOCK = 9;
44 constexpr uint32_t DRM_H264_VIDEO_SKIP_BYTES = 35; // 35:(32 + 3) 32: bytes 3:3bytes
45 constexpr uint32_t DRM_H265_VIDEO_SKIP_BYTES = 68; // 68:(65 + 3) // 65: bytes 3:3bytes
46 constexpr uint32_t DRM_AVS3_VIDEO_SKIP_BYTES = 4; // 4:(1 + 3) // 1: bytes 3:3bytes
47 constexpr uint8_t DRM_SHIFT_LEFT_NUM = 1;
48 constexpr uint8_t DRM_H264_VIDEO_NAL_TYPE_UMASK_NUM = 0x1f;
49 constexpr uint8_t DRM_H265_VIDEO_NAL_TYPE_UMASK_NUM = 0x3f;
50 constexpr uint8_t DRM_H265_VIDEO_START_NAL_TYPE = 0;
51 constexpr uint8_t DRM_H265_VIDEO_END_NAL_TYPE = 31;
52 constexpr uint32_t DRM_TS_SUB_SAMPLE_NUM = 2;
53 constexpr uint8_t DRM_H264_VIDEO_START_NAL_TYPE = 1;
54 constexpr uint8_t DRM_H264_VIDEO_END_NAL_TYPE = 5;
55 constexpr uint32_t DRM_MAX_STREAM_DATA_SIZE = 20971520; // 20971520:(20 * 1024 * 1024) 20MB, 1024:1024 bytes = 1kb
56 constexpr uint32_t DRM_H265_PAYLOAD_TYPE_OFFSET = 5;
57 constexpr uint8_t DRM_AVS_FLAG = 0xb5;
58 constexpr uint8_t DRM_USER_DATA_UNREGISTERED_TAG = 0x05;
59 constexpr uint32_t DRM_MIN_DRM_INFO_LEN = 2;
60 constexpr uint32_t DRM_INVALID_START_POS = 0xffffffff;
61
62 static const uint8_t VIDEO_FRAME_ARR[DRM_VIDEO_FRAME_ARR_LEN] = { 0x00, 0x00, 0x01 };
63 static const uint8_t AMBIGUITY_ARR[DRM_AMBIGUITY_ARR_LEN] = { 0x00, 0x00, 0x03 };
64 static const uint8_t USER_REGISTERED_UUID[DRM_USER_DATA_REGISTERED_UUID_SIZE] = {
65 0x70, 0xc1, 0xdb, 0x9f, 0x66, 0xae, 0x41, 0x27, 0xbf, 0xc0, 0xbb, 0x19, 0x81, 0x69, 0x4b, 0x66
66 };
67
68 typedef enum {
69 DRM_ARR_SUBSCRIPT_ZERO = 0,
70 DRM_ARR_SUBSCRIPT_ONE,
71 DRM_ARR_SUBSCRIPT_TWO,
72 DRM_ARR_SUBSCRIPT_THREE,
73 } DRM_ArrSubscriptCollection;
74
75 typedef enum {
76 DRM_VIDEO_AVC = 0x1,
77 DRM_VIDEO_HEVC,
78 DRM_VIDEO_AVS,
79 DRM_VIDEO_NONE,
80 } DRM_CodecType;
81
DrmGetSkipClearBytes(uint32_t & skipBytes) const82 void CodecDrmDecrypt::DrmGetSkipClearBytes(uint32_t &skipBytes) const
83 {
84 if (codingType_ == DRM_VIDEO_AVC) {
85 skipBytes = DRM_H264_VIDEO_SKIP_BYTES;
86 } else if (codingType_ == DRM_VIDEO_HEVC) {
87 skipBytes = DRM_H265_VIDEO_SKIP_BYTES;
88 } else if (codingType_ == DRM_VIDEO_AVS) {
89 skipBytes = DRM_AVS3_VIDEO_SKIP_BYTES;
90 }
91 return;
92 }
93
DrmGetNalTypeAndIndex(const uint8_t * data,uint32_t dataSize,uint8_t & nalType,uint32_t & posIndex) const94 int32_t CodecDrmDecrypt::DrmGetNalTypeAndIndex(const uint8_t *data, uint32_t dataSize,
95 uint8_t &nalType, uint32_t &posIndex) const
96 {
97 uint32_t i;
98 nalType = 0;
99 for (i = posIndex; (i + DRM_LEGACY_LEN) < dataSize; i++) {
100 if ((data[i] != VIDEO_FRAME_ARR[DRM_ARR_SUBSCRIPT_ZERO]) ||
101 (data[i + DRM_ARR_SUBSCRIPT_ONE] != VIDEO_FRAME_ARR[DRM_ARR_SUBSCRIPT_ONE]) ||
102 (data[i + DRM_ARR_SUBSCRIPT_TWO] != VIDEO_FRAME_ARR[DRM_ARR_SUBSCRIPT_TWO])) {
103 continue;
104 }
105 if (codingType_ == DRM_VIDEO_AVC) {
106 nalType = data[i + DRM_ARR_SUBSCRIPT_THREE] & DRM_H264_VIDEO_NAL_TYPE_UMASK_NUM;
107 if ((nalType == DRM_H264_VIDEO_START_NAL_TYPE) ||
108 (nalType == DRM_H264_VIDEO_END_NAL_TYPE)) {
109 posIndex = i;
110 return 0;
111 }
112 } else if (codingType_ == DRM_VIDEO_HEVC) {
113 nalType = (data[i + DRM_ARR_SUBSCRIPT_THREE] >> DRM_SHIFT_LEFT_NUM) & DRM_H265_VIDEO_NAL_TYPE_UMASK_NUM;
114 if ((nalType >= DRM_H265_VIDEO_START_NAL_TYPE) &&
115 (nalType <= DRM_H265_VIDEO_END_NAL_TYPE)) {
116 posIndex = i;
117 return 0;
118 }
119 } else if (codingType_ == DRM_VIDEO_AVS) {
120 nalType = data[i + DRM_ARR_SUBSCRIPT_THREE];
121 if (nalType == 0) {
122 posIndex = i;
123 return 0;
124 }
125 }
126 }
127 posIndex = i;
128 return -1;
129 }
130
DrmGetSyncHeaderIndex(const uint8_t * data,uint32_t dataSize,uint32_t & posIndex)131 void CodecDrmDecrypt::DrmGetSyncHeaderIndex(const uint8_t *data, uint32_t dataSize, uint32_t &posIndex)
132 {
133 uint32_t i;
134 for (i = posIndex; (i + DRM_LEGACY_LEN) < dataSize; i++) {
135 if ((data[i] != VIDEO_FRAME_ARR[DRM_ARR_SUBSCRIPT_ZERO]) ||
136 (data[i + DRM_ARR_SUBSCRIPT_ONE] != VIDEO_FRAME_ARR[DRM_ARR_SUBSCRIPT_ONE]) ||
137 (data[i + DRM_ARR_SUBSCRIPT_TWO] != VIDEO_FRAME_ARR[DRM_ARR_SUBSCRIPT_TWO])) {
138 continue;
139 }
140 posIndex = i;
141 return;
142 }
143 posIndex = dataSize;
144 return;
145 }
146
DrmGetFinalNalTypeAndIndex(const uint8_t * data,uint32_t dataSize,uint32_t & posStartIndex,uint32_t & posEndIndex) const147 uint8_t CodecDrmDecrypt::DrmGetFinalNalTypeAndIndex(const uint8_t *data, uint32_t dataSize,
148 uint32_t &posStartIndex, uint32_t &posEndIndex) const
149 {
150 uint32_t skipBytes = 0;
151 uint8_t tmpNalType = 0;
152 uint32_t tmpPosIndex = 0;
153 uint8_t nalType = 0;
154 posStartIndex = 0;
155 posEndIndex = dataSize;
156 DrmGetSkipClearBytes(skipBytes);
157 while (1) { // 1 true
158 int32_t ret = DrmGetNalTypeAndIndex(data, dataSize, tmpNalType, tmpPosIndex);
159 if (ret == 0) {
160 nalType = tmpNalType;
161 posStartIndex = tmpPosIndex;
162 tmpPosIndex += DRM_LEGACY_LEN;
163 DrmGetSyncHeaderIndex(data, dataSize, tmpPosIndex);
164 posEndIndex = tmpPosIndex;
165 if (tmpPosIndex > posStartIndex + skipBytes + DRM_AES_BLOCK_SIZE) {
166 break;
167 } else {
168 nalType = 0;
169 posStartIndex = dataSize;
170 posEndIndex = dataSize;
171 }
172 } else {
173 nalType = 0;
174 posStartIndex = dataSize;
175 posEndIndex = dataSize;
176 break;
177 }
178 }
179 return nalType;
180 }
181
DrmRemoveAmbiguityBytes(uint8_t * data,uint32_t & posEndIndex,uint32_t offset,uint32_t & dataSize)182 void CodecDrmDecrypt::DrmRemoveAmbiguityBytes(uint8_t *data, uint32_t &posEndIndex, uint32_t offset,
183 uint32_t &dataSize)
184 {
185 uint32_t len = posEndIndex;
186 uint32_t i;
187 for (i = offset; (i + DRM_LEGACY_LEN) < len; i++) {
188 if ((data[i] == AMBIGUITY_ARR[DRM_ARR_SUBSCRIPT_ZERO]) &&
189 (data[i + DRM_ARR_SUBSCRIPT_ONE] == AMBIGUITY_ARR[DRM_ARR_SUBSCRIPT_ONE]) &&
190 (data[i + DRM_ARR_SUBSCRIPT_TWO] == AMBIGUITY_ARR[DRM_ARR_SUBSCRIPT_TWO])) {
191 if (data[i + DRM_ARR_SUBSCRIPT_THREE] >= DRM_AMBIGUITY_START_NUM &&
192 data[i + DRM_ARR_SUBSCRIPT_THREE] <= DRM_AMBIGUITY_END_NUM) {
193 errno_t res = memmove_s(data + i + DRM_ARR_SUBSCRIPT_TWO, len - (i + DRM_ARR_SUBSCRIPT_TWO),
194 data + i + DRM_ARR_SUBSCRIPT_THREE, len - (i + DRM_ARR_SUBSCRIPT_THREE));
195 CHECK_AND_RETURN_LOG(res == EOK, "memmove data err");
196 len -= 1;
197 i++;
198 }
199 }
200 }
201 dataSize = dataSize - (posEndIndex - len);
202 posEndIndex = len;
203 return;
204 }
205
DrmModifyCencInfo(std::shared_ptr<AVBuffer> inBuf,uint32_t & dataSize,uint8_t isAmbiguity,MetaDrmCencInfo * cencInfo) const206 void CodecDrmDecrypt::DrmModifyCencInfo(std::shared_ptr<AVBuffer> inBuf, uint32_t &dataSize, uint8_t isAmbiguity,
207 MetaDrmCencInfo *cencInfo) const
208 {
209 uint8_t nalType;
210 uint32_t posStartIndex;
211 uint32_t posEndIndex;
212 uint32_t skipBytes = 0;
213 uint32_t delLen = 0;
214 uint32_t i;
215 CHECK_AND_RETURN_LOG((inBuf->memory_ != nullptr && inBuf->memory_->GetAddr() != nullptr && dataSize != 0 &&
216 dataSize <= DRM_MAX_STREAM_DATA_SIZE), "parameter err");
217 uint8_t *data = inBuf->memory_->GetAddr();
218 DrmGetSkipClearBytes(skipBytes);
219 nalType = DrmGetFinalNalTypeAndIndex(data, dataSize, posStartIndex, posEndIndex);
220 if (isAmbiguity == 1) {
221 DrmRemoveAmbiguityBytes(data, posEndIndex, posStartIndex, dataSize);
222 }
223 CHECK_AND_RETURN_LOG((posEndIndex >= 1), "posEndIndex err"); // 1:index
224 for (i = posEndIndex - 1; i > 0; i--) {
225 if (data[i] != 0) {
226 break;
227 }
228 delLen++;
229 }
230
231 cencInfo->subSamples[0].clearHeaderLen = dataSize;
232 cencInfo->subSamples[0].payLoadLen = 0;
233 cencInfo->subSamples[1].clearHeaderLen = 0;
234 cencInfo->subSamples[1].payLoadLen = 0;
235 if (((codingType_ == DRM_VIDEO_AVC) && ((nalType == DRM_H264_VIDEO_START_NAL_TYPE) ||
236 (nalType == DRM_H264_VIDEO_END_NAL_TYPE))) ||
237 ((codingType_ == DRM_VIDEO_HEVC) &&
238 (nalType >= DRM_H265_VIDEO_START_NAL_TYPE) && (nalType <= DRM_H265_VIDEO_END_NAL_TYPE)) ||
239 ((codingType_ == DRM_VIDEO_AVS) && (nalType == 0))) {
240 uint32_t clearHeaderLen = posStartIndex + skipBytes;
241 uint32_t payLoadLen =
242 (posEndIndex > (clearHeaderLen + delLen)) ? (posEndIndex - clearHeaderLen - delLen) : 0;
243 if (payLoadLen > 0) {
244 uint32_t lastClearLen = (payLoadLen % DRM_AES_BLOCK_SIZE == 0) ? DRM_AES_BLOCK_SIZE
245 : (payLoadLen % DRM_AES_BLOCK_SIZE);
246 payLoadLen = payLoadLen - lastClearLen;
247 cencInfo->subSamples[0].clearHeaderLen = clearHeaderLen;
248 cencInfo->subSamples[0].payLoadLen = payLoadLen;
249 cencInfo->subSamples[1].clearHeaderLen = lastClearLen + delLen + (dataSize - posEndIndex);
250 cencInfo->subSamples[1].payLoadLen = 0;
251 }
252 }
253 return;
254 }
255
SetDrmAlgoAndBlocks(uint8_t algo,MetaDrmCencInfo * cencInfo)256 void CodecDrmDecrypt::SetDrmAlgoAndBlocks(uint8_t algo, MetaDrmCencInfo *cencInfo)
257 {
258 if (algo == 0x1) { // 0x1:SM4-SAMPL SM4S
259 cencInfo->algo = MetaDrmCencAlgorithm::META_DRM_ALG_CENC_SM4_CBC;
260 cencInfo->encryptBlocks = DRM_CRYPT_BYTE_BLOCK;
261 cencInfo->skipBlocks = DRM_SKIP_BYTE_BLOCK;
262 } else if (algo == 0x2) { // 0x2:AES CBCS
263 cencInfo->algo = MetaDrmCencAlgorithm::META_DRM_ALG_CENC_AES_CBC;
264 cencInfo->encryptBlocks = DRM_CRYPT_BYTE_BLOCK;
265 cencInfo->skipBlocks = DRM_SKIP_BYTE_BLOCK;
266 } else if (algo == 0x5) { // 0x5:AES CBC1
267 cencInfo->algo = MetaDrmCencAlgorithm::META_DRM_ALG_CENC_AES_CBC;
268 cencInfo->encryptBlocks = 0;
269 cencInfo->skipBlocks = 0;
270 } else if (algo == 0x3) { // 0x3:SM4-CBC SM4C
271 cencInfo->algo = MetaDrmCencAlgorithm::META_DRM_ALG_CENC_SM4_CBC;
272 cencInfo->encryptBlocks = 0;
273 cencInfo->skipBlocks = 0;
274 } else if (algo == 0x0) { // 0x0:NONE
275 cencInfo->algo = MetaDrmCencAlgorithm::META_DRM_ALG_CENC_UNENCRYPTED;
276 cencInfo->encryptBlocks = 0;
277 cencInfo->skipBlocks = 0;
278 }
279 return;
280 }
281
DrmFindAvsCeiNalUnit(const uint8_t * data,uint32_t dataSize,uint32_t & ceiStartPos,uint32_t index)282 int CodecDrmDecrypt::DrmFindAvsCeiNalUnit(const uint8_t *data, uint32_t dataSize, uint32_t &ceiStartPos,
283 uint32_t index)
284 {
285 uint32_t i = index;
286 /*
287 * only squence_header allowed, cei is in first extension_and_user_data after squence_header.
288 * data[i + DRM_LEGACY_LEN] is the nal unit header(00~b8),
289 * 0xb0 means Squence header, 0xb5 means video extension, 0xb1 undefined, others are frames
290 */
291 if (((data[i + DRM_LEGACY_LEN] > 0) && (data[i + DRM_LEGACY_LEN] < 0xb8)) &&
292 (data[i + DRM_LEGACY_LEN] != 0xb0) && (data[i + DRM_LEGACY_LEN] != 0xb5) &&
293 (data[i + DRM_LEGACY_LEN] != 0xb1)) {
294 AVCODEC_LOGD("avs frame found");
295 return 0;
296 }
297 if ((data[i + DRM_LEGACY_LEN] == 0xb5) && (i + DRM_LEGACY_LEN + 1 < dataSize)) {
298 /* extension_and_user_data found, 0xd0: extension user data tag, 0xf0: the higher 4 bits */
299 if ((data[i + DRM_LEGACY_LEN + 1] & 0xf0) == 0xd0) {
300 ceiStartPos = i;
301 AVCODEC_LOGD("cei found, packet start pos:%{public}d", ceiStartPos);
302 }
303 }
304 return -1;
305 }
306
DrmFindHevcCeiNalUnit(const uint8_t * data,uint32_t dataSize,uint32_t & ceiStartPos,uint32_t index)307 int CodecDrmDecrypt::DrmFindHevcCeiNalUnit(const uint8_t *data, uint32_t dataSize, uint32_t &ceiStartPos,
308 uint32_t index)
309 {
310 uint32_t i = index;
311 uint8_t nalType = (data[i + DRM_LEGACY_LEN] >> DRM_SHIFT_LEFT_NUM) & DRM_H265_VIDEO_NAL_TYPE_UMASK_NUM;
312 AVCODEC_LOGD("nal type=%{public}x", nalType);
313 if (nalType <= DRM_H265_VIDEO_END_NAL_TYPE) { // nal type: 0 ~ 31 are slice nal units and reserved units
314 /* sei is not after frame data. */
315 AVCODEC_LOGD("h265 frame found");
316 return 0;
317 } else if ((nalType == 39) && (i + DRM_H265_PAYLOAD_TYPE_OFFSET < dataSize)) { // 39: SEI nal unit
318 if (data[i + DRM_H265_PAYLOAD_TYPE_OFFSET] == DRM_USER_DATA_UNREGISTERED_TAG) {
319 ceiStartPos = i;
320 }
321 }
322 if (ceiStartPos != DRM_INVALID_START_POS) {
323 uint32_t startPos = i + DRM_H265_PAYLOAD_TYPE_OFFSET;
324 uint32_t endPos = i + DRM_H265_PAYLOAD_TYPE_OFFSET;
325 ceiStartPos = DRM_INVALID_START_POS;
326 DrmGetSyncHeaderIndex(data, dataSize, endPos);
327 for (; (startPos + DRM_USER_DATA_REGISTERED_UUID_SIZE < endPos); startPos++) {
328 if (memcmp(data + startPos, USER_REGISTERED_UUID,
329 DRM_USER_DATA_REGISTERED_UUID_SIZE) == 0) {
330 ceiStartPos = i;
331 AVCODEC_LOGD("cei found, packet start pos:%{public}d", ceiStartPos);
332 break;
333 }
334 }
335 }
336 return -1;
337 }
338
DrmFindH264CeiNalUnit(const uint8_t * data,uint32_t dataSize,uint32_t & ceiStartPos,uint32_t index)339 int CodecDrmDecrypt::DrmFindH264CeiNalUnit(const uint8_t *data, uint32_t dataSize, uint32_t &ceiStartPos,
340 uint32_t index)
341 {
342 uint32_t i = index;
343 uint8_t nalType = data[i + DRM_LEGACY_LEN] & DRM_H264_VIDEO_NAL_TYPE_UMASK_NUM;
344 AVCODEC_LOGD("nal type=%{public}x", nalType);
345 if ((nalType >= DRM_H264_VIDEO_START_NAL_TYPE) && (nalType <= DRM_H264_VIDEO_END_NAL_TYPE)) {
346 /* sei is not after frame data. */
347 AVCODEC_LOGD("h264 frame found");
348 return 0;
349 } else if ((nalType == 39) || (nalType == 6)) { // 39 or 6 is SEI nal unit tag
350 if ((i + DRM_LEGACY_LEN + 1 < dataSize) &&
351 (data[i + DRM_LEGACY_LEN + 1] == DRM_USER_DATA_UNREGISTERED_TAG)) {
352 ceiStartPos = i;
353 }
354 }
355 if (ceiStartPos != DRM_INVALID_START_POS) {
356 uint32_t startPos = i + DRM_LEGACY_LEN + 1;
357 uint32_t endPos = i + DRM_LEGACY_LEN + 1;
358 ceiStartPos = DRM_INVALID_START_POS;
359 DrmGetSyncHeaderIndex(data, dataSize, endPos);
360 for (; (startPos + DRM_USER_DATA_REGISTERED_UUID_SIZE < endPos); startPos++) {
361 if (memcmp(data + startPos, USER_REGISTERED_UUID,
362 DRM_USER_DATA_REGISTERED_UUID_SIZE) == 0) {
363 ceiStartPos = i;
364 AVCODEC_LOGD("cei found, packet start pos:%{public}d", ceiStartPos);
365 break;
366 }
367 }
368 }
369 return -1;
370 }
371
DrmFindCeiNalUnit(const uint8_t * data,uint32_t dataSize,uint32_t & ceiStartPos,uint32_t index) const372 int CodecDrmDecrypt::DrmFindCeiNalUnit(const uint8_t *data, uint32_t dataSize, uint32_t &ceiStartPos,
373 uint32_t index) const
374 {
375 int ret = 0;
376 if (codingType_ == DRM_VIDEO_AVS) {
377 ret = DrmFindAvsCeiNalUnit(data, dataSize, ceiStartPos, index);
378 } else if (codingType_ == DRM_VIDEO_HEVC) {
379 ret = DrmFindHevcCeiNalUnit(data, dataSize, ceiStartPos, index);
380 } else if (codingType_ == DRM_VIDEO_AVC) {
381 ret = DrmFindH264CeiNalUnit(data, dataSize, ceiStartPos, index);
382 }
383 return ret;
384 }
385
DrmFindCeiPos(const uint8_t * data,uint32_t dataSize,uint32_t & ceiStartPos,uint32_t & ceiEndPos) const386 int CodecDrmDecrypt::DrmFindCeiPos(const uint8_t *data, uint32_t dataSize, uint32_t &ceiStartPos,
387 uint32_t &ceiEndPos) const
388 {
389 uint32_t i;
390 for (i = 0; (i + DRM_LEGACY_LEN) < dataSize; i++) {
391 /*the start code prefix is 0x000001*/
392 if ((data[i] == VIDEO_FRAME_ARR[DRM_ARR_SUBSCRIPT_ZERO]) &&
393 (data[i + DRM_ARR_SUBSCRIPT_ONE] == VIDEO_FRAME_ARR[DRM_ARR_SUBSCRIPT_ONE]) &&
394 (data[i + DRM_ARR_SUBSCRIPT_TWO] == VIDEO_FRAME_ARR[DRM_ARR_SUBSCRIPT_TWO])) {
395 uint32_t startPos = DRM_INVALID_START_POS;
396 if (ceiStartPos != DRM_INVALID_START_POS) {
397 ceiEndPos = i;
398 AVCODEC_LOGD("cei found, start pos:%{public}x end pos:%{public}x", ceiStartPos, ceiEndPos);
399 }
400 /* found a nal unit, process nal to find the cei.*/
401 if (!DrmFindCeiNalUnit(data, dataSize, startPos, i)) {
402 break;
403 }
404 if (startPos != DRM_INVALID_START_POS) {
405 ceiStartPos = startPos;
406 ceiEndPos = DRM_INVALID_START_POS;
407 }
408 i += DRM_LEGACY_LEN;
409 }
410 }
411 if ((ceiStartPos != DRM_INVALID_START_POS) && (ceiEndPos != DRM_INVALID_START_POS) &&
412 (ceiStartPos < ceiEndPos) && (ceiEndPos <= dataSize)) {
413 return 1; // 1 true
414 }
415 return 0;
416 }
417
DrmFindEncryptionFlagPos(const uint8_t * data,uint32_t dataSize,uint32_t & pos)418 void CodecDrmDecrypt::DrmFindEncryptionFlagPos(const uint8_t *data, uint32_t dataSize, uint32_t &pos)
419 {
420 uint32_t offset = pos;
421 if (data[offset + DRM_LEGACY_LEN] == DRM_AVS_FLAG) {
422 offset += DRM_LEGACY_LEN; //skip 0x00 0x00 0x01
423 offset += 2; // 2 skip this flag
424 } else {
425 for (; (offset + DRM_USER_DATA_REGISTERED_UUID_SIZE < dataSize); offset++) {
426 if (memcmp(data + offset, USER_REGISTERED_UUID, DRM_USER_DATA_REGISTERED_UUID_SIZE) == 0) {
427 offset += DRM_USER_DATA_REGISTERED_UUID_SIZE;
428 break;
429 }
430 }
431 }
432 if (offset < dataSize) {
433 pos = offset;
434 }
435 return;
436 }
437
DrmGetKeyId(uint8_t * data,uint32_t & dataSize,uint32_t & pos,MetaDrmCencInfo * cencInfo)438 int CodecDrmDecrypt::DrmGetKeyId(uint8_t *data, uint32_t &dataSize, uint32_t &pos, MetaDrmCencInfo *cencInfo)
439 {
440 uint32_t offset = pos;
441 CHECK_AND_RETURN_RET_LOG((offset < dataSize), -1, "cei data too short");
442 uint8_t encryptionFlag = (data[offset] & 0x80) >> 7; // 0x80 get encryptionFlag & 7 get bits
443 uint8_t nextKeyIdFlag = (data[offset] & 0x40) >> 6; // 0x40 get nextKeyIdFlag & 6 get bits
444 offset += 1; // 1 skip flag
445 DrmRemoveAmbiguityBytes(data, dataSize, offset, dataSize);
446
447 if (encryptionFlag != 0) {
448 CHECK_AND_RETURN_RET_LOG(((offset + META_DRM_KEY_ID_SIZE) <= dataSize), -1, "cei data too short");
449 errno_t res = memcpy_s(cencInfo->keyId, META_DRM_KEY_ID_SIZE, data + offset, META_DRM_KEY_ID_SIZE);
450 CHECK_AND_RETURN_RET_LOG((res == EOK), -1, "copy keyid err");
451 cencInfo->keyIdLen = META_DRM_KEY_ID_SIZE;
452 offset += META_DRM_KEY_ID_SIZE;
453 } else {
454 cencInfo->algo = MetaDrmCencAlgorithm::META_DRM_ALG_CENC_UNENCRYPTED;
455 }
456 if (nextKeyIdFlag == 1) {
457 offset += META_DRM_KEY_ID_SIZE;
458 }
459 pos = offset;
460 return 0;
461 }
462
DrmGetKeyIv(const uint8_t * data,uint32_t dataSize,uint32_t & pos,MetaDrmCencInfo * cencInfo)463 int CodecDrmDecrypt::DrmGetKeyIv(const uint8_t *data, uint32_t dataSize, uint32_t &pos, MetaDrmCencInfo *cencInfo)
464 {
465 uint32_t offset = pos;
466 CHECK_AND_RETURN_RET_LOG((offset < dataSize), -1, "cei data too short");
467 uint32_t ivLen = data[offset];
468 offset += 1; // 1 skip iv len
469 if ((offset + ivLen > dataSize) || (ivLen > META_DRM_IV_SIZE)) {
470 AVCODEC_LOGE("cei data too short");
471 return -1;
472 } else {
473 errno_t res = memcpy_s(cencInfo->iv, META_DRM_IV_SIZE, data + offset, ivLen);
474 CHECK_AND_RETURN_RET_LOG((res == EOK), -1, "copy iv err");
475 cencInfo->ivLen = ivLen;
476 offset += ivLen;
477 }
478 pos = offset;
479 return 0;
480 }
481
DrmParseDrmDescriptor(const uint8_t * data,uint32_t dataSize,uint32_t & pos,uint8_t drmDescriptorFlag,MetaDrmCencInfo * cencInfo)482 int CodecDrmDecrypt::DrmParseDrmDescriptor(const uint8_t *data, uint32_t dataSize, uint32_t &pos,
483 uint8_t drmDescriptorFlag, MetaDrmCencInfo *cencInfo)
484 {
485 uint32_t offset = pos;
486 if (drmDescriptorFlag == 0) {
487 return 0;
488 }
489 CHECK_AND_RETURN_RET_LOG((offset + DRM_MIN_DRM_INFO_LEN < dataSize), -1, "cei data too short");
490 uint8_t videoAlgo = data[offset + DRM_MIN_DRM_INFO_LEN] & 0x0f; // video algo offset
491 SetDrmAlgoAndBlocks(videoAlgo, cencInfo);
492 offset = offset + DRM_MIN_DRM_INFO_LEN;
493 pos = offset;
494 return 0;
495 }
496
DrmSetKeyInfo(const uint8_t * data,uint32_t dataSize,uint32_t ceiStartPos,uint8_t & isAmbiguity,MetaDrmCencInfo * cencInfo)497 void CodecDrmDecrypt::DrmSetKeyInfo(const uint8_t *data, uint32_t dataSize, uint32_t ceiStartPos,
498 uint8_t &isAmbiguity, MetaDrmCencInfo *cencInfo)
499 {
500 uint32_t totalSize = dataSize;
501 uint32_t pos = ceiStartPos;
502 uint8_t *ceiBuf = nullptr;
503 uint8_t drmDescriptorFlag = 0;
504 uint8_t drmNotAmbiguityFlag = 0;
505 CHECK_AND_RETURN_LOG((dataSize != 0), "DrmSetKeyInfo dataSize is 0");
506 CHECK_AND_RETURN_LOG((pos + DRM_LEGACY_LEN < totalSize), "cei data too short");
507 ceiBuf = reinterpret_cast<uint8_t *>(malloc(dataSize));
508 CHECK_AND_RETURN_LOG((ceiBuf != nullptr), "malloc cei data failed");
509 errno_t res = memcpy_s(ceiBuf, dataSize, data, dataSize);
510 if (res != EOK) {
511 free(ceiBuf);
512 return;
513 }
514 DrmFindEncryptionFlagPos(ceiBuf, totalSize, pos);
515 drmDescriptorFlag = (ceiBuf[pos] & 0x20) >> 5; // 0x20 get drmDescriptorFlag & 5 get bits
516 drmNotAmbiguityFlag = (ceiBuf[pos] & 0x10) >> 4; // 0x10 get drmNotAmbiguityFlag & 4 get bits
517 if (drmNotAmbiguityFlag == 1) {
518 isAmbiguity = 0;
519 } else {
520 isAmbiguity = 1; // 1:exist ambiguity
521 }
522
523 int ret = DrmGetKeyId(ceiBuf, totalSize, pos, cencInfo);
524 if (ret == 0) {
525 ret = DrmGetKeyIv(ceiBuf, totalSize, pos, cencInfo);
526 if (ret == 0) {
527 (void)DrmParseDrmDescriptor(ceiBuf, totalSize, pos, drmDescriptorFlag, cencInfo);
528 }
529 }
530 free(ceiBuf);
531 return;
532 }
533
DrmGetCencInfo(std::shared_ptr<AVBuffer> inBuf,uint32_t dataSize,uint8_t & isAmbiguity,MetaDrmCencInfo * cencInfo) const534 void CodecDrmDecrypt::DrmGetCencInfo(std::shared_ptr<AVBuffer> inBuf, uint32_t dataSize, uint8_t &isAmbiguity,
535 MetaDrmCencInfo *cencInfo) const
536 {
537 int ret;
538 uint32_t ceiStartPos = DRM_INVALID_START_POS;
539 uint32_t ceiEndPos = DRM_INVALID_START_POS;
540 CHECK_AND_RETURN_LOG((inBuf->memory_ != nullptr && inBuf->memory_->GetAddr() != nullptr && dataSize != 0 &&
541 dataSize <= DRM_MAX_STREAM_DATA_SIZE), "DrmGetCencInfo parameter err");
542 uint8_t *data = inBuf->memory_->GetAddr();
543
544 ret = DrmFindCeiPos(data, dataSize, ceiStartPos, ceiEndPos);
545 if (ret) {
546 DrmSetKeyInfo(data, ceiEndPos, ceiStartPos, isAmbiguity, cencInfo);
547 }
548 return;
549 }
550
DrmVideoCencDecrypt(std::shared_ptr<AVBuffer> & inBuf,std::shared_ptr<AVBuffer> & outBuf,uint32_t & dataSize)551 int32_t CodecDrmDecrypt::DrmVideoCencDecrypt(std::shared_ptr<AVBuffer> &inBuf, std::shared_ptr<AVBuffer> &outBuf,
552 uint32_t &dataSize)
553 {
554 AVCODEC_LOGD("DrmVideoCencDecrypt");
555 int32_t ret = AVCS_ERR_UNKNOWN;
556 CHECK_AND_RETURN_RET_LOG((inBuf != nullptr && outBuf != nullptr), ret, "DrmVideoCencDecrypt parameter err");
557 GetCodingType();
558 if (inBuf->meta_ != nullptr) {
559 std::vector<uint8_t> drmCencVec;
560 MetaDrmCencInfo *cencInfo = nullptr;
561 MetaDrmCencInfo clearCencInfo;
562 bool res = inBuf->meta_->GetData(Media::Tag::DRM_CENC_INFO, drmCencVec);
563 if (res) {
564 cencInfo = reinterpret_cast<MetaDrmCencInfo *>(&drmCencVec[0]);
565 CHECK_AND_RETURN_RET_LOG(
566 (cencInfo->encryptBlocks <= DRM_CRYPT_BYTE_BLOCK && cencInfo->skipBlocks <= DRM_SKIP_BYTE_BLOCK),
567 ret, "DrmVideoCencDecrypt parameter err");
568 if (cencInfo->algo == MetaDrmCencAlgorithm::META_DRM_ALG_CENC_UNENCRYPTED) {
569 cencInfo->subSampleNum = 1;
570 cencInfo->subSamples[0].clearHeaderLen = dataSize;
571 cencInfo->subSamples[0].payLoadLen = 0;
572 }
573 } else {
574 errno_t errCode = memset_s(&clearCencInfo, sizeof(MetaDrmCencInfo), 0, sizeof(MetaDrmCencInfo));
575 CHECK_AND_RETURN_RET_LOG(errCode == EOK, ret, "memset cenc info err");
576 clearCencInfo.algo = MetaDrmCencAlgorithm::META_DRM_ALG_CENC_UNENCRYPTED;
577 clearCencInfo.subSampleNum = 1;
578 clearCencInfo.subSamples[0].clearHeaderLen = dataSize;
579 clearCencInfo.subSamples[0].payLoadLen = 0;
580 cencInfo = reinterpret_cast<MetaDrmCencInfo *>(&clearCencInfo);
581 }
582 if (cencInfo->mode == MetaDrmCencInfoMode::META_DRM_CENC_INFO_KEY_IV_SUBSAMPLES_NOT_SET ||
583 mode_ == MetaDrmCencInfoMode::META_DRM_CENC_INFO_KEY_IV_SUBSAMPLES_NOT_SET) {
584 uint8_t isAmbiguity = 1;
585 DrmGetCencInfo(inBuf, dataSize, isAmbiguity, cencInfo);
586 DrmModifyCencInfo(inBuf, dataSize, isAmbiguity, cencInfo);
587 cencInfo->subSampleNum = DRM_TS_SUB_SAMPLE_NUM;
588 mode_ = cencInfo->mode;
589 }
590 ret = DecryptMediaData(cencInfo, inBuf, outBuf);
591 }
592 return ret;
593 }
594
DrmAudioCencDecrypt(std::shared_ptr<AVBuffer> & inBuf,std::shared_ptr<AVBuffer> & outBuf,uint32_t & dataSize)595 int32_t CodecDrmDecrypt::DrmAudioCencDecrypt(std::shared_ptr<AVBuffer> &inBuf, std::shared_ptr<AVBuffer> &outBuf,
596 uint32_t &dataSize)
597 {
598 AVCODEC_LOGD("DrmAudioCencDecrypt");
599 int32_t ret = AVCS_ERR_UNKNOWN;
600 CHECK_AND_RETURN_RET_LOG((inBuf != nullptr && outBuf != nullptr), ret, "DrmCencDecrypt parameter err");
601 CHECK_AND_RETURN_RET_LOG((inBuf->meta_ != nullptr), ret, "DrmCencDecrypt meta null");
602
603 std::vector<uint8_t> drmCencVec;
604 MetaDrmCencInfo *cencInfo = nullptr;
605 MetaDrmCencInfo clearCencInfo;
606 bool res = inBuf->meta_->GetData(Media::Tag::DRM_CENC_INFO, drmCencVec);
607 if (res) {
608 cencInfo = reinterpret_cast<MetaDrmCencInfo *>(&drmCencVec[0]);
609 if (cencInfo->algo == MetaDrmCencAlgorithm::META_DRM_ALG_CENC_UNENCRYPTED) {
610 cencInfo->subSampleNum = 1;
611 cencInfo->subSamples[0].clearHeaderLen = dataSize;
612 cencInfo->subSamples[0].payLoadLen = 0;
613 }
614 if (cencInfo->subSampleNum == 0) {
615 if (cencInfo->algo == MetaDrmCencAlgorithm::META_DRM_ALG_CENC_AES_CTR ||
616 cencInfo->algo == MetaDrmCencAlgorithm::META_DRM_ALG_CENC_SM4_CTR) {
617 cencInfo->subSampleNum = 1; // 1: subSampleNum
618 cencInfo->subSamples[0].clearHeaderLen = 0;
619 cencInfo->subSamples[0].payLoadLen = dataSize;
620 }
621 if (cencInfo->algo == MetaDrmCencAlgorithm::META_DRM_ALG_CENC_AES_CBC ||
622 cencInfo->algo == MetaDrmCencAlgorithm::META_DRM_ALG_CENC_SM4_CBC) {
623 cencInfo->subSampleNum = 2; // 2: subSampleNum
624 cencInfo->subSamples[0].clearHeaderLen = 0;
625 cencInfo->subSamples[0].payLoadLen = (dataSize / 16) * 16; // 16: BlockSize
626 cencInfo->subSamples[1].clearHeaderLen = dataSize % 16; // 16: BlockSize
627 cencInfo->subSamples[1].payLoadLen = 0;
628 }
629 }
630 } else {
631 errno_t errCode = memset_s(&clearCencInfo, sizeof(MetaDrmCencInfo), 0, sizeof(MetaDrmCencInfo));
632 CHECK_AND_RETURN_RET_LOG(errCode == EOK, ret, "memset cenc info err");
633 clearCencInfo.algo = MetaDrmCencAlgorithm::META_DRM_ALG_CENC_UNENCRYPTED;
634 clearCencInfo.subSampleNum = 1;
635 clearCencInfo.subSamples[0].clearHeaderLen = dataSize;
636 clearCencInfo.subSamples[0].payLoadLen = 0;
637 cencInfo = reinterpret_cast<MetaDrmCencInfo *>(&clearCencInfo);
638 }
639 ret = DecryptMediaData(cencInfo, inBuf, outBuf);
640
641 return ret;
642 }
643
SetCodecName(const std::string & codecName)644 void CodecDrmDecrypt::SetCodecName(const std::string &codecName)
645 {
646 codecName_ = codecName;
647 }
648
GetCodingType()649 void CodecDrmDecrypt::GetCodingType()
650 {
651 codingType_ = DRM_VIDEO_NONE;
652 if (codecName_.find("avc") != codecName_.npos) {
653 codingType_ = DRM_VIDEO_AVC;
654 } else if (codecName_.find("hevc") != codecName_.npos) {
655 codingType_ = DRM_VIDEO_HEVC;
656 } else if (codecName_.find("avs") != codecName_.npos) {
657 codingType_ = DRM_VIDEO_AVS;
658 }
659 }
660
SetDecryptionConfig(const sptr<DrmStandard::IMediaKeySessionService> & keySession,const bool svpFlag)661 void CodecDrmDecrypt::SetDecryptionConfig(const sptr<DrmStandard::IMediaKeySessionService> &keySession,
662 const bool svpFlag)
663 {
664 AVCODEC_LOGI("CodecDrmDecrypt SetDecryptConfig");
665 std::lock_guard<std::mutex> drmLock(configMutex_);
666 if (svpFlag) {
667 svpFlag_ = SVP_TRUE;
668 } else {
669 svpFlag_ = SVP_FALSE;
670 }
671 mode_ = MetaDrmCencInfoMode::META_DRM_CENC_INFO_KEY_IV_SUBSAMPLES_SET;
672 #ifdef SUPPORT_DRM
673 keySessionServiceProxy_ = keySession;
674 CHECK_AND_RETURN_LOG((keySessionServiceProxy_ != nullptr), "SetDecryptConfig keySessionServiceProxy nullptr");
675 keySessionServiceProxy_->GetMediaDecryptModule(decryptModuleProxy_);
676 CHECK_AND_RETURN_LOG((decryptModuleProxy_ != nullptr), "SetDecryptConfig decryptModuleProxy_ nullptr");
677 #else
678 (void)keySession;
679 (void)svpFlag;
680 #endif
681 }
682
683 #ifdef SUPPORT_DRM
SetDrmBuffer(const MetaDrmCencInfo * const cencInfo,const std::shared_ptr<AVBuffer> & inBuf,const std::shared_ptr<AVBuffer> & outBuf) const684 int32_t CodecDrmDecrypt::SetDrmBuffer(const MetaDrmCencInfo * const cencInfo, const std::shared_ptr<AVBuffer> &inBuf,
685 const std::shared_ptr<AVBuffer> &outBuf) const
686 {
687 AVCODEC_LOGD("CodecDrmDecrypt SetDrmBuffer");
688 DrmBuffer inDrmBuffer;
689 DrmBuffer outDrmBuffer;
690 int32_t retCode = AVCS_ERR_INVALID_VAL;
691 DrmStandard::IMediaDecryptModuleService::CryptInfo cryptInfo;
692 CHECK_AND_RETURN_RET_LOG((inBuf->memory_ != nullptr && outBuf->memory_ != nullptr), AVCS_ERR_NO_MEMORY,
693 "CodecDrmDecrypt SetDrmBuffer memory_ null");
694 inDrmBuffer.bufferType = static_cast<uint32_t>(inBuf->memory_->GetMemoryType());
695 inDrmBuffer.fd = inBuf->memory_->GetFileDescriptor();
696 inDrmBuffer.bufferLen = static_cast<uint32_t>(inBuf->memory_->GetSize());
697 CHECK_AND_RETURN_RET_LOG((inBuf->memory_->GetCapacity() >= 0), AVCS_ERR_NO_MEMORY,
698 "CodecDrmDecrypt SetDrmBuffer input buffer failed due to GetCapacity() return -1");
699 inDrmBuffer.allocLen = static_cast<uint32_t>(inBuf->memory_->GetCapacity());
700 inDrmBuffer.filledLen = static_cast<uint32_t>(inBuf->memory_->GetSize());
701 inDrmBuffer.offset = static_cast<uint32_t>(inBuf->memory_->GetOffset());
702 inDrmBuffer.sharedMemType = static_cast<uint32_t>(inBuf->memory_->GetMemoryFlag());
703
704 outDrmBuffer.bufferType = static_cast<uint32_t>(outBuf->memory_->GetMemoryType());
705 outDrmBuffer.fd = outBuf->memory_->GetFileDescriptor();
706 outDrmBuffer.bufferLen = static_cast<uint32_t>(outBuf->memory_->GetSize());
707 CHECK_AND_RETURN_RET_LOG((outBuf->memory_->GetCapacity() >= 0), AVCS_ERR_NO_MEMORY,
708 "CodecDrmDecrypt SetDrmBuffer output buffer failed due to GetCapacity() return -1");
709 outDrmBuffer.allocLen = static_cast<uint32_t>(outBuf->memory_->GetCapacity());
710 outDrmBuffer.filledLen = static_cast<uint32_t>(outBuf->memory_->GetSize());
711 outDrmBuffer.offset = static_cast<uint32_t>(outBuf->memory_->GetOffset());
712 outDrmBuffer.sharedMemType = static_cast<uint32_t>(outBuf->memory_->GetMemoryFlag());
713
714 cryptInfo.type = static_cast<DrmStandard::IMediaDecryptModuleService::CryptAlgorithmType>(cencInfo->algo);
715 std::vector<uint8_t> keyIdVector(cencInfo->keyId, cencInfo->keyId + cencInfo->keyIdLen);
716 cryptInfo.keyId = keyIdVector;
717 std::vector<uint8_t> ivVector(cencInfo->iv, cencInfo->iv + cencInfo->ivLen);
718 cryptInfo.iv = ivVector;
719 cryptInfo.pattern.encryptBlocks = cencInfo->encryptBlocks;
720 cryptInfo.pattern.skipBlocks = cencInfo->skipBlocks;
721
722 for (uint32_t i = 0; i < cencInfo->subSampleNum; i++) {
723 DrmStandard::IMediaDecryptModuleService::SubSample temp({ cencInfo->subSamples[i].clearHeaderLen,
724 cencInfo->subSamples[i].payLoadLen });
725 cryptInfo.subSample.emplace_back(temp);
726 }
727 CHECK_AND_RETURN_RET_LOG((decryptModuleProxy_ != nullptr), retCode,
728 "SetDecryptConfig decryptModuleProxy_ nullptr");
729 // LCOV_EXCL_START
730 retCode = decryptModuleProxy_->DecryptMediaData(svpFlag_, cryptInfo, inDrmBuffer, outDrmBuffer);
731 CHECK_AND_RETURN_RET_LOG((retCode == 0), AVCS_ERR_UNKNOWN, "CodecDrmDecrypt decrypt failed!");
732 return AVCS_ERR_OK;
733 // LCOV_EXCL_STOP
734 }
735 #endif
736
DecryptMediaData(const MetaDrmCencInfo * const cencInfo,std::shared_ptr<AVBuffer> & inBuf,std::shared_ptr<AVBuffer> & outBuf)737 int32_t CodecDrmDecrypt::DecryptMediaData(const MetaDrmCencInfo * const cencInfo, std::shared_ptr<AVBuffer> &inBuf,
738 std::shared_ptr<AVBuffer> &outBuf)
739 {
740 AVCODEC_LOGI("CodecDrmDecrypt DecryptMediaData");
741 #ifdef SUPPORT_DRM
742 std::lock_guard<std::mutex> drmLock(configMutex_);
743 int32_t retCode = AVCS_ERR_INVALID_VAL;
744
745 CHECK_AND_RETURN_RET_LOG(((cencInfo != nullptr) &&
746 (cencInfo->keyIdLen <= static_cast<uint32_t>(META_DRM_KEY_ID_SIZE)) &&
747 (cencInfo->ivLen <= static_cast<uint32_t>(META_DRM_IV_SIZE)) &&
748 (cencInfo->subSampleNum <= static_cast<uint32_t>(META_DRM_MAX_SUB_SAMPLE_NUM))), retCode, "parameter err");
749
750 retCode = SetDrmBuffer(cencInfo, inBuf, outBuf);
751 CHECK_AND_RETURN_RET_LOG((retCode == AVCS_ERR_OK), retCode, "SetDecryptConfig failed cause SetDrmBuffer failed");
752 // LCOV_EXCL_START
753 return AVCS_ERR_OK;
754 // LCOV_EXCL_STOP
755 #else
756 (void)cencInfo;
757 (void)inBuf;
758 (void)outBuf;
759 return AVCS_ERR_OK;
760 #endif
761 }
762
763 } // namespace MediaAVCodec
764 } // namespace OHOS
765