• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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