Tizen 2.0 Release
[framework/multimedia/gst-plugins-bad0.10.git] / ext / schroedinger / gstschrodec.c
1 /* Schrodinger
2  * Copyright (C) 2006 David Schleef <ds@schleef.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <gst/gst.h>
25 #include <gst/base/gstadapter.h>
26 #include <gst/video/video.h>
27 #include <gst/video/gstbasevideodecoder.h>
28 #include <string.h>
29 #include <schroedinger/schro.h>
30 #include <math.h>
31 #include "gstschroutils.h"
32
33 #include <schroedinger/schroparse.h>
34
35 GST_DEBUG_CATEGORY_EXTERN (schro_debug);
36 #define GST_CAT_DEFAULT schro_debug
37
38 #define GST_TYPE_SCHRO_DEC \
39   (gst_schro_dec_get_type())
40 #define GST_SCHRO_DEC(obj) \
41   (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SCHRO_DEC,GstSchroDec))
42 #define GST_SCHRO_DEC_CLASS(klass) \
43   (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SCHRO_DEC,GstSchroDecClass))
44 #define GST_IS_SCHRO_DEC(obj) \
45   (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SCHRO_DEC))
46 #define GST_IS_SCHRO_DEC_CLASS(obj) \
47   (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SCHRO_DEC))
48
49 typedef struct _GstSchroDec GstSchroDec;
50 typedef struct _GstSchroDecClass GstSchroDecClass;
51
52 struct _GstSchroDec
53 {
54   GstBaseVideoDecoder base_video_decoder;
55
56   SchroDecoder *decoder;
57
58   gboolean seq_header_buffer_seen;
59 };
60
61 struct _GstSchroDecClass
62 {
63   GstBaseVideoDecoderClass base_video_decoder_class;
64 };
65
66 GType gst_schro_dec_get_type (void);
67
68
69 /* GstSchroDec signals and args */
70 enum
71 {
72   LAST_SIGNAL
73 };
74
75 enum
76 {
77   ARG_0
78 };
79
80 static void gst_schro_dec_finalize (GObject * object);
81
82 static gboolean gst_schro_dec_sink_query (GstPad * pad, GstQuery * query);
83
84 static gboolean gst_schro_dec_start (GstBaseVideoDecoder * dec);
85 static gboolean gst_schro_dec_stop (GstBaseVideoDecoder * dec);
86 static gboolean gst_schro_dec_reset (GstBaseVideoDecoder * dec);
87 static GstFlowReturn gst_schro_dec_parse_data (GstBaseVideoDecoder *
88     base_video_decoder, gboolean at_eos);
89 static GstFlowReturn gst_schro_dec_handle_frame (GstBaseVideoDecoder * decoder,
90     GstVideoFrame * frame);
91 static gboolean gst_schro_dec_finish (GstBaseVideoDecoder * base_video_decoder);
92 static void gst_schrodec_send_tags (GstSchroDec * schro_dec);
93
94 static GstStaticPadTemplate gst_schro_dec_sink_template =
95 GST_STATIC_PAD_TEMPLATE ("sink",
96     GST_PAD_SINK,
97     GST_PAD_ALWAYS,
98     GST_STATIC_CAPS ("video/x-dirac")
99     );
100
101 static GstStaticPadTemplate gst_schro_dec_src_template =
102 GST_STATIC_PAD_TEMPLATE ("src",
103     GST_PAD_SRC,
104     GST_PAD_ALWAYS,
105     GST_STATIC_CAPS (GST_VIDEO_CAPS_YUV ("{ I420, YUY2, AYUV }"))
106     );
107
108 GST_BOILERPLATE (GstSchroDec, gst_schro_dec, GstBaseVideoDecoder,
109     GST_TYPE_BASE_VIDEO_DECODER);
110
111 static void
112 gst_schro_dec_base_init (gpointer g_class)
113 {
114
115   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
116
117   gst_element_class_add_static_pad_template (element_class,
118       &gst_schro_dec_src_template);
119   gst_element_class_add_static_pad_template (element_class,
120       &gst_schro_dec_sink_template);
121
122   gst_element_class_set_details_simple (element_class, "Dirac Decoder",
123       "Codec/Decoder/Video",
124       "Decode Dirac streams", "David Schleef <ds@schleef.org>");
125 }
126
127 static void
128 gst_schro_dec_class_init (GstSchroDecClass * klass)
129 {
130   GObjectClass *gobject_class;
131   GstBaseVideoDecoderClass *base_video_decoder_class;
132
133   gobject_class = G_OBJECT_CLASS (klass);
134   base_video_decoder_class = GST_BASE_VIDEO_DECODER_CLASS (klass);
135
136   gobject_class->finalize = gst_schro_dec_finalize;
137
138   base_video_decoder_class->start = GST_DEBUG_FUNCPTR (gst_schro_dec_start);
139   base_video_decoder_class->stop = GST_DEBUG_FUNCPTR (gst_schro_dec_stop);
140   base_video_decoder_class->reset = GST_DEBUG_FUNCPTR (gst_schro_dec_reset);
141   base_video_decoder_class->parse_data =
142       GST_DEBUG_FUNCPTR (gst_schro_dec_parse_data);
143   base_video_decoder_class->handle_frame =
144       GST_DEBUG_FUNCPTR (gst_schro_dec_handle_frame);
145   base_video_decoder_class->finish = GST_DEBUG_FUNCPTR (gst_schro_dec_finish);
146
147   gst_base_video_decoder_class_set_capture_pattern (base_video_decoder_class,
148       0xffffffff, 0x42424344);
149 }
150
151 static void
152 gst_schro_dec_init (GstSchroDec * schro_dec, GstSchroDecClass * klass)
153 {
154   GST_DEBUG ("gst_schro_dec_init");
155
156   gst_pad_set_query_function (GST_BASE_VIDEO_CODEC_SINK_PAD (schro_dec),
157       gst_schro_dec_sink_query);
158
159   schro_dec->decoder = schro_decoder_new ();
160 }
161
162 #define OGG_DIRAC_GRANULE_SHIFT 22
163 #define OGG_DIRAC_GRANULE_LOW_MASK ((1ULL<<OGG_DIRAC_GRANULE_SHIFT)-1)
164
165 static gint64
166 granulepos_to_frame (gint64 granulepos)
167 {
168   guint64 pt;
169
170   if (granulepos == -1)
171     return -1;
172
173   pt = ((granulepos >> 22) + (granulepos & OGG_DIRAC_GRANULE_LOW_MASK)) >> 9;
174   /* dist_h = (granulepos >> 22) & 0xff;
175    * dist_l = granulepos & 0xff;
176    * dist = (dist_h << 8) | dist_l;
177    * delay = (granulepos >> 9) & 0x1fff;
178    * dt = pt - delay; */
179
180   return pt >> 1;
181 }
182
183 static gboolean
184 gst_schro_dec_sink_convert (GstPad * pad,
185     GstFormat src_format, gint64 src_value,
186     GstFormat * dest_format, gint64 * dest_value)
187 {
188   gboolean res = TRUE;
189   GstSchroDec *dec;
190   GstVideoState *state;
191
192   if (src_format == *dest_format) {
193     *dest_value = src_value;
194     return TRUE;
195   }
196
197   dec = GST_SCHRO_DEC (gst_pad_get_parent (pad));
198
199   /* FIXME: check if we are in a decoding state */
200
201   state = gst_base_video_decoder_get_state (GST_BASE_VIDEO_DECODER (dec));
202
203   res = FALSE;
204   if (src_format == GST_FORMAT_DEFAULT && *dest_format == GST_FORMAT_TIME) {
205     if (state->fps_d != 0) {
206       *dest_value = gst_util_uint64_scale (granulepos_to_frame (src_value),
207           state->fps_d * GST_SECOND, state->fps_n);
208       res = TRUE;
209     } else {
210       res = FALSE;
211     }
212   }
213
214   gst_object_unref (dec);
215
216   return res;
217 }
218
219 static gboolean
220 gst_schro_dec_sink_query (GstPad * pad, GstQuery * query)
221 {
222   GstSchroDec *dec;
223   gboolean res = FALSE;
224
225   dec = GST_SCHRO_DEC (gst_pad_get_parent (pad));
226
227   switch (GST_QUERY_TYPE (query)) {
228     case GST_QUERY_CONVERT:
229     {
230       GstFormat src_fmt, dest_fmt;
231       gint64 src_val, dest_val;
232
233       gst_query_parse_convert (query, &src_fmt, &src_val, &dest_fmt, &dest_val);
234       res = gst_schro_dec_sink_convert (pad, src_fmt, src_val, &dest_fmt,
235           &dest_val);
236       if (!res)
237         goto error;
238       gst_query_set_convert (query, src_fmt, src_val, dest_fmt, dest_val);
239       break;
240     }
241     default:
242       res = gst_pad_query_default (pad, query);
243       break;
244   }
245 done:
246   gst_object_unref (dec);
247
248   return res;
249 error:
250   GST_DEBUG_OBJECT (dec, "query failed");
251   goto done;
252 }
253
254 static gboolean
255 gst_schro_dec_start (GstBaseVideoDecoder * dec)
256 {
257
258   return TRUE;
259 }
260
261 static gboolean
262 gst_schro_dec_stop (GstBaseVideoDecoder * dec)
263 {
264
265   return TRUE;
266 }
267
268 static gboolean
269 gst_schro_dec_reset (GstBaseVideoDecoder * dec)
270 {
271   GstSchroDec *schro_dec;
272
273   schro_dec = GST_SCHRO_DEC (dec);
274
275   GST_DEBUG ("reset");
276
277   if (schro_dec->decoder) {
278     schro_decoder_reset (schro_dec->decoder);
279   }
280
281   return TRUE;
282 }
283
284 static void
285 gst_schro_dec_finalize (GObject * object)
286 {
287   GstSchroDec *schro_dec;
288
289   g_return_if_fail (GST_IS_SCHRO_DEC (object));
290   schro_dec = GST_SCHRO_DEC (object);
291
292   if (schro_dec->decoder) {
293     schro_decoder_free (schro_dec->decoder);
294     schro_dec->decoder = NULL;
295   }
296
297   G_OBJECT_CLASS (parent_class)->finalize (object);
298 }
299
300 static void
301 parse_sequence_header (GstSchroDec * schro_dec, guint8 * data, int size)
302 {
303   SchroVideoFormat video_format;
304   int ret;
305   GstVideoState *state;
306
307   GST_DEBUG_OBJECT (schro_dec, "parse_sequence_header size=%d", size);
308
309   state = gst_base_video_decoder_get_state (GST_BASE_VIDEO_DECODER (schro_dec));
310
311   schro_dec->seq_header_buffer_seen = TRUE;
312
313   ret = schro_parse_decode_sequence_header (data + 13, size - 13,
314       &video_format);
315   if (ret) {
316     if (video_format.chroma_format == SCHRO_CHROMA_444) {
317       state->format = GST_VIDEO_FORMAT_AYUV;
318     } else if (video_format.chroma_format == SCHRO_CHROMA_422) {
319       state->format = GST_VIDEO_FORMAT_YUY2;
320     } else if (video_format.chroma_format == SCHRO_CHROMA_420) {
321       state->format = GST_VIDEO_FORMAT_I420;
322     }
323     state->fps_n = video_format.frame_rate_numerator;
324     state->fps_d = video_format.frame_rate_denominator;
325     GST_DEBUG_OBJECT (schro_dec, "Frame rate is %d/%d", state->fps_n,
326         state->fps_d);
327
328     state->width = video_format.width;
329     state->height = video_format.height;
330     GST_DEBUG ("Frame dimensions are %d x %d\n", state->width, state->height);
331
332     state->clean_width = video_format.clean_width;
333     state->clean_height = video_format.clean_height;
334     state->clean_offset_left = video_format.left_offset;
335     state->clean_offset_top = video_format.top_offset;
336
337     state->par_n = video_format.aspect_ratio_numerator;
338     state->par_d = video_format.aspect_ratio_denominator;
339     GST_DEBUG ("Pixel aspect ratio is %d/%d", state->par_n, state->par_d);
340
341     gst_base_video_decoder_set_src_caps (GST_BASE_VIDEO_DECODER (schro_dec));
342   } else {
343     GST_WARNING ("Failed to get frame rate from sequence header");
344   }
345
346   gst_schrodec_send_tags (schro_dec);
347 }
348
349
350 static GstFlowReturn
351 gst_schro_dec_parse_data (GstBaseVideoDecoder * base_video_decoder,
352     gboolean at_eos)
353 {
354   GstSchroDec *schro_decoder;
355   unsigned char header[SCHRO_PARSE_HEADER_SIZE];
356   int next;
357   int prev;
358   int parse_code;
359
360   GST_DEBUG_OBJECT (base_video_decoder, "parse_data");
361
362   schro_decoder = GST_SCHRO_DEC (base_video_decoder);
363
364   if (gst_adapter_available (base_video_decoder->input_adapter) <
365       SCHRO_PARSE_HEADER_SIZE) {
366     return GST_BASE_VIDEO_DECODER_FLOW_NEED_DATA;
367   }
368
369   GST_DEBUG ("available %d",
370       gst_adapter_available (base_video_decoder->input_adapter));
371
372   gst_adapter_copy (base_video_decoder->input_adapter, header, 0,
373       SCHRO_PARSE_HEADER_SIZE);
374
375   parse_code = header[4];
376   next = GST_READ_UINT32_BE (header + 5);
377   prev = GST_READ_UINT32_BE (header + 9);
378
379   GST_DEBUG ("%08x %02x %08x %08x",
380       GST_READ_UINT32_BE (header), parse_code, next, prev);
381
382   if (memcmp (header, "BBCD", 4) != 0 ||
383       (next & 0xf0000000) || (prev & 0xf0000000)) {
384     gst_base_video_decoder_lost_sync (base_video_decoder);
385     return GST_BASE_VIDEO_DECODER_FLOW_NEED_DATA;
386   }
387
388   if (SCHRO_PARSE_CODE_IS_END_OF_SEQUENCE (parse_code)) {
389     GstVideoFrame *frame;
390
391     if (next != 0 && next != SCHRO_PARSE_HEADER_SIZE) {
392       GST_WARNING ("next is not 0 or 13 in EOS packet (%d)", next);
393     }
394
395     gst_base_video_decoder_add_to_frame (base_video_decoder,
396         SCHRO_PARSE_HEADER_SIZE);
397
398     frame = base_video_decoder->current_frame;
399     frame->is_eos = TRUE;
400
401     SCHRO_DEBUG ("eos");
402
403     return gst_base_video_decoder_have_frame (base_video_decoder);
404   }
405
406   if (gst_adapter_available (base_video_decoder->input_adapter) < next) {
407     return GST_BASE_VIDEO_DECODER_FLOW_NEED_DATA;
408   }
409
410   if (SCHRO_PARSE_CODE_IS_SEQ_HEADER (parse_code)) {
411     guint8 *data;
412
413     data = g_malloc (next);
414
415     gst_adapter_copy (base_video_decoder->input_adapter, data, 0, next);
416     parse_sequence_header (schro_decoder, data, next);
417
418     gst_base_video_decoder_set_sync_point (base_video_decoder);
419
420 #if 0
421     if (GST_CLOCK_TIME_IS_VALID (base_video_decoder->last_sink_timestamp)) {
422       base_video_decoder->current_frame->presentation_timestamp =
423           base_video_decoder->last_sink_timestamp;
424       GST_DEBUG ("got timestamp %" G_GINT64_FORMAT,
425           base_video_decoder->last_sink_timestamp);
426     } else if (base_video_decoder->last_sink_offset_end != -1) {
427       GstVideoState *state;
428
429 #if 0
430       /* FIXME perhaps should use this to determine if the granulepos
431        * is valid */
432       {
433         guint64 pt;
434         int dist_h;
435         int dist_l;
436         int dist;
437         int delay;
438         guint64 dt;
439         gint64 granulepos = base_video_decoder->last_sink_offset_end;
440
441         pt = ((granulepos >> 22) +
442             (granulepos & OGG_DIRAC_GRANULE_LOW_MASK)) >> 9;
443         dist_h = (granulepos >> 22) & 0xff;
444         dist_l = granulepos & 0xff;
445         dist = (dist_h << 8) | dist_l;
446         delay = (granulepos >> 9) & 0x1fff;
447         dt = pt - delay;
448         GST_DEBUG ("gp pt %lld dist %d delay %d dt %lld", pt, dist, delay, dt);
449       }
450 #endif
451       state = gst_base_video_decoder_get_state (base_video_decoder);
452       base_video_decoder->current_frame->presentation_timestamp =
453           gst_util_uint64_scale (granulepos_to_frame
454           (base_video_decoder->last_sink_offset_end), state->fps_d * GST_SECOND,
455           state->fps_n);
456     } else {
457       base_video_decoder->current_frame->presentation_timestamp = -1;
458     }
459 #endif
460
461     g_free (data);
462   }
463
464   if (!schro_decoder->seq_header_buffer_seen) {
465     gst_adapter_flush (base_video_decoder->input_adapter, next);
466     return GST_FLOW_OK;
467   }
468
469   if (SCHRO_PARSE_CODE_IS_PICTURE (parse_code)) {
470     GstVideoFrame *frame;
471     guint8 tmp[4];
472
473     frame = base_video_decoder->current_frame;
474
475     gst_adapter_copy (base_video_decoder->input_adapter, tmp,
476         SCHRO_PARSE_HEADER_SIZE, 4);
477
478     frame->presentation_frame_number = GST_READ_UINT32_BE (tmp);
479
480     gst_base_video_decoder_add_to_frame (base_video_decoder, next);
481
482     return gst_base_video_decoder_have_frame (base_video_decoder);
483   } else {
484     gst_base_video_decoder_add_to_frame (base_video_decoder, next);
485   }
486
487   return GST_FLOW_OK;
488 }
489
490 static void
491 gst_schrodec_send_tags (GstSchroDec * schro_dec)
492 {
493   GstTagList *list;
494
495   list = gst_tag_list_new ();
496   gst_tag_list_add (list, GST_TAG_MERGE_REPLACE,
497       GST_TAG_VIDEO_CODEC, "Dirac", NULL);
498
499   gst_element_found_tags_for_pad (GST_ELEMENT_CAST (schro_dec),
500       GST_BASE_VIDEO_CODEC_SRC_PAD (schro_dec), list);
501 }
502
503 static GstFlowReturn
504 gst_schro_dec_process (GstSchroDec * schro_dec, gboolean eos)
505 {
506   gboolean go;
507   GstFlowReturn ret;
508
509   ret = GST_FLOW_OK;
510   go = TRUE;
511   while (go) {
512     int it;
513
514     it = schro_decoder_autoparse_wait (schro_dec->decoder);
515
516     switch (it) {
517       case SCHRO_DECODER_FIRST_ACCESS_UNIT:
518         break;
519       case SCHRO_DECODER_NEED_BITS:
520         GST_DEBUG ("need bits");
521         go = 0;
522         break;
523       case SCHRO_DECODER_NEED_FRAME:
524       {
525         GstBuffer *outbuf;
526         GstVideoState *state;
527         SchroFrame *schro_frame;
528
529         GST_DEBUG ("need frame");
530
531         state =
532             gst_base_video_decoder_get_state (GST_BASE_VIDEO_DECODER
533             (schro_dec));
534         outbuf =
535             gst_base_video_decoder_alloc_src_buffer (GST_BASE_VIDEO_DECODER
536             (schro_dec));
537         schro_frame =
538             gst_schro_buffer_wrap (outbuf, state->format, state->width,
539             state->height);
540         schro_decoder_add_output_picture (schro_dec->decoder, schro_frame);
541         break;
542       }
543       case SCHRO_DECODER_OK:
544       {
545         SchroFrame *schro_frame;
546         SchroTag *tag;
547         GstVideoFrame *frame;
548
549         GST_DEBUG ("got frame");
550
551         tag = schro_decoder_get_picture_tag (schro_dec->decoder);
552         schro_frame = schro_decoder_pull (schro_dec->decoder);
553         frame = tag->value;
554
555         if (schro_frame) {
556           if (schro_frame->priv) {
557             GstFlowReturn flow_ret;
558
559             frame->src_buffer = gst_buffer_ref (GST_BUFFER (schro_frame->priv));
560
561             flow_ret =
562                 gst_base_video_decoder_finish_frame (GST_BASE_VIDEO_DECODER
563                 (schro_dec), frame);
564             if (flow_ret != GST_FLOW_OK) {
565               GST_DEBUG ("finish frame returned %d", flow_ret);
566               return flow_ret;
567             }
568           } else {
569             GST_DEBUG ("skipped frame");
570           }
571
572           schro_frame_unref (schro_frame);
573         }
574         if (tag)
575           schro_tag_free (tag);
576         if (!eos) {
577           go = FALSE;
578         }
579       }
580
581         break;
582       case SCHRO_DECODER_EOS:
583         GST_DEBUG ("eos");
584         go = FALSE;
585         break;
586       case SCHRO_DECODER_ERROR:
587         go = FALSE;
588         GST_DEBUG ("codec error");
589         ret = GST_FLOW_ERROR;
590         break;
591       default:
592         break;
593     }
594   }
595   return ret;
596 }
597
598 GstFlowReturn
599 gst_schro_dec_handle_frame (GstBaseVideoDecoder * base_video_decoder,
600     GstVideoFrame * frame)
601 {
602   GstSchroDec *schro_dec;
603   SchroBuffer *input_buffer;
604
605   schro_dec = GST_SCHRO_DEC (base_video_decoder);
606
607   GST_DEBUG ("handle frame");
608
609   input_buffer = gst_schro_wrap_gst_buffer (frame->sink_buffer);
610   frame->sink_buffer = NULL;
611
612   input_buffer->tag = schro_tag_new (frame, NULL);
613
614   schro_decoder_autoparse_push (schro_dec->decoder, input_buffer);
615
616   return gst_schro_dec_process (schro_dec, FALSE);
617 }
618
619 gboolean
620 gst_schro_dec_finish (GstBaseVideoDecoder * base_video_decoder)
621 {
622   GstSchroDec *schro_dec;
623
624   schro_dec = GST_SCHRO_DEC (base_video_decoder);
625
626   GST_DEBUG ("finish");
627
628   schro_decoder_autoparse_push_end_of_sequence (schro_dec->decoder);
629
630   return gst_schro_dec_process (schro_dec, TRUE);
631 }