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