d21d8ca6adb4bf7b67af95fafff49f270745a50e
[glsdk/gst-plugin-ducati.git] / src / gstducatividdec.h
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 #ifndef __GST_DUCATIVIDDEC_H__
21 #define __GST_DUCATIVIDDEC_H__
23 #include <stdint.h>
24 #include <stddef.h>
25 #include <omap_drm.h>
26 #include <omap_drmif.h>
28 #include "gstducati.h"
29 #include "gstducatibufferpriv.h"
31 #include <gst/drm/gstdrmbufferpool.h>
32 #include <gst/video/video.h>
33 #include <gst/video/video-crop.h>
35 G_BEGIN_DECLS
37 #define GST_TYPE_DUCATIVIDDEC               (gst_ducati_viddec_get_type())
38 #define GST_DUCATIVIDDEC(obj)               (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_DUCATIVIDDEC, GstDucatiVidDec))
39 #define GST_DUCATIVIDDEC_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_DUCATIVIDDEC, GstDucatiVidDecClass))
40 #define GST_IS_DUCATIVIDDEC(obj)            (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_DUCATIVIDDEC))
41 #define GST_IS_DUCATIVIDDEC_CLASS(klass)    (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_DUCATIVIDDEC))
42 #define GST_DUCATIVIDDEC_GET_CLASS(obj)     (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_DUCATIVIDDEC, GstDucatiVidDecClass))
44 typedef struct _GstDucatiVidDec      GstDucatiVidDec;
45 typedef struct _GstDucatiVidDecClass GstDucatiVidDecClass;
47 struct _GstDucatiVidDec
48 {
49   GstElement parent;
51   GstPad *sinkpad, *srcpad;
53   GstDRMBufferPool *pool;
55   /* minimum output size required by the codec: */
56   gint outsize;
58   /* minimum number of buffers required by the codec: */
59   gint min_buffers;
61   /* input (unpadded, unaligned) size of video: */
62   gint input_width, input_height;
64   /* input (unpadded, aligned to MB) size of video: */
65   gint width, height;
67   gint fps_n, fps_d;
69   /* output (padded) size including any codec padding: */
70   gint padded_width, padded_height;
72   /* output stride (>= padded_width) */
73   gint stride;
75   gboolean interlaced;
77   struct omap_bo *input_bo;
78   /* input buffer, allocated when codec is created: */
79   guint8 *input;
81   /* number of bytes pushed to input on current frame: */
82   gint in_size;
84   /* the crop to attach to output buffers: */
85   GstVideoCrop *crop;
87   /* on first output buffer, we need to send crop info to sink.. and some
88    * operations like flushing should be avoided if we haven't sent any
89    * input buffers:
90    */
91   gboolean first_out_buffer, first_in_buffer;
92   gboolean send_crop_event;
94   GstSegment segment;
95   gdouble qos_proportion;
96   GstClockTime qos_earliest_time;
98   gboolean need_out_buf;
100   /* by default, codec_data from sinkpad is prepended to first buffer: */
101   GstBuffer *codec_data;
103   /* workaround enabled to indicate that timestamp from demuxer is PTS,
104    * not DTS (cough, cough.. avi):
105    */
106   gboolean ts_is_pts;
108   /* auto-detection for ts_is_pts workaround.. if we detect out of order
109    * timestamps from demuxer/parser, then the ts is definitely DTS,
110    * otherwise it may be PTS and out of order timestamps out of decoder
111    * will trigger the ts_is_pts workaround.
112    */
113   gboolean ts_may_be_pts;
115   gboolean wait_keyframe;
117   gboolean needs_flushing;
119   GHashTable *passed_in_bufs;
121 #define NDTS 32
122   GstClockTime dts_queue[NDTS];
123   gint dts_ridx, dts_widx;
124   GstClockTime last_dts, last_pts;
126   Engine_Handle           engine;
127   VIDDEC3_Handle          codec;
128   VIDDEC3_Params         *params;
129   VIDDEC3_DynamicParams  *dynParams;
130   VIDDEC3_Status         *status;
131   XDM2_BufDesc           *inBufs;
132   XDM2_BufDesc           *outBufs;
133   VIDDEC3_InArgs         *inArgs;
134   VIDDEC3_OutArgs        *outArgs;
136   XDAS_Int16 pageMemType;
137   struct omap_device *device;
138 };
140 struct _GstDucatiVidDecClass
142   GstElementClass parent_class;
144   const gchar *codec_name;
146   /**
147    * Parse codec specific fields the given caps structure.  The base-
148    * class implementation of this method handles standard stuff like
149    * width/height/framerate/codec_data.
150    */
151   gboolean (*parse_caps) (GstDucatiVidDec * self, GstStructure * s);
153   /**
154    * Called when the input buffer size changes, to recalculate codec required
155    * output buffer size and minimum count
156    */
157   void (*update_buffer_size) (GstDucatiVidDec * self);
159   /**
160    * Called to allocate/initialize  params/dynParams/status/inArgs/outArgs
161    */
162   gboolean (*allocate_params) (GstDucatiVidDec * self, gint params_sz,
163       gint dynparams_sz, gint status_sz, gint inargs_sz, gint outargs_sz);
165   /**
166    * Push input data into codec's input buffer, returning a sub-buffer of
167    * any remaining data, or NULL if none.  Consumes reference to 'buf'
168    */
169   GstBuffer * (*push_input) (GstDucatiVidDec * self, GstBuffer * buf);
171   /**
172    * Called to handle errors returned by VIDDEC3_process.
173    */
174   gint (*handle_error) (GstDucatiVidDec * self, gint ret, gint extended_error,
175       gint status_extended_error);
177   /**
178    * Called to check whether it's a good idea to drop buf or not.
179    */
180   gboolean (*can_drop_frame) (GstDucatiVidDec * self, GstBuffer * buf, gint64 diff);
182   gboolean (*query) (GstDucatiVidDec * self, GstPad * pad, GstQuery * query,
183       gboolean * forward);
185   /**
186    * Called to push a decoder buffer. Consumes reference to 'buf'.
187    */
188   GstFlowReturn (*push_output) (GstDucatiVidDec * self, GstBuffer * buf);
190   /**
191    * Called before a flush happens.
192    */
193   void (*on_flush) (GstDucatiVidDec * self, gboolean eos);
195   /**
196    * Called to set new caps on the sink pad.
197    */
198   gboolean (*set_sink_caps) (GstDucatiVidDec * self, GstCaps *caps);
199 };
201 GType gst_ducati_viddec_get_type (void);
203 /* helper methods for derived classes: */
205 static inline void
206 push_input (GstDucatiVidDec * self, const guint8 *in, gint sz)
208   GST_DEBUG_OBJECT (self, "push: %d bytes)", sz);
209   memcpy (self->input + self->in_size, in, sz);
210   self->in_size += sz;
213 static inline int
214 check_start_code (const guint8 *sc, gint scsize,
215     const guint8 *inbuf, gint insize)
217   if (insize < scsize)
218     return FALSE;
220   while (scsize) {
221     if (*sc != *inbuf)
222       return FALSE;
223     scsize--;
224     sc++;
225     inbuf++;
226   }
228   return TRUE;
231 static inline int
232 find_start_code (const guint8 *sc, gint scsize,
233     const guint8 *inbuf, gint insize)
235   gint size = 0;
236   while (insize) {
237     if (check_start_code (sc, scsize, inbuf, insize))
238       break;
239     insize--;
240     size++;
241     inbuf++;
242   }
243   return size;
246 gboolean
247 gst_ducati_viddec_codec_flush (GstDucatiVidDec * self, gboolean eos);
249 G_END_DECLS
251 #endif /* __GST_DUCATIVIDDEC_H__ */