mpeg2dec: Fix negotiation issue with playbin
[glsdk/gst-plugin-ducati.git] / src / gstducatih264dec.c
1 /*
2  * GStreamer
3  * Copyright (c) 2010, Texas Instruments Incorporated
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation
8  * version 2.1 of the License.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18  */
20 /**
21  * SECTION:element-ducatih264dec
22  *
23  * FIXME:Describe ducatih264dec here.
24  *
25  * <refsect2>
26  * <title>Example launch line</title>
27  * |[
28  * gst-launch -v -m fakesrc ! ducatih264dec ! fakesink silent=TRUE
29  * ]|
30  * </refsect2>
31  */
33 #ifdef HAVE_CONFIG_H
34 #include <config.h>
35 #endif
37 #include <math.h>
38 #include "gstducatih264dec.h"
41 #define GST_BUFFER_FLAG_B_FRAME (GST_BUFFER_FLAG_LAST << 0)
42 #define PADX  32
43 #define PADY  24
45 /* This structure is not public, this should be replaced by
46    sizeof(sErrConcealLayerStr) when it is made so. */
47 #define SIZE_OF_CONCEALMENT_DATA 65536
50 static void gst_ducati_h264dec_base_init (gpointer gclass);
51 static void gst_ducati_h264dec_class_init (GstDucatiH264DecClass * klass);
52 static void gst_ducati_h264dec_init (GstDucatiH264Dec * self, gpointer klass);
54 static GstDucatiVidDecClass *parent_class = NULL;
56 GType
57 gst_ducati_h264dec_get_type (void)
58 {
59   static GType ducati_h264dec_type = 0;
61   if (!ducati_h264dec_type) {
62     static const GTypeInfo ducati_h264dec_info = {
63       sizeof (GstDucatiH264DecClass),
64       (GBaseInitFunc) gst_ducati_h264dec_base_init,
65       NULL,
66       (GClassInitFunc) gst_ducati_h264dec_class_init,
67       NULL,
68       NULL,
69       sizeof (GstDucatiH264Dec),
70       0,
71       (GInstanceInitFunc) gst_ducati_h264dec_init,
72     };
74     ducati_h264dec_type = g_type_register_static (GST_TYPE_DUCATIVIDDEC,
75         "GstDucatiH264Dec", &ducati_h264dec_info, 0);
76   }
77   return ducati_h264dec_type;
78 }
80 /* *INDENT-OFF* */
81 static GstStaticPadTemplate sink_factory = GST_STATIC_PAD_TEMPLATE ("sink",
82     GST_PAD_SINK,
83     GST_PAD_ALWAYS,
84     GST_STATIC_CAPS ("video/x-h264, "
85         "stream-format = byte-stream, "   /* only byte-stream */
86         "alignment = au, "          /* only entire frames */
87         "width = (int)[ 16, 2048 ], "
88         "height = (int)[ 16, 2048 ]; "
89         "video/x-h264, "
90         "stream-format = byte-stream, "   /* only byte-stream */
91         "alignment = au, "          /* only entire frames */
92         "width = (int)[ 16, 2048 ], "
93         "height = (int)[ 16, 2048 ], "
94         "profile = (string) {high, high-10-intra, high-10, high-4:2:2-intra, "
95         "high-4:2:2, high-4:4:4-intra, high-4:4:4, cavlc-4:4:4-intra}, "
96         "level = (string) {1, 1b, 1.1, 1.2, 1.3, 2, 2.1, 2.2, 3, 3.1, 3.2, 4, 4.1, 4.2, 5, 5.1};")
97     );
99 static const struct
101   const char *level;
102   gint kb;
103 } max_dpb_by_level[] = {
104   { "1", 149 },
105   { "1b", 149 }, /* That one's not in the spec ?? */
106   { "1.1", 338 },
107   { "1.2", 891 },
108   { "1.3", 891 },
109   { "2", 891 },
110   { "2.1", 1782 },
111   { "2.2", 3038 },
112   { "3", 3038 },
113   { "3.1", 6750 },
114   { "3.2", 7680 },
115   { "4", 12288 },
116   { "4.1", 12288 },
117   { "4.2", 12288 },
118   { "5", 41400 },
119   { "5.1", 69120 },
120 };
121 /* *INDENT-ON* */
123 /* GstDucatiVidDec vmethod implementations */
125 static void
126 gst_ducati_h264dec_update_buffer_size (GstDucatiVidDec * self)
128   gint w = self->width;
129   gint h = self->height;
131   /* calculate output buffer parameters: */
132   self->padded_width = ALIGN2 (w + (2 * PADX), 7);
133   self->padded_height = h + 4 * PADY;
134   self->min_buffers = MIN (16, 32768 / ((w / 16) * (h / 16))) + 3;
137 static gboolean
138 gst_ducati_h264dec_allocate_params (GstDucatiVidDec * self, gint params_sz,
139     gint dynparams_sz, gint status_sz, gint inargs_sz, gint outargs_sz)
141   gboolean ret = GST_DUCATIVIDDEC_CLASS (parent_class)->allocate_params (self,
142       sizeof (IH264VDEC_Params), sizeof (IH264VDEC_DynamicParams),
143       sizeof (IH264VDEC_Status), sizeof (IH264VDEC_InArgs),
144       sizeof (IH264VDEC_OutArgs));
146   if (ret) {
147     IH264VDEC_Params *params = (IH264VDEC_Params *) self->params;
149     self->params->displayDelay = IVIDDEC3_DISPLAY_DELAY_AUTO;
150     params->dpbSizeInFrames = IH264VDEC_DPB_NUMFRAMES_AUTO;
151     params->pConstantMemory = 0;
152     params->presetLevelIdc = IH264VDEC_LEVEL41;
153     params->errConcealmentMode = IH264VDEC_APPLY_CONCEALMENT;
154     params->temporalDirModePred = TRUE;
156     if (self->codec_debug_info) {
157       /* We must allocate a byte per MB, plus the size of some struture which
158          is not public. Place this in the first metadata buffer slot, and ask
159          for MBINFO metadata for it. */
160       GstDucatiH264Dec *h264dec = GST_DUCATIH264DEC (self);
161       unsigned mbw = (self->width + 15) / 16;
162       unsigned mbh = (self->height + 15) / 16;
163       unsigned nmb = mbw * mbh;
165       h264dec->bo_mberror =
166           omap_bo_new (self->device, nmb + SIZE_OF_CONCEALMENT_DATA,
167           OMAP_BO_WC);
168       /* XDM_MemoryType required by drm to allcoate buffer */
169       self->outBufs->descs[2].memType = XDM_MEMTYPE_RAW;
170       self->outBufs->descs[2].buf =
171           (XDAS_Int8 *) omap_bo_dmabuf (h264dec->bo_mberror);
172       self->outBufs->descs[2].bufSize.bytes = nmb + SIZE_OF_CONCEALMENT_DATA;
173       self->params->metadataType[0] = IVIDEO_METADATAPLANE_MBINFO;
174       /* need to lock the buffer to get the page pinned */
175       dce_buf_lock (1, (size_t *) & self->outBufs->descs[2].buf);
176     }
177   }
179   return ret;
182 static gint
183 gst_ducati_h264dec_handle_error (GstDucatiVidDec * self, gint ret,
184     gint extended_error, gint status_extended_error)
186   GstDucatiH264Dec *h264dec = GST_DUCATIH264DEC (self);
187   const unsigned char *mberror, *mbcon;
188   unsigned mbw, mbh, nmb;
189   uint16_t mbwr, mbhr;
190   size_t n, nerr = 0;
191   char *line;
192   unsigned x, y;
194   if (h264dec->bo_mberror) {
195     mberror = omap_bo_map (h264dec->bo_mberror);
196     mbw = (self->width + 15) / 16;
197     mbh = (self->height + 15) / 16;
198     nmb = mbw * mbh;
199     mbcon = mberror + nmb;
200     mbwr = ((const uint16_t *) mbcon)[21];      /* not a public struct */
201     mbhr = ((const uint16_t *) mbcon)[22];      /* not a public struct */
202     if (nmb != mbwr * mbhr) {
203       GST_WARNING_OBJECT (self, "Failed to find MB size - "
204           "corruption might have happened");
205     } else {
206       for (n = 0; n < nmb; ++n) {
207         if (mberror[n])
208           ++nerr;
209       }
210       GST_INFO_OBJECT (self, "Frame has %zu MB errors over %zu (%u x %u) MBs",
211           nerr, nmb, mbwr, mbhr);
212       line = g_malloc (mbw + 1);
213       for (y = 0; y < mbh; y++) {
214         line[mbw] = 0;
215         for (x = 0; x < mbw; x++) {
216           line[x] = mberror[x + y * mbw] ? '!' : '.';
217         }
218         GST_INFO_OBJECT (self, "MB: %4u: %s", y, line);
219       }
220       g_free (line);
221     }
222   }
224   if (extended_error & 0x00000001) {
225     /* No valid slice. This seems to be bad enough that it's better to flush and
226      * skip to the next keyframe.
227      */
229     if (extended_error == 0x00000201) {
230       /* the codec doesn't unlock the input buffer in this case... */
231       gst_buffer_unref ((GstBuffer *) self->inArgs->inputID);
232       self->inArgs->inputID = 0;
233     }
235     self->needs_flushing = TRUE;
236   }
238   ret =
239       GST_DUCATIVIDDEC_CLASS (parent_class)->handle_error (self, ret,
240       extended_error, status_extended_error);
242   return ret;
245 static gboolean
246 gst_ducati_h264dec_can_drop_frame (GstDucatiVidDec * self, GstBuffer * buf,
247     gint64 diff)
249   gboolean is_bframe = GST_BUFFER_FLAG_IS_SET (buf,
250       GST_BUFFER_FLAG_B_FRAME);
252   if (diff >= 0 && is_bframe)
253     return TRUE;
255   return FALSE;
258 static gint
259 gst_ducati_h264dec_find_max_dpb_from_level (GstDucatiVidDec * self,
260     const char *level)
262   guint n;
264   for (n = 0; n < G_N_ELEMENTS (max_dpb_by_level); ++n)
265     if (!strcmp (level, max_dpb_by_level[n].level))
266       return max_dpb_by_level[n].kb;
268   GST_WARNING_OBJECT (self, "Max DBP not found for level %s", level);
269   return -1;
272 static gint
273 gst_ducati_h264dec_get_max_dpb_size (GstDucatiVidDec * self, GstCaps * caps)
275   gint wmb = (self->width + 15) / 16;
276   gint hmb = (self->height + 15) / 16;
277   gint max_dpb, max_dpb_size;
278   GstStructure *structure;
279   const char *level;
280   float chroma_factor = 1.5;    /* We only support NV12, which is 4:2:0 */
282   /* Min( 1024 * MaxDPB / ( PicWidthInMbs * FrameHeightInMbs * 256 * ChromaFormatFactor ), 16 ) */
284   structure = gst_caps_get_structure (caps, 0);
285   if (!structure)
286     return -1;
288   level = gst_structure_get_string (structure, "level");
289   if (!level)
290     return -1;
292   max_dpb = gst_ducati_h264dec_find_max_dpb_from_level (self, level);
293   if (max_dpb < 0)
294     return -1;
296   max_dpb_size =
297       lrint (ceil (1024 * max_dpb / (wmb * hmb * 256 * chroma_factor)));
298   if (max_dpb_size > MAX_BACKLOG_FRAMES)
299     max_dpb_size = MAX_BACKLOG_FRAMES;
301   return max_dpb_size;
304 static gboolean
305 gst_ducati_h264dec_set_sink_caps (GstDucatiVidDec * self, GstCaps * caps)
307   GstDucatiH264Dec *h264dec = GST_DUCATIH264DEC (self);
308   IH264VDEC_Params *params = (IH264VDEC_Params *) self->params;
309   GstStructure *structure;
310   const char *level;
311   structure = gst_caps_get_structure (caps, 0);
312   level = gst_structure_get_string (structure, "level");
314   if (level) {
315     GST_DEBUG_OBJECT (self, "Level obtained from stream caps = %s", level);
316     if (!strcmp (level, "5") || !strcmp (level, "5.1")) {
317       if (params->presetLevelIdc != IH264VDEC_LEVEL51) {
318         params->presetLevelIdc = IH264VDEC_LEVEL51;
319         self->codec_create_params_changed = TRUE;
320         GST_DEBUG_OBJECT (self,
321             "Level was earlier set to 4.2, changing it to 5.1");
322       }
323     }
324   }
326   GST_DEBUG_OBJECT (self, "set_sink_caps: %" GST_PTR_FORMAT, caps);
328   if (!GST_CALL_PARENT_WITH_DEFAULT (GST_DUCATIVIDDEC_CLASS, set_sink_caps,
329           (self, caps), TRUE))
330     return FALSE;
332   /* HW decoder fails in GETSTATUS */
333 #if 0
334   /* When we have the first decoded buffer, we ask the decoder for the
335      max number of frames needed to reorder */
336   int err = VIDDEC3_control (self->codec, XDM_GETSTATUS,
337       self->dynParams, self->status);
338   if (!err) {
339     IH264VDEC_Status *s = (IH264VDEC_Status *) self->status;
340     if (s->spsMaxRefFrames > MAX_BACKLOG_FRAMES) {
341       h264dec->backlog_maxframes = MAX_BACKLOG_FRAMES;
342       GST_WARNING_OBJECT (self,
343           "Stream needs %d frames for reordering, we can only accomodate %d",
344           s->spsMaxRefFrames, MAX_BACKLOG_FRAMES);
345     } else {
346       h264dec->backlog_maxframes = s->spsMaxRefFrames;
347       GST_INFO_OBJECT (self, "Num frames for reordering: %d",
348           h264dec->backlog_maxframes);
349     }
350   } else {
351     h264dec->backlog_maxframes = MAX_BACKLOG_FRAMES;
352     GST_WARNING_OBJECT (self,
353         "Failed to request num frames for reordering, defaulting to %d",
354         h264dec->backlog_maxframes);
355   }
356 #endif
358   self->backlog_maxframes = -1;
360   structure = gst_caps_get_structure (caps, 0);
361   if (structure) {
362     gint num_ref_frames = -1, num_reorder_frames = -1;
363     const char *profile;
365     /* baseline profile does not use B frames (and I'll say constrained-baseline
366        is unlikely either from the name, it's not present in my H264 spec... */
367     profile = gst_structure_get_string (structure, "profile");
368     if (profile && (!strcmp (profile, "baseline")
369             || !strcmp (profile, "constrained-baseline"))) {
370       GST_DEBUG_OBJECT (self, "No need for reordering for %s profile", profile);
371       self->backlog_maxframes = 0;
372       goto no_b_frames;
373     }
376     if (gst_structure_get_int (structure, "num-ref-frames", &num_ref_frames)
377         && num_ref_frames >= 0) {
378       ((IH264VDEC_Params *) self->params)->dpbSizeInFrames = num_ref_frames;
379     }
380     if (gst_structure_get_int (structure, "num-reorder-frames",
381             &num_reorder_frames)
382         && num_reorder_frames >= 0) {
383       if (num_reorder_frames > MAX_BACKLOG_FRAMES) {
384         self->backlog_maxframes = MAX_BACKLOG_FRAMES;
385         GST_WARNING_OBJECT (self,
386             "Stream needs %d frames for reordering, we can only accomodate %d",
387             num_reorder_frames, MAX_BACKLOG_FRAMES);
388       } else {
389         self->backlog_maxframes = num_reorder_frames;
390         GST_INFO_OBJECT (self, "Num frames for reordering: %d",
391             self->backlog_maxframes);
392       }
393     }
394   }
396   /* If not present, use the spec forumula for a bound */
397   if (self->backlog_maxframes < 0) {
398     self->backlog_maxframes = gst_ducati_h264dec_get_max_dpb_size (self, caps);
399     if (self->backlog_maxframes >= 0) {
400       GST_WARNING_OBJECT (self,
401           "num-reorder-frames not found on caps, calculation from stream parameters gives %d",
402           self->backlog_maxframes);
403     } else {
404       self->backlog_maxframes = MAX_H264_BACKLOG_FRAMES;
405     }
406   }
407   if (self->backlog_maxframes > self->backlog_max_maxframes)
408     self->backlog_maxframes = self->backlog_max_maxframes;
409   GST_WARNING_OBJECT (self,
410       "Using %d frames for reordering", self->backlog_maxframes);
412 no_b_frames:
414   return TRUE;
417 /* GObject vmethod implementations */
419 static void
420 gst_ducati_h264dec_base_init (gpointer gclass)
422   GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
424   gst_element_class_set_static_metadata (element_class,
425       "DucatiH264Dec",
426       "Codec/Decoder/Video",
427       "Decodes video in H.264/bytestream format with ducati",
428       "Rob Clark <rob@ti.com>");
430   gst_element_class_add_pad_template (element_class,
431       gst_static_pad_template_get (&sink_factory));
434 static void
435 gst_ducati_h264dec_finalize (GObject * obj)
437   GstDucatiH264Dec *self = GST_DUCATIH264DEC (obj);
438   if (self->bo_mberror)
439     omap_bo_del (self->bo_mberror);
440   G_OBJECT_CLASS (parent_class)->finalize (obj);
443 static void
444 gst_ducati_h264dec_class_init (GstDucatiH264DecClass * klass)
446   GstDucatiVidDecClass *bclass = GST_DUCATIVIDDEC_CLASS (klass);
447   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
449   parent_class = g_type_class_peek_parent (klass);
451   bclass->codec_name = "ivahd_h264dec";
452   bclass->update_buffer_size =
453       GST_DEBUG_FUNCPTR (gst_ducati_h264dec_update_buffer_size);
454   bclass->allocate_params =
455       GST_DEBUG_FUNCPTR (gst_ducati_h264dec_allocate_params);
456   bclass->handle_error = GST_DEBUG_FUNCPTR (gst_ducati_h264dec_handle_error);
457   bclass->can_drop_frame =
458       GST_DEBUG_FUNCPTR (gst_ducati_h264dec_can_drop_frame);
459   bclass->set_sink_caps = GST_DEBUG_FUNCPTR (gst_ducati_h264dec_set_sink_caps);
460   gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_ducati_h264dec_finalize);
463 static void
464 gst_ducati_h264dec_init (GstDucatiH264Dec * self, gpointer gclass)
466 #ifndef GST_DISABLE_GST_DEBUG
467   GstDucatiVidDec *dec = GST_DUCATIVIDDEC (self);
469   dec->error_strings[0] = "no error-free slice";
470   dec->error_strings[1] = "error parsing SPS";
471   dec->error_strings[2] = "error parsing PPS";
472   dec->error_strings[3] = "error parsing slice header";
473   dec->error_strings[4] = "error parsing MB data";
474   dec->error_strings[5] = "unknown SPS";
475   dec->error_strings[6] = "unknown PPS";
476   dec->error_strings[7] = "invalid parameter";
477   dec->error_strings[16] = "unsupported feature";
478   dec->error_strings[17] = "SEI buffer overflow";
479   dec->error_strings[18] = "stream end";
480   dec->error_strings[19] = "no free buffers";
481   dec->error_strings[20] = "resolution change";
482   dec->error_strings[21] = "unsupported resolution";
483   dec->error_strings[22] = "invalid maxNumRefFrames";
484   dec->error_strings[23] = "invalid mbox message";
485   dec->error_strings[24] = "bad datasync input";
486   dec->error_strings[25] = "missing slice";
487   dec->error_strings[26] = "bad datasync param";
488   dec->error_strings[27] = "bad hw state";
489   dec->error_strings[28] = "temporal direct mode";
490   dec->error_strings[29] = "display width too small";
491   dec->error_strings[30] = "no SPS/PPS header";
492   dec->error_strings[31] = "gap in frame num";
493 #endif