diff options
Diffstat (limited to 'extras/recipes-ti/gstreamer-ti/gstreamer-ti/0008-Add-support-for-pad-allocated-buffers-in-TIViddec2.patch')
-rw-r--r-- | extras/recipes-ti/gstreamer-ti/gstreamer-ti/0008-Add-support-for-pad-allocated-buffers-in-TIViddec2.patch | 302 |
1 files changed, 302 insertions, 0 deletions
diff --git a/extras/recipes-ti/gstreamer-ti/gstreamer-ti/0008-Add-support-for-pad-allocated-buffers-in-TIViddec2.patch b/extras/recipes-ti/gstreamer-ti/gstreamer-ti/0008-Add-support-for-pad-allocated-buffers-in-TIViddec2.patch new file mode 100644 index 00000000..9ceb30f5 --- /dev/null +++ b/extras/recipes-ti/gstreamer-ti/gstreamer-ti/0008-Add-support-for-pad-allocated-buffers-in-TIViddec2.patch | |||
@@ -0,0 +1,302 @@ | |||
1 | From e5a264465c1c77d5fc18eeb51b99c79fc3f28a3e Mon Sep 17 00:00:00 2001 | ||
2 | From: Don Darling <don.osc2@gmail.com> | ||
3 | Date: Tue, 8 Jun 2010 13:48:51 -0500 | ||
4 | Subject: [PATCH 8/8] Add support for pad-allocated buffers in TIViddec2. | ||
5 | |||
6 | When padAllocOutbufs=TRUE is specified to the TIViddec2 element, it will | ||
7 | attempt to allocate buffers from downstream instead of allocating its own. | ||
8 | |||
9 | Downstream buffers will only be used if it can be determined that they are | ||
10 | all members of a DMAI BufTab, which means they are CMEM-based, and will work | ||
11 | with the codecs. Currently, the only known downstream element that can provide | ||
12 | these buffers is TIDmaiVideoSink, and it is only supported for DM365. | ||
13 | |||
14 | There is currently no support for centering small clips in the middle of the | ||
15 | display screen -- this would require additional support in the display driver. | ||
16 | As a result, pad-allocation can currently only be used with clips that are at | ||
17 | least as large as the display, and this feature not enabled by default because | ||
18 | of these strict clip-size requirements. | ||
19 | |||
20 | On DM365, there are known issues with the MPEG-2 decoder's output buffer size | ||
21 | calculation that cause it not to work with D1 resolutions unless you hard-code | ||
22 | the size. H.264 and MPEG-4 decoders work as expected, and MPEG-2 works as | ||
23 | expected for 720p. | ||
24 | --- | ||
25 | .../ti_build/ticodecplugin/src/gsttividdec2.c | 159 ++++++++++++++++---- | ||
26 | .../ti_build/ticodecplugin/src/gsttividdec2.h | 1 + | ||
27 | 2 files changed, 127 insertions(+), 33 deletions(-) | ||
28 | |||
29 | diff --git a/gstreamer_ti/ti_build/ticodecplugin/src/gsttividdec2.c b/gstreamer_ti/ti_build/ticodecplugin/src/gsttividdec2.c | ||
30 | index c39208f..ec3cb05 100644 | ||
31 | --- a/gstreamer_ti/ti_build/ticodecplugin/src/gsttividdec2.c | ||
32 | +++ b/gstreamer_ti/ti_build/ticodecplugin/src/gsttividdec2.c | ||
33 | @@ -73,7 +73,8 @@ enum | ||
34 | PROP_FRAMERATE, /* framerate (GstFraction) */ | ||
35 | PROP_DISPLAY_BUFFER, /* displayBuffer (boolean) */ | ||
36 | PROP_GEN_TIMESTAMPS, /* genTimeStamps (boolean) */ | ||
37 | - PROP_RTCODECTHREAD /* rtCodecThread (boolean) */ | ||
38 | + PROP_RTCODECTHREAD, /* rtCodecThread (boolean) */ | ||
39 | + PROP_PAD_ALLOC_OUTBUFS /* padAllocOutbufs (boolean) */ | ||
40 | }; | ||
41 | |||
42 | /* Define sink (input) pad capabilities. Currently, MPEG and H264 are | ||
43 | @@ -170,8 +171,8 @@ static GstClockTime | ||
44 | gst_tividdec2_frame_duration(GstTIViddec2 *viddec2); | ||
45 | static gboolean | ||
46 | gst_tividdec2_resizeBufTab(GstTIViddec2 *viddec2); | ||
47 | -static gboolean | ||
48 | - gst_tividdec2_codec_start (GstTIViddec2 *viddec2); | ||
49 | +static gboolean | ||
50 | + gst_tividdec2_codec_start (GstTIViddec2 *viddec2, GstBuffer **padBuffer); | ||
51 | static gboolean | ||
52 | gst_tividdec2_codec_stop (GstTIViddec2 *viddec2); | ||
53 | static void | ||
54 | @@ -324,6 +325,11 @@ static void gst_tividdec2_class_init(GstTIViddec2Class *klass) | ||
55 | g_param_spec_boolean("genTimeStamps", "Generate Time Stamps", | ||
56 | "Set timestamps on output buffers", | ||
57 | TRUE, G_PARAM_WRITABLE)); | ||
58 | + | ||
59 | + g_object_class_install_property(gobject_class, PROP_PAD_ALLOC_OUTBUFS, | ||
60 | + g_param_spec_boolean("padAllocOutbufs", "Use pad allocation", | ||
61 | + "Try to allocate buffers with pad allocation", | ||
62 | + FALSE, G_PARAM_WRITABLE)); | ||
63 | } | ||
64 | |||
65 | /****************************************************************************** | ||
66 | @@ -448,6 +454,7 @@ static void gst_tividdec2_init(GstTIViddec2 *viddec2, GstTIViddec2Class *gclass) | ||
67 | |||
68 | viddec2->numOutputBufs = 0UL; | ||
69 | viddec2->hOutBufTab = NULL; | ||
70 | + viddec2->padAllocOutbufs = FALSE; | ||
71 | viddec2->circBuf = NULL; | ||
72 | |||
73 | viddec2->sps_pps_data = NULL; | ||
74 | @@ -548,6 +555,10 @@ static void gst_tividdec2_set_property(GObject *object, guint prop_id, | ||
75 | viddec2->rtCodecThread = g_value_get_boolean(value); | ||
76 | GST_LOG("setting \"RTCodecThread\" to \"%s\"\n", | ||
77 | viddec2->rtCodecThread ? "TRUE" : "FALSE"); | ||
78 | + case PROP_PAD_ALLOC_OUTBUFS: | ||
79 | + viddec2->padAllocOutbufs = g_value_get_boolean(value); | ||
80 | + GST_LOG("setting \"padAllocOutbufs\" to \"%s\"\n", | ||
81 | + viddec2->padAllocOutbufs ? "TRUE" : "FALSE"); | ||
82 | break; | ||
83 | default: | ||
84 | G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); | ||
85 | @@ -1079,9 +1090,9 @@ static gboolean gst_tividdec2_init_video(GstTIViddec2 *viddec2) | ||
86 | */ | ||
87 | Rendezvous_meet(viddec2->waitOnDecodeThread); | ||
88 | |||
89 | - if (viddec2->circBuf == NULL || viddec2->hOutBufTab == NULL) { | ||
90 | + if (viddec2->circBuf == NULL) { | ||
91 | GST_ELEMENT_ERROR(viddec2, RESOURCE, FAILED, | ||
92 | - ("decode thread failed to create circbuf or display buffer handles\n"), | ||
93 | + ("decode thread failed to create circbuf handles\n"), | ||
94 | (NULL)); | ||
95 | return FALSE; | ||
96 | } | ||
97 | @@ -1260,11 +1271,13 @@ static gboolean gst_tividdec2_codec_stop (GstTIViddec2 *viddec2) | ||
98 | * gst_tividdec2_codec_start | ||
99 | * Initialize codec engine | ||
100 | *****************************************************************************/ | ||
101 | -static gboolean gst_tividdec2_codec_start (GstTIViddec2 *viddec2) | ||
102 | +static gboolean gst_tividdec2_codec_start (GstTIViddec2 *viddec2, | ||
103 | + GstBuffer **padBuffer) | ||
104 | { | ||
105 | - VIDDEC2_Params params = Vdec2_Params_DEFAULT; | ||
106 | - VIDDEC2_DynamicParams dynParams = Vdec2_DynamicParams_DEFAULT; | ||
107 | - BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT; | ||
108 | + VIDDEC2_Params params = Vdec2_Params_DEFAULT; | ||
109 | + VIDDEC2_DynamicParams dynParams = Vdec2_DynamicParams_DEFAULT; | ||
110 | + BufferGfx_Attrs gfxAttrs = BufferGfx_Attrs_DEFAULT; | ||
111 | + BufTab_Handle codecBufTab = NULL; | ||
112 | Cpu_Device device; | ||
113 | ColorSpace_Type colorSpace; | ||
114 | Int defaultNumBufs; | ||
115 | @@ -1364,30 +1377,77 @@ static gboolean gst_tividdec2_codec_start (GstTIViddec2 *viddec2) | ||
116 | viddec2->numOutputBufs = defaultNumBufs; | ||
117 | } | ||
118 | |||
119 | - /* Create codec output buffers */ | ||
120 | - GST_LOG("creating output buffer table\n"); | ||
121 | - gfxAttrs.colorSpace = colorSpace; | ||
122 | - gfxAttrs.dim.width = params.maxWidth; | ||
123 | - gfxAttrs.dim.height = params.maxHeight; | ||
124 | - gfxAttrs.dim.lineLength = BufferGfx_calcLineLength( | ||
125 | - gfxAttrs.dim.width, gfxAttrs.colorSpace); | ||
126 | + /* Try to allocate a buffer from downstream. To do this, we must first | ||
127 | + * set the framerate to a reasonable default if one hasn't been specified, | ||
128 | + * and we need to set the source pad caps with the stream information we | ||
129 | + * have so far. | ||
130 | + */ | ||
131 | + gst_tividdec2_frame_duration(viddec2); | ||
132 | + gst_tividdec2_set_source_caps_base(viddec2, params.maxWidth, | ||
133 | + params.maxHeight, colorSpace); | ||
134 | + | ||
135 | + *padBuffer = NULL; | ||
136 | + if (viddec2->padAllocOutbufs) { | ||
137 | + if (gst_pad_alloc_buffer(viddec2->srcpad, 0, | ||
138 | + Vdec2_getOutBufSize(viddec2->hVd), GST_PAD_CAPS(viddec2->srcpad), | ||
139 | + padBuffer) != GST_FLOW_OK) { | ||
140 | + GST_LOG("failed to allocate a downstream buffer\n"); | ||
141 | + *padBuffer = NULL; | ||
142 | + } | ||
143 | + | ||
144 | + if (*padBuffer && !GST_IS_TIDMAIBUFFERTRANSPORT(*padBuffer)) { | ||
145 | + GST_LOG("downstream buffer is not a DMAI buffer; disabling use of " | ||
146 | + "pad-allocated buffers\n"); | ||
147 | + gst_buffer_unref(*padBuffer); | ||
148 | + *padBuffer = NULL; | ||
149 | + } | ||
150 | + | ||
151 | + if (*padBuffer) { | ||
152 | + codecBufTab = Buffer_getBufTab( | ||
153 | + GST_TIDMAIBUFFERTRANSPORT_DMAIBUF(*padBuffer)); | ||
154 | + | ||
155 | + if (!codecBufTab) { | ||
156 | + GST_LOG("downstream buffer is not a BufTab member; disabling " | ||
157 | + "use of pad-allocated buffers\n"); | ||
158 | + gst_buffer_unref(*padBuffer); | ||
159 | + *padBuffer = NULL; | ||
160 | + } | ||
161 | + } | ||
162 | + } | ||
163 | + | ||
164 | + /* If we can't use pad-allocated buffers, allocate our own BufTab for | ||
165 | + * output buffers to push downstream. | ||
166 | + */ | ||
167 | + if (!(*padBuffer)) { | ||
168 | + | ||
169 | + GST_LOG("creating output buffer table\n"); | ||
170 | + gfxAttrs.colorSpace = colorSpace; | ||
171 | + gfxAttrs.dim.width = params.maxWidth; | ||
172 | + gfxAttrs.dim.height = params.maxHeight; | ||
173 | + gfxAttrs.dim.lineLength = BufferGfx_calcLineLength( | ||
174 | + gfxAttrs.dim.width, gfxAttrs.colorSpace); | ||
175 | |||
176 | - /* By default, new buffers are marked as in-use by the codec */ | ||
177 | - gfxAttrs.bAttrs.useMask = gst_tidmaibuffer_CODEC_FREE; | ||
178 | + /* By default, new buffers are marked as in-use by the codec */ | ||
179 | + gfxAttrs.bAttrs.useMask = gst_tidmaibuffer_CODEC_FREE; | ||
180 | |||
181 | - viddec2->hOutBufTab = gst_tidmaibuftab_new( | ||
182 | - viddec2->numOutputBufs, Vdec2_getOutBufSize(viddec2->hVd), | ||
183 | - BufferGfx_getBufferAttrs(&gfxAttrs)); | ||
184 | + viddec2->hOutBufTab = gst_tidmaibuftab_new( | ||
185 | + viddec2->numOutputBufs, Vdec2_getOutBufSize(viddec2->hVd), | ||
186 | + BufferGfx_getBufferAttrs(&gfxAttrs)); | ||
187 | + | ||
188 | + codecBufTab = GST_TIDMAIBUFTAB_BUFTAB(viddec2->hOutBufTab); | ||
189 | + } | ||
190 | |||
191 | - if (viddec2->hOutBufTab == NULL) { | ||
192 | + /* The value of codecBufTab should now either point to a downstream | ||
193 | + * BufTab or our own BufTab. | ||
194 | + */ | ||
195 | + if (codecBufTab == NULL) { | ||
196 | GST_ELEMENT_ERROR(viddec2, RESOURCE, NO_SPACE_LEFT, | ||
197 | - ("failed to create output buffers\n"), (NULL)); | ||
198 | + ("no BufTab available for codec output\n"), (NULL)); | ||
199 | return FALSE; | ||
200 | } | ||
201 | |||
202 | - /* Tell the Vdec module that hOutBufTab will be used for display buffers */ | ||
203 | - Vdec2_setBufTab(viddec2->hVd, | ||
204 | - GST_TIDMAIBUFTAB_BUFTAB(viddec2->hOutBufTab)); | ||
205 | + /* Tell the Vdec module what BufTab it will be using for its output */ | ||
206 | + Vdec2_setBufTab(viddec2->hVd, codecBufTab); | ||
207 | |||
208 | return TRUE; | ||
209 | } | ||
210 | @@ -1403,8 +1463,10 @@ static void* gst_tividdec2_decode_thread(void *arg) | ||
211 | { | ||
212 | GstTIViddec2 *viddec2 = GST_TIVIDDEC2(gst_object_ref(arg)); | ||
213 | GstBuffer *encDataWindow = NULL; | ||
214 | + GstBuffer *padBuffer = NULL; | ||
215 | Buffer_Attrs bAttrs = Buffer_Attrs_DEFAULT; | ||
216 | gboolean codecFlushed = FALSE; | ||
217 | + gboolean usePadBufs = FALSE; | ||
218 | void *threadRet = GstTIThreadSuccess; | ||
219 | Buffer_Handle hDummyInputBuf = NULL; | ||
220 | Buffer_Handle hDstBuf; | ||
221 | @@ -1420,7 +1482,8 @@ static void* gst_tividdec2_decode_thread(void *arg) | ||
222 | GST_LOG("init video decode_thread \n"); | ||
223 | |||
224 | /* Initialize codec engine */ | ||
225 | - ret = gst_tividdec2_codec_start(viddec2); | ||
226 | + ret = gst_tividdec2_codec_start(viddec2, &padBuffer); | ||
227 | + usePadBufs = (padBuffer != NULL); | ||
228 | |||
229 | /* Notify main thread that is ok to continue initialization */ | ||
230 | Rendezvous_meet(viddec2->waitOnDecodeThread); | ||
231 | @@ -1476,7 +1539,34 @@ static void* gst_tividdec2_decode_thread(void *arg) | ||
232 | } | ||
233 | |||
234 | /* Obtain a free output buffer for the decoded data */ | ||
235 | - if (!(hDstBuf = gst_tidmaibuftab_get_buf(viddec2->hOutBufTab))) { | ||
236 | + if (usePadBufs) { | ||
237 | + | ||
238 | + /* First time through this loop, padBuffer will already be set | ||
239 | + * to the buffer we got in codec_start. It will be NULL for every | ||
240 | + * frame after that. | ||
241 | + */ | ||
242 | + if (G_LIKELY(!padBuffer)) { | ||
243 | + if (gst_pad_alloc_buffer(viddec2->srcpad, 0, 0, | ||
244 | + GST_PAD_CAPS(viddec2->srcpad), &padBuffer) | ||
245 | + != GST_FLOW_OK) { | ||
246 | + GST_ELEMENT_ERROR(viddec2, RESOURCE, READ, | ||
247 | + ("failed to allocate a downstream buffer\n"), (NULL)); | ||
248 | + padBuffer = NULL; | ||
249 | + goto thread_exit; | ||
250 | + } | ||
251 | + } | ||
252 | + hDstBuf = GST_TIDMAIBUFFERTRANSPORT_DMAIBUF(padBuffer); | ||
253 | + gst_buffer_unref(padBuffer); | ||
254 | + padBuffer = NULL; | ||
255 | + | ||
256 | + /* Set the CODEC_FREE flag -- this isn't done automatically when | ||
257 | + * allocating buffers from downstream. | ||
258 | + */ | ||
259 | + Buffer_setUseMask(hDstBuf, Buffer_getUseMask(hDstBuf) | | ||
260 | + gst_tidmaibuffer_CODEC_FREE); | ||
261 | + | ||
262 | + } | ||
263 | + else if (!(hDstBuf = gst_tidmaibuftab_get_buf(viddec2->hOutBufTab))) { | ||
264 | GST_ELEMENT_ERROR(viddec2, RESOURCE, READ, | ||
265 | ("failed to get a free contiguous buffer from BufTab\n"), | ||
266 | (NULL)); | ||
267 | @@ -1623,12 +1713,15 @@ thread_failure: | ||
268 | thread_exit: | ||
269 | |||
270 | /* Re-claim any buffers owned by the codec */ | ||
271 | - bufIdx = BufTab_getNumBufs(GST_TIDMAIBUFTAB_BUFTAB(viddec2->hOutBufTab)); | ||
272 | + if (viddec2->hOutBufTab) { | ||
273 | + bufIdx = | ||
274 | + BufTab_getNumBufs(GST_TIDMAIBUFTAB_BUFTAB(viddec2->hOutBufTab)); | ||
275 | |||
276 | - while (bufIdx-- > 0) { | ||
277 | - Buffer_Handle hBuf = BufTab_getBuf( | ||
278 | - GST_TIDMAIBUFTAB_BUFTAB(viddec2->hOutBufTab), bufIdx); | ||
279 | - Buffer_freeUseMask(hBuf, gst_tidmaibuffer_CODEC_FREE); | ||
280 | + while (bufIdx-- > 0) { | ||
281 | + Buffer_Handle hBuf = BufTab_getBuf( | ||
282 | + GST_TIDMAIBUFTAB_BUFTAB(viddec2->hOutBufTab), bufIdx); | ||
283 | + Buffer_freeUseMask(hBuf, gst_tidmaibuffer_CODEC_FREE); | ||
284 | + } | ||
285 | } | ||
286 | |||
287 | /* Release the last buffer we retrieved from the circular buffer */ | ||
288 | diff --git a/gstreamer_ti/ti_build/ticodecplugin/src/gsttividdec2.h b/gstreamer_ti/ti_build/ticodecplugin/src/gsttividdec2.h | ||
289 | index b16e9c5..6b09d2a 100644 | ||
290 | --- a/gstreamer_ti/ti_build/ticodecplugin/src/gsttividdec2.h | ||
291 | +++ b/gstreamer_ti/ti_build/ticodecplugin/src/gsttividdec2.h | ||
292 | @@ -91,6 +91,7 @@ struct _GstTIViddec2 | ||
293 | UInt32 numOutputBufs; | ||
294 | GstTIDmaiBufTab *hOutBufTab; | ||
295 | GstTICircBuffer *circBuf; | ||
296 | + gboolean padAllocOutbufs; | ||
297 | |||
298 | /* Quicktime h264 header */ | ||
299 | GstBuffer *sps_pps_data; | ||
300 | -- | ||
301 | 1.7.0.4 | ||
302 | |||