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