BufferImpl.cpp revision a5a96828cf0791b9342e4edbb3f2b2c4760c5020
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 "BufferImpl" 19#include <utils/Log.h> 20 21#include <binder/IMemory.h> 22#include <media/stagefright/foundation/ABuffer.h> 23#include <media/stagefright/foundation/AMessage.h> 24#include <media/ICrypto.h> 25#include <utils/NativeHandle.h> 26 27#include "include/Codec2Buffer.h" 28#include "include/SecureBuffer.h" 29#include "include/SharedMemoryBuffer.h" 30 31namespace android { 32 33// SharedMemoryBuffer 34 35SharedMemoryBuffer::SharedMemoryBuffer(const sp<AMessage> &format, const sp<IMemory> &mem) 36 : MediaCodecBuffer(format, new ABuffer(mem->pointer(), mem->size())), 37 mMemory(mem) { 38} 39 40SharedMemoryBuffer::SharedMemoryBuffer(const sp<AMessage> &format, const sp<TMemory> &mem) 41 : MediaCodecBuffer(format, new ABuffer(mem->getPointer(), mem->getSize())), 42 mTMemory(mem) { 43} 44 45// SecureBuffer 46 47SecureBuffer::SecureBuffer(const sp<AMessage> &format, const void *ptr, size_t size) 48 : MediaCodecBuffer(format, new ABuffer(nullptr, size)), 49 mPointer(ptr) { 50} 51 52SecureBuffer::SecureBuffer( 53 const sp<AMessage> &format, const sp<NativeHandle> &handle, size_t size) 54 : MediaCodecBuffer(format, new ABuffer(nullptr, size)), 55 mPointer(nullptr), 56 mHandle(handle) { 57} 58 59void *SecureBuffer::getDestinationPointer() { 60 return (void *)(mHandle == nullptr ? mPointer : mHandle->handle()); 61} 62 63ICrypto::DestinationType SecureBuffer::getDestinationType() { 64 return ICrypto::kDestinationTypeNativeHandle; 65} 66 67// Codec2Buffer 68 69bool Codec2Buffer::canCopyLinear(const std::shared_ptr<C2Buffer> &buffer) const { 70 if (const_cast<Codec2Buffer *>(this)->base() == nullptr) { 71 return false; 72 } 73 if (buffer->data().type() != C2BufferData::LINEAR) { 74 return false; 75 } 76 if (buffer->data().linearBlocks().size() == 0u) { 77 // Nothing to copy, so we can copy by doing nothing. 78 return true; 79 } else if (buffer->data().linearBlocks().size() > 1u) { 80 // We don't know how to copy more than one blocks. 81 return false; 82 } 83 if (buffer->data().linearBlocks()[0].size() > capacity()) { 84 // It won't fit. 85 return false; 86 } 87 return true; 88} 89 90bool Codec2Buffer::copyLinear(const std::shared_ptr<C2Buffer> &buffer) { 91 // We assume that all canCopyLinear() checks passed. 92 if (buffer->data().linearBlocks().size() == 0u) { 93 setRange(0, 0); 94 return true; 95 } 96 C2ReadView view = buffer->data().linearBlocks()[0].map().get(); 97 if (view.error() != C2_OK) { 98 ALOGD("Error while mapping: %d", view.error()); 99 return false; 100 } 101 if (view.capacity() > capacity()) { 102 ALOGD("C2ConstLinearBlock lied --- it actually doesn't fit: view(%u) > this(%zu)", 103 view.capacity(), capacity()); 104 return false; 105 } 106 memcpy(base(), view.data(), view.capacity()); 107 setRange(0, view.capacity()); 108 return true; 109} 110 111// LocalLinearBuffer 112 113bool LocalLinearBuffer::canCopy(const std::shared_ptr<C2Buffer> &buffer) const { 114 return canCopyLinear(buffer); 115} 116 117bool LocalLinearBuffer::copy(const std::shared_ptr<C2Buffer> &buffer) { 118 return copyLinear(buffer); 119} 120 121// DummyContainerBuffer 122 123DummyContainerBuffer::DummyContainerBuffer( 124 const sp<AMessage> &format, const std::shared_ptr<C2Buffer> &buffer) 125 : Codec2Buffer(format, new ABuffer(nullptr, 1)), 126 mBufferRef(buffer) { 127 setRange(0, buffer ? 1 : 0); 128} 129 130std::shared_ptr<C2Buffer> DummyContainerBuffer::asC2Buffer() { 131 return std::move(mBufferRef); 132} 133 134bool DummyContainerBuffer::canCopy(const std::shared_ptr<C2Buffer> &) const { 135 return !mBufferRef; 136} 137 138bool DummyContainerBuffer::copy(const std::shared_ptr<C2Buffer> &buffer) { 139 mBufferRef = buffer; 140 setRange(0, mBufferRef ? 1 : 0); 141 return true; 142} 143 144// LinearBlockBuffer 145 146// static 147sp<LinearBlockBuffer> LinearBlockBuffer::Allocate( 148 const sp<AMessage> &format, const std::shared_ptr<C2LinearBlock> &block) { 149 C2WriteView writeView(block->map().get()); 150 if (writeView.error() != C2_OK) { 151 return nullptr; 152 } 153 return new LinearBlockBuffer(format, std::move(writeView), block); 154} 155 156std::shared_ptr<C2Buffer> LinearBlockBuffer::asC2Buffer() { 157 return C2Buffer::CreateLinearBuffer(mBlock->share(offset(), size(), C2Fence())); 158} 159 160bool LinearBlockBuffer::canCopy(const std::shared_ptr<C2Buffer> &buffer) const { 161 return canCopyLinear(buffer); 162} 163 164bool LinearBlockBuffer::copy(const std::shared_ptr<C2Buffer> &buffer) { 165 return copyLinear(buffer); 166} 167 168LinearBlockBuffer::LinearBlockBuffer( 169 const sp<AMessage> &format, 170 C2WriteView&& writeView, 171 const std::shared_ptr<C2LinearBlock> &block) 172 : Codec2Buffer(format, new ABuffer(writeView.data(), writeView.size())), 173 mWriteView(writeView), 174 mBlock(block) { 175} 176 177// ConstLinearBlockBuffer 178 179// static 180sp<ConstLinearBlockBuffer> ConstLinearBlockBuffer::Allocate( 181 const sp<AMessage> &format, const std::shared_ptr<C2Buffer> &buffer) { 182 if (!buffer 183 || buffer->data().type() != C2BufferData::LINEAR 184 || buffer->data().linearBlocks().size() != 1u) { 185 return nullptr; 186 } 187 C2ReadView readView(buffer->data().linearBlocks()[0].map().get()); 188 if (readView.error() != C2_OK) { 189 return nullptr; 190 } 191 return new ConstLinearBlockBuffer(format, std::move(readView), buffer); 192} 193 194ConstLinearBlockBuffer::ConstLinearBlockBuffer( 195 const sp<AMessage> &format, 196 C2ReadView&& readView, 197 const std::shared_ptr<C2Buffer> &buffer) 198 : Codec2Buffer(format, new ABuffer( 199 // NOTE: ABuffer only takes non-const pointer but this data is 200 // supposed to be read-only. 201 const_cast<uint8_t *>(readView.data()), readView.capacity())), 202 mReadView(readView), 203 mBufferRef(buffer) { 204} 205 206std::shared_ptr<C2Buffer> ConstLinearBlockBuffer::asC2Buffer() { 207 return std::move(mBufferRef); 208} 209 210} // namespace android 211