OLD | NEW |
| (Empty) |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 // | |
5 // An abstract class to define the behavior of an output buffer sink for | |
6 // media::OmxCodec. It is responsible for negotiation of buffer allocation | |
7 // for output of media::OmxCodec. It is also responsible for processing buffer | |
8 // output from OpenMAX decoder. It is important to note that implementor must | |
9 // assure usage of this class is safe on the thread where media::OmxCodec | |
10 // lives. Ownership of this object is described in src/media/omx/omx_codec.h. | |
11 // | |
12 // BUFFER NEGOTIATION | |
13 // | |
14 // One of the key function of OmxOutputSink is to negotiate output buffer | |
15 // allocation with OmxCodec. There are two modes of operation: | |
16 // | |
17 // 1. Buffer is provided by OmxCodec. | |
18 // | |
19 // In this case ProvidesEGLImage() will return false and OmxCodec allocates | |
20 // output buffers during initialization. Here's a sample sequence of actions: | |
21 // | |
22 // - OmxCodec allocated buffers during initialization. | |
23 // - OmxOutputSink::UseThisBuffer(id, buffer) is called to assign an output | |
24 // buffer header to the sink component. | |
25 // - OmxOutputSink maps the output buffer as a texture for rendering. | |
26 // - OmxCodec received dynamic port reconfiguration from the hardware. | |
27 // - OmxOutputSink::StopUsingThisBuffer(id) is called to release the buffer. | |
28 // - OmxOutputSink unmaps the output buffer as texture and make sure there | |
29 // is not reference to it. | |
30 // - OmxOutputSink::UseThisBuffer(id, buffer) is called to assign a new | |
31 // output buffer to the sink component. | |
32 // - ... | |
33 // | |
34 // 1. Buffer is provided by OmxCodec as EGL image. | |
35 // | |
36 // - OmxOutputSink::AllocateEGLImages(...) is called to request an EGL image | |
37 // from the sink component, an associated buffer header is created. | |
38 // - OmxOutputSink::UseThisBuffer(id, buffer) is called to assign an output | |
39 // buffer header to the sink component. | |
40 // - OmxOutputSink maps the output buffer as a texture for rendering. | |
41 // - OmxCodec received dynamic port reconfiguration from the hardware. | |
42 // - OmxOutputSink::StopUsingThisBuffer(id) is called to release the buffer. | |
43 // - OmxOutputSink unmaps the output buffer as texture and make sure there | |
44 // is not reference to it. | |
45 // - OmxOutputSink::ReleaseEGLImages() is called to tell the sink component | |
46 // to release all allocated EGL images. | |
47 // - OmxOutputSink::AllocateEGLImages(...) is called to allocate EGL images. | |
48 // - ... | |
49 // | |
50 // BUFFER READY SIGNALING | |
51 // | |
52 // Another key part of OmxOutputSink is to process the output buffer given | |
53 // by OmxCodec. This is done by signaling the sink component that a | |
54 // particular buffer is ready. | |
55 // | |
56 // This is done through the following sequence: | |
57 // | |
58 // - Owner of this object calls BufferReady(buffer_id, callback). | |
59 // - OmxOutputSink uses the buffer for rendering or other operations | |
60 // asynchronously. | |
61 // - Callback provided by BufferReady() is called along with a buffer id to | |
62 // notify the buffer has been consumed. | |
63 // | |
64 // It is up to implementor to decide which thread this callback is executed. | |
65 // | |
66 // THREADING | |
67 // | |
68 // OmxOutputSink::BufferReady(buffer_id) is called from the owner of this | |
69 // object which can be made from any thread. All other methods are made on | |
70 // the thread where OmxCodec lives. | |
71 // | |
72 // When the sink component is notified of buffer ready and the buffer is | |
73 // used BufferUsedCallback is called. There is no gurantee which thread | |
74 // this call is made. | |
75 // | |
76 // OWNERSHIP | |
77 // | |
78 // Described in src/media/omx/omx_codec.h. | |
79 | |
80 #ifndef MEDIA_OMX_OMX_OUTPUT_SINK_ | |
81 #define MEDIA_OMX_OMX_OUTPUT_SINK_ | |
82 | |
83 #include <vector> | |
84 | |
85 #include "base/callback.h" | |
86 #include "third_party/openmax/il/OMX_Core.h" | |
87 | |
88 // TODO(hclam): This is just to get the build going. Remove this when we | |
89 // include the GLES header. | |
90 typedef void* EGLImageKHR; | |
91 | |
92 namespace media { | |
93 | |
94 class OmxOutputSink { | |
95 public: | |
96 typedef Callback1<int>::Type BufferUsedCallback; | |
97 virtual ~OmxOutputSink() {} | |
98 | |
99 // Returns true if this sink component provides EGL images as output | |
100 // buffers. | |
101 virtual bool ProvidesEGLImages() const = 0; | |
102 | |
103 // Returns a list of EGL images allocated by the sink component. The | |
104 // EGL images will then be given to the hardware decoder for port | |
105 // configuration. The amount of EGL images created is controlled by the | |
106 // sink component. The EGL image allocated is owned by the sink | |
107 // component. | |
108 // Returns true if allocate was successful. | |
109 // TODO(hclam): Improve this API once we know what to do with it. | |
110 virtual bool AllocateEGLImages(int width, int height, | |
111 std::vector<EGLImageKHR>* images) = 0; | |
112 | |
113 // Notify the sink component that OmxCodec has done with the EGL | |
114 // image allocated by AllocateEGLImages(). They can be released by | |
115 // the sink component any time. | |
116 virtual void ReleaseEGLImages( | |
117 const std::vector<EGLImageKHR>& images) = 0; | |
118 | |
119 // Assign a buffer header to the sink component for output. The sink | |
120 // component will read from the assicated buffer for the decoded frame. | |
121 // There is also an associated buffer id to identify the buffer. This id | |
122 // is used in subsequent steps for identifying the right buffer. | |
123 // Note that the sink component doesn't own the buffer header. | |
124 // Note that this method is used to assign buffer only at the | |
125 // initialization stage and is not used for data delivery. | |
126 virtual void UseThisBuffer(int buffer_id, | |
127 OMX_BUFFERHEADERTYPE* buffer) = 0; | |
128 | |
129 // Tell the sink component to stop using the buffer identified by the | |
130 // buffer id. | |
131 // TODO(hclam): Should accept a callback so notify the operation has | |
132 // completed. | |
133 virtual void StopUsingThisBuffer(int id) = 0; | |
134 | |
135 // Notify the sink component that the buffer identified by buffer id | |
136 // is ready to be consumed. When the buffer is used, |callback| is | |
137 // called. Ths callback can be made on any thread. | |
138 virtual void BufferReady(int buffer_id, | |
139 BufferUsedCallback* callback) = 0; | |
140 }; | |
141 | |
142 } | |
143 | |
144 #endif // MEDIA_OMX_OMX_OUTPUT_SINK_ | |
OLD | NEW |