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 <unistd.h>
26 #include <omap_drm.h>
27 #include <omap_drmif.h>
29 #include "gstducati.h"
30 #include "gstducatibufferpriv.h"
32 #include <gst/drm/gstdrmbufferpool.h>
33 #include <gst/video/video.h>
34 #include <gst/video/video-crop.h>
36 G_BEGIN_DECLS
38 #define GST_TYPE_DUCATIVIDDEC (gst_ducati_viddec_get_type())
39 #define GST_DUCATIVIDDEC(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), GST_TYPE_DUCATIVIDDEC, GstDucatiVidDec))
40 #define GST_DUCATIVIDDEC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), GST_TYPE_DUCATIVIDDEC, GstDucatiVidDecClass))
41 #define GST_IS_DUCATIVIDDEC(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_TYPE_DUCATIVIDDEC))
42 #define GST_IS_DUCATIVIDDEC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), GST_TYPE_DUCATIVIDDEC))
43 #define GST_DUCATIVIDDEC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GST_TYPE_DUCATIVIDDEC, GstDucatiVidDecClass))
45 typedef struct _GstDucatiVidDec GstDucatiVidDec;
46 typedef struct _GstDucatiVidDecClass GstDucatiVidDecClass;
48 /* For re-ordering in normal playback */
49 #define MAX_BACKLOG_FRAMES 16
50 /* For re-ordering in reverse playback */
51 #define MAX_BACKLOG_ARRAY_SIZE 120
53 struct _GstDucatiVidDec
54 {
55 GstElement parent;
57 GstPad *sinkpad, *srcpad;
59 GstDRMBufferPool *pool;
61 /* minimum output size required by the codec: */
62 gint outsize;
64 /* minimum number of buffers required by the codec: */
65 gint min_buffers;
67 /* input (unpadded, unaligned) size of video: */
68 gint input_width, input_height;
70 /* input (unpadded, aligned to MB) size of video: */
71 gint width, height;
73 gint fps_n, fps_d;
75 /* output (padded) size including any codec padding: */
76 gint padded_width, padded_height;
78 /* output stride (>= padded_width) */
79 gint stride;
81 gboolean interlaced;
83 struct omap_bo *input_bo;
84 /* input buffer, allocated when codec is created: */
85 guint8 *input;
87 /* number of bytes pushed to input on current frame: */
88 gint in_size;
90 /* the crop to attach to output buffers: */
91 GstVideoCrop *crop;
93 /* on first output buffer, we need to send crop info to sink.. and some
94 * operations like flushing should be avoided if we haven't sent any
95 * input buffers:
96 */
97 gboolean first_out_buffer, first_in_buffer;
98 gboolean send_crop_event;
100 GstSegment segment;
101 gdouble qos_proportion;
102 GstClockTime qos_earliest_time;
104 gboolean need_out_buf;
106 /* by default, codec_data from sinkpad is prepended to first buffer: */
107 GstBuffer *codec_data;
109 /* workaround enabled to indicate that timestamp from demuxer is PTS,
110 * not DTS (cough, cough.. avi):
111 */
112 gboolean ts_is_pts;
114 /* auto-detection for ts_is_pts workaround.. if we detect out of order
115 * timestamps from demuxer/parser, then the ts is definitely DTS,
116 * otherwise it may be PTS and out of order timestamps out of decoder
117 * will trigger the ts_is_pts workaround.
118 */
119 gboolean ts_may_be_pts;
121 gboolean wait_keyframe;
123 gboolean needs_flushing;
125 GHashTable *passed_in_bufs;
127 #define NDTS 32
128 GstClockTime dts_queue[NDTS];
129 gint dts_ridx, dts_widx;
130 GstClockTime last_dts, last_pts;
132 Engine_Handle engine;
133 VIDDEC3_Handle codec;
134 VIDDEC3_Params *params;
135 VIDDEC3_DynamicParams *dynParams;
136 VIDDEC3_Status *status;
137 XDM2_BufDesc *inBufs;
138 XDM2_BufDesc *outBufs;
139 VIDDEC3_InArgs *inArgs;
140 VIDDEC3_OutArgs *outArgs;
142 XDAS_Int16 pageMemType;
143 struct omap_device *device;
145 /* Frames waiting to be reordered */
146 GstBuffer *backlog_frames[MAX_BACKLOG_ARRAY_SIZE + 1];
147 gint backlog_maxframes;
148 gint backlog_nframes;
149 gint backlog_max_maxframes;
151 gboolean codec_debug_info;
153 const char *error_strings[32];
154 };
156 struct _GstDucatiVidDecClass
157 {
158 GstElementClass parent_class;
160 const gchar *codec_name;
162 /**
163 * Parse codec specific fields the given caps structure. The base-
164 * class implementation of this method handles standard stuff like
165 * width/height/framerate/codec_data.
166 */
167 gboolean (*parse_caps) (GstDucatiVidDec * self, GstStructure * s);
169 /**
170 * Called when the input buffer size changes, to recalculate codec required
171 * output buffer size and minimum count
172 */
173 void (*update_buffer_size) (GstDucatiVidDec * self);
175 /**
176 * Called to allocate/initialize params/dynParams/status/inArgs/outArgs
177 */
178 gboolean (*allocate_params) (GstDucatiVidDec * self, gint params_sz,
179 gint dynparams_sz, gint status_sz, gint inargs_sz, gint outargs_sz);
181 /**
182 * Push input data into codec's input buffer, returning a sub-buffer of
183 * any remaining data, or NULL if none. Consumes reference to 'buf'
184 */
185 GstBuffer * (*push_input) (GstDucatiVidDec * self, GstBuffer * buf);
187 /**
188 * Called to handle errors returned by VIDDEC3_process.
189 */
190 gint (*handle_error) (GstDucatiVidDec * self, gint ret, gint extended_error,
191 gint status_extended_error);
193 /**
194 * Called to check whether it's a good idea to drop buf or not.
195 */
196 gboolean (*can_drop_frame) (GstDucatiVidDec * self, GstBuffer * buf, gint64 diff);
198 gboolean (*query) (GstDucatiVidDec * self, GstPad * pad, GstQuery * query,
199 gboolean * forward);
201 /**
202 * Called to push a decoder buffer. Consumes reference to 'buf'.
203 */
204 GstFlowReturn (*push_output) (GstDucatiVidDec * self, GstBuffer * buf);
206 /**
207 * Called before a flush happens.
208 */
209 void (*on_flush) (GstDucatiVidDec * self, gboolean eos);
211 /**
212 * Called to set new caps on the sink pad.
213 */
214 gboolean (*set_sink_caps) (GstDucatiVidDec * self, GstCaps *caps);
215 };
217 GType gst_ducati_viddec_get_type (void);
219 /* helper methods for derived classes: */
221 static inline void
222 push_input (GstDucatiVidDec * self, const guint8 *in, gint sz)
223 {
224 GST_DEBUG_OBJECT (self, "push: %d bytes)", sz);
225 memcpy (self->input + self->in_size, in, sz);
226 self->in_size += sz;
227 }
229 static inline int
230 check_start_code (const guint8 *sc, gint scsize,
231 const guint8 *inbuf, gint insize)
232 {
233 if (insize < scsize)
234 return FALSE;
236 while (scsize) {
237 if (*sc != *inbuf)
238 return FALSE;
239 scsize--;
240 sc++;
241 inbuf++;
242 }
244 return TRUE;
245 }
247 static inline int
248 find_start_code (const guint8 *sc, gint scsize,
249 const guint8 *inbuf, gint insize)
250 {
251 gint size = 0;
252 while (insize) {
253 if (check_start_code (sc, scsize, inbuf, insize))
254 break;
255 insize--;
256 size++;
257 inbuf++;
258 }
259 return size;
260 }
262 gboolean
263 gst_ducati_viddec_codec_flush (GstDucatiVidDec * self, gboolean eos);
265 G_END_DECLS
267 #endif /* __GST_DUCATIVIDDEC_H__ */