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 <C2Buffer.h>
24
25 #include <Codec2BufferUtils.h>
26
27 #include <android/hardware/cas/native/1.0/IDescrambler.h>
28 #include <android/hardware/drm/1.0/types.h>
29 #include <binder/MemoryDealer.h>
30 #include <hidlmemory/FrameworkUtils.h>
31 #include <media/openmax/OMX_Core.h>
32 #include <media/stagefright/foundation/ABuffer.h>
33 #include <media/stagefright/foundation/AMessage.h>
34 #include <media/stagefright/foundation/AUtils.h>
35 #include <media/stagefright/ACodec.h>
36 #include <media/stagefright/MediaCodec.h>
37 #include <media/MediaCodecBuffer.h>
38 #include <system/window.h>
39
40 #include "include/ACodecBufferChannel.h"
41 #include "include/SecureBuffer.h"
42 #include "include/SharedMemoryBuffer.h"
43
44 namespace android {
45 using hardware::fromHeap;
46 using hardware::hidl_handle;
47 using hardware::hidl_string;
48 using hardware::hidl_vec;
49 using namespace hardware::cas::V1_0;
50 using namespace hardware::cas::native::V1_0;
51 using DrmBufferType = hardware::drm::V1_0::BufferType;
52 using BufferInfo = ACodecBufferChannel::BufferInfo;
53 using BufferInfoIterator = std::vector<const BufferInfo>::const_iterator;
54
~ACodecBufferChannel()55 ACodecBufferChannel::~ACodecBufferChannel() {
56 if (mCrypto != nullptr && mDealer != nullptr && mHeapSeqNum >= 0) {
57 mCrypto->unsetHeap(mHeapSeqNum);
58 }
59 }
60
findClientBuffer(const std::shared_ptr<const std::vector<const BufferInfo>> & array,const sp<MediaCodecBuffer> & buffer)61 static BufferInfoIterator findClientBuffer(
62 const std::shared_ptr<const std::vector<const BufferInfo>> &array,
63 const sp<MediaCodecBuffer> &buffer) {
64 return std::find_if(
65 array->begin(), array->end(),
66 [buffer](const BufferInfo &info) { return info.mClientBuffer == buffer; });
67 }
68
findBufferId(const std::shared_ptr<const std::vector<const BufferInfo>> & array,IOMX::buffer_id bufferId)69 static BufferInfoIterator findBufferId(
70 const std::shared_ptr<const std::vector<const BufferInfo>> &array,
71 IOMX::buffer_id bufferId) {
72 return std::find_if(
73 array->begin(), array->end(),
74 [bufferId](const BufferInfo &info) { return bufferId == info.mBufferId; });
75 }
76
BufferInfo(const sp<MediaCodecBuffer> & buffer,IOMX::buffer_id bufferId,const sp<IMemory> & sharedEncryptedBuffer)77 ACodecBufferChannel::BufferInfo::BufferInfo(
78 const sp<MediaCodecBuffer> &buffer,
79 IOMX::buffer_id bufferId,
80 const sp<IMemory> &sharedEncryptedBuffer)
81 : mClientBuffer(
82 (sharedEncryptedBuffer == nullptr)
83 ? buffer
84 : new SharedMemoryBuffer(buffer->format(), sharedEncryptedBuffer)),
85 mCodecBuffer(buffer),
86 mBufferId(bufferId),
87 mSharedEncryptedBuffer(sharedEncryptedBuffer) {
88 }
89
ACodecBufferChannel(const sp<AMessage> & inputBufferFilled,const sp<AMessage> & outputBufferDrained,const sp<AMessage> & pollForRenderedBuffers)90 ACodecBufferChannel::ACodecBufferChannel(
91 const sp<AMessage> &inputBufferFilled, const sp<AMessage> &outputBufferDrained,
92 const sp<AMessage> &pollForRenderedBuffers)
93 : mInputBufferFilled(inputBufferFilled),
94 mOutputBufferDrained(outputBufferDrained),
95 mPollForRenderedBuffers(pollForRenderedBuffers),
96 mHeapSeqNum(-1) {
97 }
98
queueInputBuffer(const sp<MediaCodecBuffer> & buffer)99 status_t ACodecBufferChannel::queueInputBuffer(const sp<MediaCodecBuffer> &buffer) {
100 std::shared_ptr<const std::vector<const BufferInfo>> array(
101 std::atomic_load(&mInputBuffers));
102 BufferInfoIterator it = findClientBuffer(array, buffer);
103 if (it == array->end()) {
104 return -ENOENT;
105 }
106 if (it->mClientBuffer != it->mCodecBuffer) {
107 // Copy metadata from client to codec buffer.
108 it->mCodecBuffer->meta()->clear();
109 int64_t timeUs;
110 CHECK(it->mClientBuffer->meta()->findInt64("timeUs", &timeUs));
111 it->mCodecBuffer->meta()->setInt64("timeUs", timeUs);
112 int32_t eos;
113 if (it->mClientBuffer->meta()->findInt32("eos", &eos)) {
114 it->mCodecBuffer->meta()->setInt32("eos", eos);
115 }
116 int32_t csd;
117 if (it->mClientBuffer->meta()->findInt32("csd", &csd)) {
118 it->mCodecBuffer->meta()->setInt32("csd", csd);
119 }
120 int32_t decodeOnly;
121 if (it->mClientBuffer->meta()->findInt32("decode-only", &decodeOnly)) {
122 it->mCodecBuffer->meta()->setInt32("decode-only", decodeOnly);
123 }
124 }
125 ALOGV("queueInputBuffer #%d", it->mBufferId);
126 sp<AMessage> msg = mInputBufferFilled->dup();
127 msg->setObject("buffer", it->mCodecBuffer);
128 msg->setInt32("buffer-id", it->mBufferId);
129 msg->post();
130 return OK;
131 }
132
queueSecureInputBuffer(const sp<MediaCodecBuffer> & buffer,bool secure,const uint8_t * key,const uint8_t * iv,CryptoPlugin::Mode mode,CryptoPlugin::Pattern pattern,const CryptoPlugin::SubSample * subSamples,size_t numSubSamples,AString * errorDetailMsg)133 status_t ACodecBufferChannel::queueSecureInputBuffer(
134 const sp<MediaCodecBuffer> &buffer, bool secure, const uint8_t *key,
135 const uint8_t *iv, CryptoPlugin::Mode mode, CryptoPlugin::Pattern pattern,
136 const CryptoPlugin::SubSample *subSamples, size_t numSubSamples,
137 AString *errorDetailMsg) {
138 if (!hasCryptoOrDescrambler() || mDealer == nullptr) {
139 return -ENOSYS;
140 }
141 std::shared_ptr<const std::vector<const BufferInfo>> array(
142 std::atomic_load(&mInputBuffers));
143 BufferInfoIterator it = findClientBuffer(array, buffer);
144 if (it == array->end()) {
145 return -ENOENT;
146 }
147
148 native_handle_t *secureHandle = NULL;
149 if (secure) {
150 sp<SecureBuffer> secureData =
151 static_cast<SecureBuffer *>(it->mCodecBuffer.get());
152 if (secureData->getDestinationType() != ICrypto::kDestinationTypeNativeHandle) {
153 return BAD_VALUE;
154 }
155 secureHandle = static_cast<native_handle_t *>(secureData->getDestinationPointer());
156 }
157 ssize_t result = -1;
158 ssize_t codecDataOffset = 0;
159 if (numSubSamples == 1
160 && subSamples[0].mNumBytesOfClearData == 0
161 && subSamples[0].mNumBytesOfEncryptedData == 0) {
162 // We don't need to go through crypto or descrambler if the input is empty.
163 result = 0;
164 } else if (mCrypto != NULL) {
165 hardware::drm::V1_0::DestinationBuffer destination;
166 if (secure) {
167 destination.type = DrmBufferType::NATIVE_HANDLE;
168 destination.secureMemory = hidl_handle(secureHandle);
169 } else {
170 destination.type = DrmBufferType::SHARED_MEMORY;
171 IMemoryToSharedBuffer(
172 mDecryptDestination, mHeapSeqNum, &destination.nonsecureMemory);
173 }
174
175 hardware::drm::V1_0::SharedBuffer source;
176 IMemoryToSharedBuffer(it->mSharedEncryptedBuffer, mHeapSeqNum, &source);
177
178 result = mCrypto->decrypt(key, iv, mode, pattern,
179 source, it->mClientBuffer->offset(),
180 subSamples, numSubSamples, destination, errorDetailMsg);
181
182 if (result < 0) {
183 return result;
184 }
185
186 if (destination.type == DrmBufferType::SHARED_MEMORY) {
187 memcpy(it->mCodecBuffer->base(), mDecryptDestination->unsecurePointer(), result);
188 }
189 } else {
190 // Here we cast CryptoPlugin::SubSample to hardware::cas::native::V1_0::SubSample
191 // directly, the structure definitions should match as checked in DescramblerImpl.cpp.
192 hidl_vec<SubSample> hidlSubSamples;
193 hidlSubSamples.setToExternal((SubSample *)subSamples, numSubSamples, false /*own*/);
194
195 ssize_t offset;
196 size_t size;
197 it->mSharedEncryptedBuffer->getMemory(&offset, &size);
198 hardware::cas::native::V1_0::SharedBuffer srcBuffer = {
199 .heapBase = *mHidlMemory,
200 .offset = (uint64_t) offset,
201 .size = size
202 };
203
204 DestinationBuffer dstBuffer;
205 if (secure) {
206 dstBuffer.type = BufferType::NATIVE_HANDLE;
207 dstBuffer.secureMemory = hidl_handle(secureHandle);
208 } else {
209 dstBuffer.type = BufferType::SHARED_MEMORY;
210 dstBuffer.nonsecureMemory = srcBuffer;
211 }
212
213 Status status = Status::OK;
214 hidl_string detailedError;
215 ScramblingControl sctrl = ScramblingControl::UNSCRAMBLED;
216
217 if (key != NULL) {
218 sctrl = (ScramblingControl)key[0];
219 // Adjust for the PES offset
220 codecDataOffset = key[2] | (key[3] << 8);
221 }
222
223 auto returnVoid = mDescrambler->descramble(
224 sctrl,
225 hidlSubSamples,
226 srcBuffer,
227 0,
228 dstBuffer,
229 0,
230 [&status, &result, &detailedError] (
231 Status _status, uint32_t _bytesWritten,
232 const hidl_string& _detailedError) {
233 status = _status;
234 result = (ssize_t)_bytesWritten;
235 detailedError = _detailedError;
236 });
237
238 if (!returnVoid.isOk() || status != Status::OK || result < 0) {
239 ALOGE("descramble failed, trans=%s, status=%d, result=%zd",
240 returnVoid.description().c_str(), status, result);
241 return UNKNOWN_ERROR;
242 }
243
244 if (result < codecDataOffset) {
245 ALOGD("invalid codec data offset: %zd, result %zd", codecDataOffset, result);
246 return BAD_VALUE;
247 }
248
249 ALOGV("descramble succeeded, %zd bytes", result);
250
251 if (dstBuffer.type == BufferType::SHARED_MEMORY) {
252 memcpy(it->mCodecBuffer->base(),
253 (uint8_t*)it->mSharedEncryptedBuffer->unsecurePointer(),
254 result);
255 }
256 }
257
258 it->mCodecBuffer->setRange(codecDataOffset, result - codecDataOffset);
259
260 // Copy metadata from client to codec buffer.
261 it->mCodecBuffer->meta()->clear();
262 int64_t timeUs;
263 CHECK(it->mClientBuffer->meta()->findInt64("timeUs", &timeUs));
264 it->mCodecBuffer->meta()->setInt64("timeUs", timeUs);
265 int32_t eos;
266 if (it->mClientBuffer->meta()->findInt32("eos", &eos)) {
267 it->mCodecBuffer->meta()->setInt32("eos", eos);
268 }
269 int32_t csd;
270 if (it->mClientBuffer->meta()->findInt32("csd", &csd)) {
271 it->mCodecBuffer->meta()->setInt32("csd", csd);
272 }
273 int32_t decodeOnly;
274 if (it->mClientBuffer->meta()->findInt32("decode-only", &decodeOnly)) {
275 it->mCodecBuffer->meta()->setInt32("decode-only", decodeOnly);
276 }
277
278 ALOGV("queueSecureInputBuffer #%d", it->mBufferId);
279 sp<AMessage> msg = mInputBufferFilled->dup();
280 msg->setObject("buffer", it->mCodecBuffer);
281 msg->setInt32("buffer-id", it->mBufferId);
282 msg->post();
283 return OK;
284 }
285
attachBuffer(const std::shared_ptr<C2Buffer> & c2Buffer,const sp<MediaCodecBuffer> & buffer)286 status_t ACodecBufferChannel::attachBuffer(
287 const std::shared_ptr<C2Buffer> &c2Buffer,
288 const sp<MediaCodecBuffer> &buffer) {
289 switch (c2Buffer->data().type()) {
290 case C2BufferData::LINEAR: {
291 if (c2Buffer->data().linearBlocks().size() != 1u) {
292 return -ENOSYS;
293 }
294 C2ConstLinearBlock block{c2Buffer->data().linearBlocks().front()};
295 C2ReadView view{block.map().get()};
296 size_t copyLength = std::min(size_t(view.capacity()), buffer->capacity());
297 ALOGV_IF(view.capacity() > buffer->capacity(),
298 "view.capacity() = %zu, buffer->capacity() = %zu",
299 view.capacity(), buffer->capacity());
300 memcpy(buffer->base(), view.data(), copyLength);
301 buffer->setRange(0, copyLength);
302 break;
303 }
304 case C2BufferData::GRAPHIC: {
305 sp<ABuffer> imageData;
306 if (!buffer->format()->findBuffer("image-data", &imageData)) {
307 return -ENOSYS;
308 }
309 if (c2Buffer->data().graphicBlocks().size() != 1u) {
310 return -ENOSYS;
311 }
312 C2ConstGraphicBlock block{c2Buffer->data().graphicBlocks().front()};
313 const C2GraphicView view{block.map().get()};
314 status_t err = ImageCopy(
315 buffer->base(), (const MediaImage2 *)(imageData->base()), view);
316 if (err != OK) {
317 return err;
318 }
319 break;
320 }
321 case C2BufferData::LINEAR_CHUNKS: [[fallthrough]];
322 case C2BufferData::GRAPHIC_CHUNKS: [[fallthrough]];
323 default:
324 return -ENOSYS;
325 }
326
327 return OK;
328 }
329
getHeapSeqNum(const sp<HidlMemory> & memory)330 int32_t ACodecBufferChannel::getHeapSeqNum(const sp<HidlMemory> &memory) {
331 CHECK(mCrypto);
332 auto it = mHeapSeqNumMap.find(memory);
333 int32_t heapSeqNum = -1;
334 if (it == mHeapSeqNumMap.end()) {
335 heapSeqNum = mCrypto->setHeap(memory);
336 mHeapSeqNumMap.emplace(memory, heapSeqNum);
337 } else {
338 heapSeqNum = it->second;
339 }
340 return heapSeqNum;
341 }
342
attachEncryptedBuffer(const sp<hardware::HidlMemory> & memory,bool secure,const uint8_t * key,const uint8_t * iv,CryptoPlugin::Mode mode,CryptoPlugin::Pattern pattern,size_t offset,const CryptoPlugin::SubSample * subSamples,size_t numSubSamples,const sp<MediaCodecBuffer> & buffer,AString * errorDetailMsg)343 status_t ACodecBufferChannel::attachEncryptedBuffer(
344 const sp<hardware::HidlMemory> &memory,
345 bool secure,
346 const uint8_t *key,
347 const uint8_t *iv,
348 CryptoPlugin::Mode mode,
349 CryptoPlugin::Pattern pattern,
350 size_t offset,
351 const CryptoPlugin::SubSample *subSamples,
352 size_t numSubSamples,
353 const sp<MediaCodecBuffer> &buffer,
354 AString* errorDetailMsg) {
355 std::shared_ptr<const std::vector<const BufferInfo>> array(
356 std::atomic_load(&mInputBuffers));
357 BufferInfoIterator it = findClientBuffer(array, buffer);
358 if (it == array->end()) {
359 return -ENOENT;
360 }
361
362 native_handle_t *secureHandle = NULL;
363 if (secure) {
364 sp<SecureBuffer> secureData =
365 static_cast<SecureBuffer *>(it->mCodecBuffer.get());
366 if (secureData->getDestinationType() != ICrypto::kDestinationTypeNativeHandle) {
367 return BAD_VALUE;
368 }
369 secureHandle = static_cast<native_handle_t *>(secureData->getDestinationPointer());
370 }
371 size_t size = 0;
372 for (size_t i = 0; i < numSubSamples; ++i) {
373 size += subSamples[i].mNumBytesOfClearData + subSamples[i].mNumBytesOfEncryptedData;
374 }
375 ssize_t result = -1;
376 ssize_t codecDataOffset = 0;
377 if (mCrypto != NULL) {
378 hardware::drm::V1_0::DestinationBuffer destination;
379 if (secure) {
380 destination.type = DrmBufferType::NATIVE_HANDLE;
381 destination.secureMemory = hidl_handle(secureHandle);
382 } else {
383 destination.type = DrmBufferType::SHARED_MEMORY;
384 IMemoryToSharedBuffer(
385 mDecryptDestination, mHeapSeqNum, &destination.nonsecureMemory);
386 }
387
388 int32_t heapSeqNum = getHeapSeqNum(memory);
389 hardware::drm::V1_0::SharedBuffer source{(uint32_t)heapSeqNum, offset, size};
390
391 result = mCrypto->decrypt(key, iv, mode, pattern,
392 source, it->mClientBuffer->offset(),
393 subSamples, numSubSamples, destination, errorDetailMsg);
394
395 if (result < 0) {
396 return result;
397 }
398
399 if (destination.type == DrmBufferType::SHARED_MEMORY) {
400 memcpy(it->mCodecBuffer->base(), mDecryptDestination->unsecurePointer(), result);
401 }
402 } else {
403 // Here we cast CryptoPlugin::SubSample to hardware::cas::native::V1_0::SubSample
404 // directly, the structure definitions should match as checked in DescramblerImpl.cpp.
405 hidl_vec<SubSample> hidlSubSamples;
406 hidlSubSamples.setToExternal((SubSample *)subSamples, numSubSamples, false /*own*/);
407
408 hardware::cas::native::V1_0::SharedBuffer srcBuffer = {
409 .heapBase = *memory,
410 .offset = (uint64_t) offset,
411 .size = size
412 };
413
414 DestinationBuffer dstBuffer;
415 if (secure) {
416 dstBuffer.type = BufferType::NATIVE_HANDLE;
417 dstBuffer.secureMemory = hidl_handle(secureHandle);
418 } else {
419 dstBuffer.type = BufferType::SHARED_MEMORY;
420 dstBuffer.nonsecureMemory = srcBuffer;
421 }
422
423 Status status = Status::OK;
424 hidl_string detailedError;
425 ScramblingControl sctrl = ScramblingControl::UNSCRAMBLED;
426
427 if (key != NULL) {
428 sctrl = (ScramblingControl)key[0];
429 // Adjust for the PES offset
430 codecDataOffset = key[2] | (key[3] << 8);
431 }
432
433 auto returnVoid = mDescrambler->descramble(
434 sctrl,
435 hidlSubSamples,
436 srcBuffer,
437 0,
438 dstBuffer,
439 0,
440 [&status, &result, &detailedError] (
441 Status _status, uint32_t _bytesWritten,
442 const hidl_string& _detailedError) {
443 status = _status;
444 result = (ssize_t)_bytesWritten;
445 detailedError = _detailedError;
446 });
447 if (errorDetailMsg) {
448 errorDetailMsg->setTo(detailedError.c_str(), detailedError.size());
449 }
450 if (!returnVoid.isOk() || status != Status::OK || result < 0) {
451 ALOGE("descramble failed, trans=%s, status=%d, result=%zd",
452 returnVoid.description().c_str(), status, result);
453 return UNKNOWN_ERROR;
454 }
455
456 if (result < codecDataOffset) {
457 ALOGD("invalid codec data offset: %zd, result %zd", codecDataOffset, result);
458 return BAD_VALUE;
459 }
460
461 ALOGV("descramble succeeded, %zd bytes", result);
462
463 if (dstBuffer.type == BufferType::SHARED_MEMORY) {
464 memcpy(it->mCodecBuffer->base(),
465 (uint8_t*)it->mSharedEncryptedBuffer->unsecurePointer(),
466 result);
467 }
468 }
469
470 it->mCodecBuffer->setRange(codecDataOffset, result - codecDataOffset);
471 return OK;
472 }
473
renderOutputBuffer(const sp<MediaCodecBuffer> & buffer,int64_t timestampNs)474 status_t ACodecBufferChannel::renderOutputBuffer(
475 const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) {
476 std::shared_ptr<const std::vector<const BufferInfo>> array(
477 std::atomic_load(&mOutputBuffers));
478 BufferInfoIterator it = findClientBuffer(array, buffer);
479 if (it == array->end()) {
480 return -ENOENT;
481 }
482
483 ALOGV("renderOutputBuffer #%d", it->mBufferId);
484 sp<AMessage> msg = mOutputBufferDrained->dup();
485 msg->setObject("buffer", buffer);
486 msg->setInt32("buffer-id", it->mBufferId);
487 msg->setInt32("render", true);
488 msg->setInt64("timestampNs", timestampNs);
489 msg->post();
490 return OK;
491 }
492
pollForRenderedBuffers()493 void ACodecBufferChannel::pollForRenderedBuffers() {
494 mPollForRenderedBuffers->post();
495 }
496
discardBuffer(const sp<MediaCodecBuffer> & buffer)497 status_t ACodecBufferChannel::discardBuffer(const sp<MediaCodecBuffer> &buffer) {
498 std::shared_ptr<const std::vector<const BufferInfo>> array(
499 std::atomic_load(&mInputBuffers));
500 bool input = true;
501 BufferInfoIterator it = findClientBuffer(array, buffer);
502 if (it == array->end()) {
503 array = std::atomic_load(&mOutputBuffers);
504 input = false;
505 it = findClientBuffer(array, buffer);
506 if (it == array->end()) {
507 return -ENOENT;
508 }
509 }
510 ALOGV("discardBuffer #%d", it->mBufferId);
511 sp<AMessage> msg = input ? mInputBufferFilled->dup() : mOutputBufferDrained->dup();
512 msg->setObject("buffer", it->mCodecBuffer);
513 msg->setInt32("buffer-id", it->mBufferId);
514 msg->setInt32("discarded", true);
515 msg->post();
516 return OK;
517 }
518
getInputBufferArray(Vector<sp<MediaCodecBuffer>> * array)519 void ACodecBufferChannel::getInputBufferArray(Vector<sp<MediaCodecBuffer>> *array) {
520 std::shared_ptr<const std::vector<const BufferInfo>> inputBuffers(
521 std::atomic_load(&mInputBuffers));
522 array->clear();
523 for (const BufferInfo &elem : *inputBuffers) {
524 array->push_back(elem.mClientBuffer);
525 }
526 }
527
getOutputBufferArray(Vector<sp<MediaCodecBuffer>> * array)528 void ACodecBufferChannel::getOutputBufferArray(Vector<sp<MediaCodecBuffer>> *array) {
529 std::shared_ptr<const std::vector<const BufferInfo>> outputBuffers(
530 std::atomic_load(&mOutputBuffers));
531 array->clear();
532 for (const BufferInfo &elem : *outputBuffers) {
533 array->push_back(elem.mClientBuffer);
534 }
535 }
536
makeMemoryDealer(size_t heapSize)537 sp<MemoryDealer> ACodecBufferChannel::makeMemoryDealer(size_t heapSize) {
538 sp<MemoryDealer> dealer;
539 if (mDealer != nullptr && mCrypto != nullptr && mHeapSeqNum >= 0) {
540 mCrypto->unsetHeap(mHeapSeqNum);
541 }
542 dealer = new MemoryDealer(heapSize, "ACodecBufferChannel");
543 if (mCrypto != nullptr) {
544 sp<HidlMemory> hHeap = fromHeap(dealer->getMemoryHeap());
545 int32_t seqNum = mCrypto->setHeap(hHeap);
546 if (seqNum >= 0) {
547 mHeapSeqNum = seqNum;
548 ALOGV("setHeap returned mHeapSeqNum=%d", mHeapSeqNum);
549 } else {
550 mHeapSeqNum = -1;
551 ALOGE("setHeap failed, setting mHeapSeqNum=-1");
552 }
553 } else if (mDescrambler != nullptr) {
554 sp<IMemoryHeap> heap = dealer->getMemoryHeap();
555 mHidlMemory = fromHeap(heap);
556 if (mHidlMemory != NULL) {
557 ALOGV("created hidl_memory for descrambler");
558 } else {
559 ALOGE("failed to create hidl_memory for descrambler");
560 }
561 }
562 return dealer;
563 }
564
setInputBufferArray(const std::vector<BufferAndId> & array)565 void ACodecBufferChannel::setInputBufferArray(const std::vector<BufferAndId> &array) {
566 if (hasCryptoOrDescrambler()) {
567 size_t totalSize = std::accumulate(
568 array.begin(), array.end(), 0u,
569 [alignment = MemoryDealer::getAllocationAlignment()]
570 (size_t sum, const BufferAndId& elem) {
571 return sum + align(elem.mBuffer->capacity(), alignment);
572 });
573 size_t maxSize = std::accumulate(
574 array.begin(), array.end(), 0u,
575 [alignment = MemoryDealer::getAllocationAlignment()]
576 (size_t max, const BufferAndId& elem) {
577 return std::max(max, align(elem.mBuffer->capacity(), alignment));
578 });
579 size_t destinationBufferSize = maxSize;
580 size_t heapSize = totalSize + destinationBufferSize;
581 if (heapSize > 0) {
582 mDealer = makeMemoryDealer(heapSize);
583 mDecryptDestination = mDealer->allocate(destinationBufferSize);
584 }
585 }
586 std::vector<const BufferInfo> inputBuffers;
587 for (const BufferAndId &elem : array) {
588 sp<IMemory> sharedEncryptedBuffer;
589 if (hasCryptoOrDescrambler()) {
590 sharedEncryptedBuffer = mDealer->allocate(elem.mBuffer->capacity());
591 }
592 inputBuffers.emplace_back(elem.mBuffer, elem.mBufferId, sharedEncryptedBuffer);
593 }
594 std::atomic_store(
595 &mInputBuffers,
596 std::make_shared<const std::vector<const BufferInfo>>(inputBuffers));
597 }
598
setOutputBufferArray(const std::vector<BufferAndId> & array)599 void ACodecBufferChannel::setOutputBufferArray(const std::vector<BufferAndId> &array) {
600 std::vector<const BufferInfo> outputBuffers;
601 for (const BufferAndId &elem : array) {
602 outputBuffers.emplace_back(elem.mBuffer, elem.mBufferId, nullptr);
603 }
604 std::atomic_store(
605 &mOutputBuffers,
606 std::make_shared<const std::vector<const BufferInfo>>(outputBuffers));
607 }
608
fillThisBuffer(IOMX::buffer_id bufferId)609 void ACodecBufferChannel::fillThisBuffer(IOMX::buffer_id bufferId) {
610 ALOGV("fillThisBuffer #%d", bufferId);
611 std::shared_ptr<const std::vector<const BufferInfo>> array(
612 std::atomic_load(&mInputBuffers));
613 BufferInfoIterator it = findBufferId(array, bufferId);
614
615 if (it == array->end()) {
616 ALOGE("fillThisBuffer: unrecognized buffer #%d", bufferId);
617 return;
618 }
619 if (it->mClientBuffer != it->mCodecBuffer) {
620 it->mClientBuffer->setFormat(it->mCodecBuffer->format());
621 }
622
623 mCallback->onInputBufferAvailable(
624 std::distance(array->begin(), it),
625 it->mClientBuffer);
626 }
627
drainThisBuffer(IOMX::buffer_id bufferId,OMX_U32 omxFlags)628 void ACodecBufferChannel::drainThisBuffer(
629 IOMX::buffer_id bufferId,
630 OMX_U32 omxFlags) {
631 ALOGV("drainThisBuffer #%d", bufferId);
632 std::shared_ptr<const std::vector<const BufferInfo>> array(
633 std::atomic_load(&mOutputBuffers));
634 BufferInfoIterator it = findBufferId(array, bufferId);
635
636 if (it == array->end()) {
637 ALOGE("drainThisBuffer: unrecognized buffer #%d", bufferId);
638 return;
639 }
640 if (it->mClientBuffer != it->mCodecBuffer) {
641 it->mClientBuffer->setFormat(it->mCodecBuffer->format());
642 }
643
644 uint32_t flags = 0;
645 if (omxFlags & OMX_BUFFERFLAG_SYNCFRAME) {
646 flags |= MediaCodec::BUFFER_FLAG_SYNCFRAME;
647 }
648 if (omxFlags & OMX_BUFFERFLAG_CODECCONFIG) {
649 flags |= MediaCodec::BUFFER_FLAG_CODECCONFIG;
650 }
651 if (omxFlags & OMX_BUFFERFLAG_EOS) {
652 flags |= MediaCodec::BUFFER_FLAG_EOS;
653 }
654 if (omxFlags & OMX_BUFFERFLAG_DECODEONLY) {
655 flags |= MediaCodec::BUFFER_FLAG_DECODE_ONLY;
656 }
657 it->mClientBuffer->meta()->setInt32("flags", flags);
658
659 mCallback->onOutputBufferAvailable(
660 std::distance(array->begin(), it),
661 it->mClientBuffer);
662 }
663
setCrypto(const sp<ICrypto> & crypto)664 void ACodecBufferChannel::setCrypto(const sp<ICrypto> &crypto) {
665 if (mCrypto != nullptr) {
666 for (std::pair<wp<HidlMemory>, int32_t> entry : mHeapSeqNumMap) {
667 mCrypto->unsetHeap(entry.second);
668 }
669 mHeapSeqNumMap.clear();
670 if (mHeapSeqNum >= 0) {
671 mCrypto->unsetHeap(mHeapSeqNum);
672 mHeapSeqNum = -1;
673 }
674 }
675 mCrypto = crypto;
676 }
677
setDescrambler(const sp<IDescrambler> & descrambler)678 void ACodecBufferChannel::setDescrambler(const sp<IDescrambler> &descrambler) {
679 mDescrambler = descrambler;
680 }
681
682 } // namespace android
683