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