1 /* 2 * Copyright (C) 2009 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 #ifndef MEDIA_BUFFER_GROUP_H_ 18 19 #define MEDIA_BUFFER_GROUP_H_ 20 21 #include <list> 22 23 #include <media/MediaExtractorPluginApi.h> 24 #include <media/NdkMediaErrorPriv.h> 25 #include <media/stagefright/MediaBufferBase.h> 26 #include <utils/Errors.h> 27 #include <utils/threads.h> 28 29 namespace android { 30 31 class MediaBufferBase; 32 33 class MediaBufferGroup : public MediaBufferObserver { 34 public: 35 MediaBufferGroup(size_t growthLimit = 0); 36 37 // create a media buffer group with preallocated buffers 38 MediaBufferGroup(size_t buffers, size_t buffer_size, size_t growthLimit = 0); 39 40 ~MediaBufferGroup(); 41 42 void add_buffer(MediaBufferBase *buffer); 43 44 bool has_buffers(); 45 46 // If nonBlocking is false, it blocks until a buffer is available and 47 // passes it to the caller in *buffer, while returning OK. 48 // The returned buffer will have a reference count of 1. 49 // If nonBlocking is true and a buffer is not immediately available, 50 // buffer is set to NULL and it returns WOULD_BLOCK. 51 // If requestedSize is 0, any free MediaBuffer will be returned. 52 // If requestedSize is > 0, the returned MediaBuffer should have buffer 53 // size of at least requstedSize. 54 status_t acquire_buffer( 55 MediaBufferBase **buffer, bool nonBlocking = false, size_t requestedSize = 0); 56 57 size_t buffers() const; 58 59 // If buffer is nullptr, have acquire_buffer() check for remote release. 60 virtual void signalBufferReturned(MediaBufferBase *buffer); 61 wrap()62 CMediaBufferGroup *wrap() { 63 if (mWrapper) { 64 return mWrapper; 65 } 66 67 mWrapper = new CMediaBufferGroup; 68 mWrapper->handle = this; 69 70 mWrapper->add_buffer = [](void *handle, size_t size) -> void { 71 MediaBufferBase *buf = MediaBufferBase::Create(size); 72 ((MediaBufferGroup*)handle)->add_buffer(buf); 73 }; 74 75 mWrapper->init = [](void *handle, 76 size_t buffers, size_t buffer_size, size_t growthLimit) -> bool { 77 ((MediaBufferGroup*)handle)->init(buffers, buffer_size, growthLimit); 78 // ((MediaBufferGroup*)handle)->mWrapper->init = nullptr; // enforce call-once 79 return true; 80 }; 81 82 mWrapper->acquire_buffer = [](void *handle, 83 CMediaBuffer **buf, bool nonBlocking, size_t requestedSize) -> media_status_t { 84 MediaBufferBase *acquiredBuf = nullptr; 85 status_t err = ((MediaBufferGroup*)handle)->acquire_buffer( 86 &acquiredBuf, nonBlocking, requestedSize); 87 if (err == OK && acquiredBuf != nullptr) { 88 *buf = acquiredBuf->wrap(); 89 } else { 90 *buf = nullptr; 91 } 92 return translate_error(err); 93 }; 94 95 mWrapper->has_buffers = [](void *handle) -> bool { 96 return ((MediaBufferGroup*)handle)->has_buffers(); 97 }; 98 99 return mWrapper; 100 } 101 102 private: 103 CMediaBufferGroup *mWrapper; 104 struct InternalData; 105 InternalData *mInternal; 106 107 MediaBufferGroup(const MediaBufferGroup &); 108 MediaBufferGroup &operator=(const MediaBufferGroup &); 109 void init(size_t buffers, size_t buffer_size, size_t growthLimit); 110 }; 111 112 } // namespace android 113 114 #endif // MEDIA_BUFFER_GROUP_H_ 115