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 "avcodec_errors.h"
17 #include "avcodec_log.h"
18 #include "meta/meta.h"
19 #include "common/native_mfmagic.h"
20 #include "securec.h"
21 #include "native_cencinfo.h"
22
23 namespace {
24 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_FRAMEWORK, "NativeAVCencInfo"};
25 }
26
27 using namespace OHOS::MediaAVCodec;
28 using namespace OHOS::Media;
29 using MetaDrmCencInfo = Plugins::MetaDrmCencInfo;
30 using MetaDrmCencAlgorithm = Plugins::MetaDrmCencAlgorithm;
31 using MetaDrmCencInfoMode = Plugins::MetaDrmCencInfoMode;
32
33 struct OH_AVCencInfo {
OH_AVCencInfoOH_AVCencInfo34 explicit OH_AVCencInfo()
35 {
36 cencInfo_.algo = MetaDrmCencAlgorithm::META_DRM_ALG_CENC_UNENCRYPTED;
37 for (int32_t i = 0; i < META_DRM_KEY_ID_SIZE; i++) {
38 cencInfo_.keyId[i] = 0;
39 }
40 cencInfo_.keyIdLen = 0;
41 for (int32_t i = 0; i < META_DRM_IV_SIZE; i++) {
42 cencInfo_.iv[i] = 0;
43 }
44 cencInfo_.ivLen = 0;
45 cencInfo_.encryptBlocks = 0;
46 cencInfo_.skipBlocks = 0;
47 cencInfo_.firstEncryptOffset = 0;
48 cencInfo_.subSamples[0].clearHeaderLen = 0;
49 cencInfo_.subSamples[0].payLoadLen = 0;
50 cencInfo_.subSampleNum = 1;
51 cencInfo_.mode = MetaDrmCencInfoMode::META_DRM_CENC_INFO_KEY_IV_SUBSAMPLES_SET;
52 }
53 ~OH_AVCencInfo() = default;
54
55 MetaDrmCencInfo cencInfo_;
56 };
57
58 #ifdef __cplusplus
59 extern "C" {
60 #endif
61
OH_AVCencInfo_Create()62 OH_AVCencInfo *OH_AVCencInfo_Create()
63 {
64 struct OH_AVCencInfo *cencInfoObject = new (std::nothrow) OH_AVCencInfo();
65 CHECK_AND_RETURN_RET_LOG(cencInfoObject != nullptr, nullptr, "failed to new OH_AVCencInfo");
66
67 int ret = memset_s(&(cencInfoObject->cencInfo_), sizeof(MetaDrmCencInfo), 0, sizeof(MetaDrmCencInfo));
68 if (ret != EOK) {
69 AVCODEC_LOGE("failed to memset OH_AVCencInfo");
70 delete cencInfoObject;
71 return nullptr;
72 }
73 return cencInfoObject;
74 }
75
OH_AVCencInfo_Destroy(OH_AVCencInfo * cencInfo)76 OH_AVErrCode OH_AVCencInfo_Destroy(OH_AVCencInfo *cencInfo)
77 {
78 CHECK_AND_RETURN_RET_LOG(cencInfo != nullptr, AV_ERR_INVALID_VAL, "input cencInfo is nullptr!");
79 delete cencInfo;
80 return AV_ERR_OK;
81 }
82
OH_AVCencInfo_SetAlgorithm(OH_AVCencInfo * cencInfo,enum DrmCencAlgorithm algo)83 OH_AVErrCode OH_AVCencInfo_SetAlgorithm(OH_AVCencInfo *cencInfo, enum DrmCencAlgorithm algo)
84 {
85 CHECK_AND_RETURN_RET_LOG(cencInfo != nullptr, AV_ERR_INVALID_VAL, "input cencInfo is nullptr!");
86 struct OH_AVCencInfo *cencInfoObject = cencInfo;
87
88 switch (algo) {
89 case DRM_ALG_CENC_UNENCRYPTED:
90 cencInfoObject->cencInfo_.algo = MetaDrmCencAlgorithm::META_DRM_ALG_CENC_UNENCRYPTED;
91 break;
92 case DRM_ALG_CENC_AES_CTR:
93 cencInfoObject->cencInfo_.algo = MetaDrmCencAlgorithm::META_DRM_ALG_CENC_AES_CTR;
94 break;
95 case DRM_ALG_CENC_AES_WV:
96 cencInfoObject->cencInfo_.algo = MetaDrmCencAlgorithm::META_DRM_ALG_CENC_AES_WV;
97 break;
98 case DRM_ALG_CENC_AES_CBC:
99 cencInfoObject->cencInfo_.algo = MetaDrmCencAlgorithm::META_DRM_ALG_CENC_AES_CBC;
100 break;
101 case DRM_ALG_CENC_SM4_CBC:
102 cencInfoObject->cencInfo_.algo = MetaDrmCencAlgorithm::META_DRM_ALG_CENC_SM4_CBC;
103 break;
104 case DRM_ALG_CENC_SM4_CTR:
105 cencInfoObject->cencInfo_.algo = MetaDrmCencAlgorithm::META_DRM_ALG_CENC_SM4_CTR;
106 break;
107 default:
108 cencInfoObject->cencInfo_.algo = MetaDrmCencAlgorithm::META_DRM_ALG_CENC_UNENCRYPTED;
109 break;
110 }
111 return AV_ERR_OK;
112 }
113
OH_AVCencInfo_SetKeyIdAndIv(OH_AVCencInfo * cencInfo,uint8_t * keyId,uint32_t keyIdLen,uint8_t * iv,uint32_t ivLen)114 OH_AVErrCode OH_AVCencInfo_SetKeyIdAndIv(OH_AVCencInfo *cencInfo, uint8_t *keyId,
115 uint32_t keyIdLen, uint8_t *iv, uint32_t ivLen)
116 {
117 CHECK_AND_RETURN_RET_LOG(cencInfo != nullptr, AV_ERR_INVALID_VAL, "input cencInfo is nullptr!");
118 CHECK_AND_RETURN_RET_LOG(keyId != nullptr, AV_ERR_INVALID_VAL, "input keyId is nullptr!");
119 CHECK_AND_RETURN_RET_LOG(keyIdLen == DRM_KEY_ID_SIZE, AV_ERR_INVALID_VAL, "input keyIdLen is err!");
120 CHECK_AND_RETURN_RET_LOG(iv != nullptr, AV_ERR_INVALID_VAL, "input iv is nullptr!");
121 CHECK_AND_RETURN_RET_LOG(ivLen == DRM_KEY_IV_SIZE, AV_ERR_INVALID_VAL, "input ivLen is err!");
122 struct OH_AVCencInfo *cencInfoObject = cencInfo;
123
124 cencInfoObject->cencInfo_.keyIdLen = keyIdLen;
125 int ret = memcpy_s(cencInfoObject->cencInfo_.keyId, sizeof(cencInfoObject->cencInfo_.keyId), keyId, keyIdLen);
126 if (ret != EOK) {
127 AVCODEC_LOGE("failed to memcpy keyId");
128 return AV_ERR_INVALID_VAL;
129 }
130
131 cencInfoObject->cencInfo_.ivLen = ivLen;
132 ret = memcpy_s(cencInfoObject->cencInfo_.iv, sizeof(cencInfoObject->cencInfo_.iv), iv, ivLen);
133 if (ret != EOK) {
134 AVCODEC_LOGE("failed to memcpy iv");
135 return AV_ERR_INVALID_VAL;
136 }
137 return AV_ERR_OK;
138 }
139
OH_AVCencInfo_SetSubsampleInfo(OH_AVCencInfo * cencInfo,uint32_t encryptedBlockCount,uint32_t skippedBlockCount,uint32_t firstEncryptedOffset,uint32_t subsampleCount,DrmSubsample * subsamples)140 OH_AVErrCode OH_AVCencInfo_SetSubsampleInfo(OH_AVCencInfo *cencInfo, uint32_t encryptedBlockCount,
141 uint32_t skippedBlockCount, uint32_t firstEncryptedOffset, uint32_t subsampleCount, DrmSubsample *subsamples)
142 {
143 CHECK_AND_RETURN_RET_LOG(cencInfo != nullptr, AV_ERR_INVALID_VAL, "input cencInfo is nullptr!");
144 CHECK_AND_RETURN_RET_LOG(subsampleCount <= DRM_KEY_MAX_SUB_SAMPLE_NUM, AV_ERR_INVALID_VAL,
145 "input subsampleCount is err!");
146 CHECK_AND_RETURN_RET_LOG(subsamples != nullptr, AV_ERR_INVALID_VAL, "input subsamples is nullptr!");
147 struct OH_AVCencInfo *cencInfoObject = cencInfo;
148
149 cencInfoObject->cencInfo_.encryptBlocks = encryptedBlockCount;
150 cencInfoObject->cencInfo_.skipBlocks = skippedBlockCount;
151 cencInfoObject->cencInfo_.firstEncryptOffset = firstEncryptedOffset;
152 cencInfoObject->cencInfo_.subSampleNum = subsampleCount;
153 for (uint32_t i = 0; i < subsampleCount; i++) {
154 cencInfoObject->cencInfo_.subSamples[i].clearHeaderLen = subsamples[i].clearHeaderLen;
155 cencInfoObject->cencInfo_.subSamples[i].payLoadLen = subsamples[i].payLoadLen;
156 }
157 return AV_ERR_OK;
158 }
159
OH_AVCencInfo_SetMode(OH_AVCencInfo * cencInfo,enum DrmCencInfoMode mode)160 OH_AVErrCode OH_AVCencInfo_SetMode(OH_AVCencInfo *cencInfo, enum DrmCencInfoMode mode)
161 {
162 CHECK_AND_RETURN_RET_LOG(cencInfo != nullptr, AV_ERR_INVALID_VAL, "input cencInfo is nullptr!");
163 struct OH_AVCencInfo *cencInfoObject = cencInfo;
164
165 switch (mode) {
166 case DRM_CENC_INFO_KEY_IV_SUBSAMPLES_SET:
167 cencInfoObject->cencInfo_.mode = MetaDrmCencInfoMode::META_DRM_CENC_INFO_KEY_IV_SUBSAMPLES_SET;
168 break;
169 case DRM_CENC_INFO_KEY_IV_SUBSAMPLES_NOT_SET:
170 cencInfoObject->cencInfo_.mode = MetaDrmCencInfoMode::META_DRM_CENC_INFO_KEY_IV_SUBSAMPLES_NOT_SET;
171 break;
172 default:
173 cencInfoObject->cencInfo_.mode = MetaDrmCencInfoMode::META_DRM_CENC_INFO_KEY_IV_SUBSAMPLES_SET;
174 break;
175 }
176 return AV_ERR_OK;
177 }
178
OH_AVCencInfo_SetAVBuffer(OH_AVCencInfo * cencInfo,OH_AVBuffer * buffer)179 OH_AVErrCode OH_AVCencInfo_SetAVBuffer(OH_AVCencInfo *cencInfo, OH_AVBuffer *buffer)
180 {
181 CHECK_AND_RETURN_RET_LOG(cencInfo != nullptr, AV_ERR_INVALID_VAL, "input cencInfo is nullptr!");
182 CHECK_AND_RETURN_RET_LOG(buffer != nullptr && buffer->buffer_ != nullptr && buffer->buffer_->meta_ != nullptr,
183 AV_ERR_INVALID_VAL, "input buffer is nullptr!");
184 struct OH_AVCencInfo *cencInfoObject = cencInfo;
185
186 std::vector<uint8_t> cencInfoVec(reinterpret_cast<uint8_t *>(&(cencInfoObject->cencInfo_)),
187 (reinterpret_cast<uint8_t *>(&(cencInfoObject->cencInfo_))) + sizeof(MetaDrmCencInfo));
188 buffer->buffer_->meta_->SetData(Tag::DRM_CENC_INFO, std::move(cencInfoVec));
189 return AV_ERR_OK;
190 }
191
192 #ifdef __cplusplus
193 };
194 #endif