faad: cater for renegotiation
authorMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Tue, 12 Oct 2010 16:17:27 +0000 (18:17 +0200)
committerMark Nauwelaerts <mark.nauwelaerts@collabora.co.uk>
Tue, 12 Oct 2010 16:19:54 +0000 (18:19 +0200)
At least, whenever either stream (e.g. ADTS) or upstream provides necessary
info for doing so.

Fixes #631501.

ext/faad/gstfaad.c
ext/faad/gstfaad.h

index 8e4e614..2ee8324 100644 (file)
@@ -268,6 +268,7 @@ gst_faad_reset (GstFaad * faad)
   faad->bytes_in = 0;
   faad->sum_dur_out = 0;
   faad->error_count = 0;
+  faad->last_header = 0;
 
   gst_faad_reset_stream_state (faad);
 }
@@ -391,6 +392,7 @@ gst_faad_setcaps (GstPad * pad, GstCaps * caps)
   } else if ((value = gst_structure_get_value (str, "framed")) &&
       g_value_get_boolean (value) == TRUE) {
     faad->packetised = TRUE;
+    faad->init = FALSE;
     GST_DEBUG_OBJECT (faad, "we have packetized audio");
   } else {
     faad->init = FALSE;
@@ -1098,6 +1100,7 @@ gst_faad_chain (GstPad * pad, GstBuffer * buffer)
     }
   }
 
+init:
   /* init if not already done during capsnego */
   if (!faad->init) {
 #if FAAD2_MINOR_VERSION >= 7
@@ -1147,6 +1150,14 @@ gst_faad_chain (GstPad * pad, GstBuffer * buffer)
       if (input_size < FAAD_MIN_STREAMSIZE || info.bytesconsumed <= 0) {
         break;
       }
+      /* faad only really parses ADTS header at Init time, not when decoding,
+       * so monitor for changes and kick faad when needed */
+      if (GST_READ_UINT32_BE (input_data) >> 4 != faad->last_header >> 4) {
+        GST_DEBUG_OBJECT (faad, "ADTS header changed, forcing Init");
+        faad->init = FALSE;
+        faad->last_header = GST_READ_UINT32_BE (input_data);
+        goto init;
+      }
     }
 
     out = faacDecDecode (faad->handle, &info, input_data, input_size);
index b13f0e7..4552250 100644 (file)
@@ -53,6 +53,7 @@ typedef struct _GstFaad {
   guchar    *channel_positions;
 
   guint8     fake_codec_data[2];
+  guint32    last_header;
 
   GstAdapter *adapter;