1 /* 2 * Copyright 2016, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 //#define LOG_NDEBUG 0 18 #define LOG_TAG "ACodecBufferChannel" 19 #include <utils/Log.h> 20 21 #include <numeric> 22 23 #include <android/hardware/cas/native/1.0/IDescrambler.h> 24 #include <binder/MemoryDealer.h> 25 #include <hidlmemory/FrameworkUtils.h> 26 #include <media/openmax/OMX_Core.h> 27 #include <media/stagefright/foundation/AMessage.h> 28 #include <media/stagefright/foundation/AUtils.h> 29 #include <media/stagefright/MediaCodec.h> 30 #include <media/MediaCodecBuffer.h> 31 #include <system/window.h> 32 33 #include "include/ACodecBufferChannel.h" 34 #include "include/SecureBuffer.h" 35 #include "include/SharedMemoryBuffer.h" 36 37 namespace android { 38 using hardware::fromHeap; 39 using hardware::hidl_handle; 40 using hardware::hidl_string; 41 using hardware::hidl_vec; 42 using namespace hardware::cas::V1_0; 43 using namespace hardware::cas::native::V1_0; 44 using BufferInfo = ACodecBufferChannel::BufferInfo; 45 using BufferInfoIterator = std::vector<const BufferInfo>::const_iterator; 46 47 ACodecBufferChannel::~ACodecBufferChannel() { 48 if (mCrypto != nullptr && mDealer != nullptr && mHeapSeqNum >= 0) { 49 mCrypto->unsetHeap(mHeapSeqNum); 50 } 51 } 52 53 static BufferInfoIterator findClientBuffer( 54 const std::shared_ptr<const std::vector<const BufferInfo>> &array, 55 const sp<MediaCodecBuffer> &buffer) { 56 return std::find_if( 57 array->begin(), array->end(), 58 [buffer](const BufferInfo &info) { return info.mClientBuffer == buffer; }); 59 } 60 61 static BufferInfoIterator findBufferId( 62 const std::shared_ptr<const std::vector<const BufferInfo>> &array, 63 IOMX::buffer_id bufferId) { 64 return std::find_if( 65 array->begin(), array->end(), 66 [bufferId](const BufferInfo &info) { return bufferId == info.mBufferId; }); 67 } 68 69 ACodecBufferChannel::BufferInfo::BufferInfo( 70 const sp<MediaCodecBuffer> &buffer, 71 IOMX::buffer_id bufferId, 72 const sp<IMemory> &sharedEncryptedBuffer) 73 : mClientBuffer( 74 (sharedEncryptedBuffer == nullptr) 75 ? buffer 76 : new SharedMemoryBuffer(buffer->format(), sharedEncryptedBuffer)), 77 mCodecBuffer(buffer), 78 mBufferId(bufferId), 79 mSharedEncryptedBuffer(sharedEncryptedBuffer) { 80 } 81 82 ACodecBufferChannel::ACodecBufferChannel( 83 const sp<AMessage> &inputBufferFilled, const sp<AMessage> &outputBufferDrained) 84 : mInputBufferFilled(inputBufferFilled), 85 mOutputBufferDrained(outputBufferDrained), 86 mHeapSeqNum(-1) { 87 } 88 89 status_t ACodecBufferChannel::queueInputBuffer(const sp<MediaCodecBuffer> &buffer) { 90 if (mDealer != nullptr) { 91 return -ENOSYS; 92 } 93 std::shared_ptr<const std::vector<const BufferInfo>> array( 94 std::atomic_load(&mInputBuffers)); 95 BufferInfoIterator it = findClientBuffer(array, buffer); 96 if (it == array->end()) { 97 return -ENOENT; 98 } 99 ALOGV("queueInputBuffer #%d", it->mBufferId); 100 sp<AMessage> msg = mInputBufferFilled->dup(); 101 msg->setObject("buffer", it->mCodecBuffer); 102 msg->setInt32("buffer-id", it->mBufferId); 103 msg->post(); 104 return OK; 105 } 106 107 status_t ACodecBufferChannel::queueSecureInputBuffer( 108 const sp<MediaCodecBuffer> &buffer, bool secure, const uint8_t *key, 109 const uint8_t *iv, CryptoPlugin::Mode mode, CryptoPlugin::Pattern pattern, 110 const CryptoPlugin::SubSample *subSamples, size_t numSubSamples, 111 AString *errorDetailMsg) { 112 if (!hasCryptoOrDescrambler() || mDealer == nullptr) { 113 return -ENOSYS; 114 } 115 std::shared_ptr<const std::vector<const BufferInfo>> array( 116 std::atomic_load(&mInputBuffers)); 117 BufferInfoIterator it = findClientBuffer(array, buffer); 118 if (it == array->end()) { 119 return -ENOENT; 120 } 121 122 native_handle_t *secureHandle = NULL; 123 if (secure) { 124 sp<SecureBuffer> secureData = 125 static_cast<SecureBuffer *>(it->mCodecBuffer.get()); 126 if (secureData->getDestinationType() != ICrypto::kDestinationTypeNativeHandle) { 127 return BAD_VALUE; 128 } 129 secureHandle = static_cast<native_handle_t *>(secureData->getDestinationPointer()); 130 } 131 ssize_t result = -1; 132 ssize_t codecDataOffset = 0; 133 if (mCrypto != NULL) { 134 ICrypto::DestinationBuffer destination; 135 if (secure) { 136 destination.mType = ICrypto::kDestinationTypeNativeHandle; 137 destination.mHandle = secureHandle; 138 } else { 139 destination.mType = ICrypto::kDestinationTypeSharedMemory; 140 destination.mSharedMemory = mDecryptDestination; 141 } 142 143 ICrypto::SourceBuffer source; 144 source.mSharedMemory = it->mSharedEncryptedBuffer; 145 source.mHeapSeqNum = mHeapSeqNum; 146 147 result = mCrypto->decrypt(key, iv, mode, pattern, 148 source, it->mClientBuffer->offset(), 149 subSamples, numSubSamples, destination, errorDetailMsg); 150 151 if (result < 0) { 152 return result; 153 } 154 155 if (destination.mType == ICrypto::kDestinationTypeSharedMemory) { 156 memcpy(it->mCodecBuffer->base(), destination.mSharedMemory->pointer(), result); 157 } 158 } else { 159 // Here we cast CryptoPlugin::SubSample to hardware::cas::native::V1_0::SubSample 160 // directly, the structure definitions should match as checked in DescramblerImpl.cpp. 161 hidl_vec<SubSample> hidlSubSamples; 162 hidlSubSamples.setToExternal((SubSample *)subSamples, numSubSamples, false /*own*/); 163 164 ssize_t offset; 165 size_t size; 166 it->mSharedEncryptedBuffer->getMemory(&offset, &size); 167 hardware::cas::native::V1_0::SharedBuffer srcBuffer = { 168 .heapBase = *mHidlMemory, 169 .offset = (uint64_t) offset, 170 .size = size 171 }; 172 173 DestinationBuffer dstBuffer; 174 if (secure) { 175 dstBuffer.type = BufferType::NATIVE_HANDLE; 176 dstBuffer.secureMemory = hidl_handle(secureHandle); 177 } else { 178 dstBuffer.type = BufferType::SHARED_MEMORY; 179 dstBuffer.nonsecureMemory = srcBuffer; 180 } 181 182 Status status = Status::OK; 183 hidl_string detailedError; 184 ScramblingControl sctrl = ScramblingControl::UNSCRAMBLED; 185 186 if (key != NULL) { 187 sctrl = (ScramblingControl)key[0]; 188 // Adjust for the PES offset 189 codecDataOffset = key[2] | (key[3] << 8); 190 } 191 192 auto returnVoid = mDescrambler->descramble( 193 sctrl, 194 hidlSubSamples, 195 srcBuffer, 196 0, 197 dstBuffer, 198 0, 199 [&status, &result, &detailedError] ( 200 Status _status, uint32_t _bytesWritten, 201 const hidl_string& _detailedError) { 202 status = _status; 203 result = (ssize_t)_bytesWritten; 204 detailedError = _detailedError; 205 }); 206 207 if (!returnVoid.isOk() || status != Status::OK || result < 0) { 208 ALOGE("descramble failed, trans=%s, status=%d, result=%zd", 209 returnVoid.description().c_str(), status, result); 210 return UNKNOWN_ERROR; 211 } 212 213 if (result < codecDataOffset) { 214 ALOGD("invalid codec data offset: %zd, result %zd", codecDataOffset, result); 215 return BAD_VALUE; 216 } 217 218 ALOGV("descramble succeeded, %zd bytes", result); 219 220 if (dstBuffer.type == BufferType::SHARED_MEMORY) { 221 memcpy(it->mCodecBuffer->base(), 222 (uint8_t*)it->mSharedEncryptedBuffer->pointer(), result); 223 } 224 } 225 226 it->mCodecBuffer->setRange(codecDataOffset, result - codecDataOffset); 227 228 // Copy metadata from client to codec buffer. 229 it->mCodecBuffer->meta()->clear(); 230 int64_t timeUs; 231 CHECK(it->mClientBuffer->meta()->findInt64("timeUs", &timeUs)); 232 it->mCodecBuffer->meta()->setInt64("timeUs", timeUs); 233 int32_t eos; 234 if (it->mClientBuffer->meta()->findInt32("eos", &eos)) { 235 it->mCodecBuffer->meta()->setInt32("eos", eos); 236 } 237 int32_t csd; 238 if (it->mClientBuffer->meta()->findInt32("csd", &csd)) { 239 it->mCodecBuffer->meta()->setInt32("csd", csd); 240 } 241 242 ALOGV("queueSecureInputBuffer #%d", it->mBufferId); 243 sp<AMessage> msg = mInputBufferFilled->dup(); 244 msg->setObject("buffer", it->mCodecBuffer); 245 msg->setInt32("buffer-id", it->mBufferId); 246 msg->post(); 247 return OK; 248 } 249 250 status_t ACodecBufferChannel::renderOutputBuffer( 251 const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) { 252 std::shared_ptr<const std::vector<const BufferInfo>> array( 253 std::atomic_load(&mOutputBuffers)); 254 BufferInfoIterator it = findClientBuffer(array, buffer); 255 if (it == array->end()) { 256 return -ENOENT; 257 } 258 259 ALOGV("renderOutputBuffer #%d", it->mBufferId); 260 sp<AMessage> msg = mOutputBufferDrained->dup(); 261 msg->setObject("buffer", buffer); 262 msg->setInt32("buffer-id", it->mBufferId); 263 msg->setInt32("render", true); 264 msg->setInt64("timestampNs", timestampNs); 265 msg->post(); 266 return OK; 267 } 268 269 status_t ACodecBufferChannel::discardBuffer(const sp<MediaCodecBuffer> &buffer) { 270 std::shared_ptr<const std::vector<const BufferInfo>> array( 271 std::atomic_load(&mInputBuffers)); 272 bool input = true; 273 BufferInfoIterator it = findClientBuffer(array, buffer); 274 if (it == array->end()) { 275 array = std::atomic_load(&mOutputBuffers); 276 input = false; 277 it = findClientBuffer(array, buffer); 278 if (it == array->end()) { 279 return -ENOENT; 280 } 281 } 282 ALOGV("discardBuffer #%d", it->mBufferId); 283 sp<AMessage> msg = input ? mInputBufferFilled->dup() : mOutputBufferDrained->dup(); 284 msg->setObject("buffer", it->mCodecBuffer); 285 msg->setInt32("buffer-id", it->mBufferId); 286 msg->setInt32("discarded", true); 287 msg->post(); 288 return OK; 289 } 290 291 void ACodecBufferChannel::getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) { 292 std::shared_ptr<const std::vector<const BufferInfo>> inputBuffers( 293 std::atomic_load(&mInputBuffers)); 294 array->clear(); 295 for (const BufferInfo &elem : *inputBuffers) { 296 array->push_back(elem.mClientBuffer); 297 } 298 } 299 300 void ACodecBufferChannel::getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) { 301 std::shared_ptr<const std::vector<const BufferInfo>> outputBuffers( 302 std::atomic_load(&mOutputBuffers)); 303 array->clear(); 304 for (const BufferInfo &elem : *outputBuffers) { 305 array->push_back(elem.mClientBuffer); 306 } 307 } 308 309 sp<MemoryDealer> ACodecBufferChannel::makeMemoryDealer(size_t heapSize) { 310 sp<MemoryDealer> dealer; 311 if (mDealer != nullptr && mCrypto != nullptr && mHeapSeqNum >= 0) { 312 mCrypto->unsetHeap(mHeapSeqNum); 313 } 314 dealer = new MemoryDealer(heapSize, "ACodecBufferChannel"); 315 if (mCrypto != nullptr) { 316 int32_t seqNum = mCrypto->setHeap(dealer->getMemoryHeap()); 317 if (seqNum >= 0) { 318 mHeapSeqNum = seqNum; 319 ALOGV("setHeap returned mHeapSeqNum=%d", mHeapSeqNum); 320 } else { 321 mHeapSeqNum = -1; 322 ALOGE("setHeap failed, setting mHeapSeqNum=-1"); 323 } 324 } else if (mDescrambler != nullptr) { 325 sp<IMemoryHeap> heap = dealer->getMemoryHeap(); 326 mHidlMemory = fromHeap(heap); 327 if (mHidlMemory != NULL) { 328 ALOGV("created hidl_memory for descrambler"); 329 } else { 330 ALOGE("failed to create hidl_memory for descrambler"); 331 } 332 } 333 return dealer; 334 } 335 336 void ACodecBufferChannel::setInputBufferArray(const std::vector<BufferAndId> &array) { 337 if (hasCryptoOrDescrambler()) { 338 size_t totalSize = std::accumulate( 339 array.begin(), array.end(), 0u, 340 [alignment = MemoryDealer::getAllocationAlignment()] 341 (size_t sum, const BufferAndId& elem) { 342 return sum + align(elem.mBuffer->capacity(), alignment); 343 }); 344 size_t maxSize = std::accumulate( 345 array.begin(), array.end(), 0u, 346 [alignment = MemoryDealer::getAllocationAlignment()] 347 (size_t max, const BufferAndId& elem) { 348 return std::max(max, align(elem.mBuffer->capacity(), alignment)); 349 }); 350 size_t destinationBufferSize = maxSize; 351 size_t heapSize = totalSize + destinationBufferSize; 352 if (heapSize > 0) { 353 mDealer = makeMemoryDealer(heapSize); 354 mDecryptDestination = mDealer->allocate(destinationBufferSize); 355 } 356 } 357 std::vector<const BufferInfo> inputBuffers; 358 for (const BufferAndId &elem : array) { 359 sp<IMemory> sharedEncryptedBuffer; 360 if (hasCryptoOrDescrambler()) { 361 sharedEncryptedBuffer = mDealer->allocate(elem.mBuffer->capacity()); 362 } 363 inputBuffers.emplace_back(elem.mBuffer, elem.mBufferId, sharedEncryptedBuffer); 364 } 365 std::atomic_store( 366 &mInputBuffers, 367 std::make_shared<const std::vector<const BufferInfo>>(inputBuffers)); 368 } 369 370 void ACodecBufferChannel::setOutputBufferArray(const std::vector<BufferAndId> &array) { 371 std::vector<const BufferInfo> outputBuffers; 372 for (const BufferAndId &elem : array) { 373 outputBuffers.emplace_back(elem.mBuffer, elem.mBufferId, nullptr); 374 } 375 std::atomic_store( 376 &mOutputBuffers, 377 std::make_shared<const std::vector<const BufferInfo>>(outputBuffers)); 378 } 379 380 void ACodecBufferChannel::fillThisBuffer(IOMX::buffer_id bufferId) { 381 ALOGV("fillThisBuffer #%d", bufferId); 382 std::shared_ptr<const std::vector<const BufferInfo>> array( 383 std::atomic_load(&mInputBuffers)); 384 BufferInfoIterator it = findBufferId(array, bufferId); 385 386 if (it == array->end()) { 387 ALOGE("fillThisBuffer: unrecognized buffer #%d", bufferId); 388 return; 389 } 390 if (it->mClientBuffer != it->mCodecBuffer) { 391 it->mClientBuffer->setFormat(it->mCodecBuffer->format()); 392 } 393 394 mCallback->onInputBufferAvailable( 395 std::distance(array->begin(), it), 396 it->mClientBuffer); 397 } 398 399 void ACodecBufferChannel::drainThisBuffer( 400 IOMX::buffer_id bufferId, 401 OMX_U32 omxFlags) { 402 ALOGV("drainThisBuffer #%d", bufferId); 403 std::shared_ptr<const std::vector<const BufferInfo>> array( 404 std::atomic_load(&mOutputBuffers)); 405 BufferInfoIterator it = findBufferId(array, bufferId); 406 407 if (it == array->end()) { 408 ALOGE("drainThisBuffer: unrecognized buffer #%d", bufferId); 409 return; 410 } 411 if (it->mClientBuffer != it->mCodecBuffer) { 412 it->mClientBuffer->setFormat(it->mCodecBuffer->format()); 413 } 414 415 uint32_t flags = 0; 416 if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) { 417 flags |= MediaCodec::BUFFER_FLAG_SYNCFRAME; 418 } 419 if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) { 420 flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG; 421 } 422 if (omxFlags & OMX_BUFFERFLAG_EOS) { 423 flags |= MediaCodec::BUFFER_FLAG_EOS; 424 } 425 it->mClientBuffer->meta()->setInt32("flags", flags); 426 427 mCallback->onOutputBufferAvailable( 428 std::distance(array->begin(), it), 429 it->mClientBuffer); 430 } 431 432 } // namespace android 433