amcaudiodec: Calculate number of samples per frame for MP3 and use that
authorSebastian Dröge <sebastian@centricular.com>
Fri, 14 Feb 2014 11:39:06 +0000 (12:39 +0100)
committerSebastian Dröge <sebastian@centricular.com>
Fri, 14 Feb 2014 11:53:56 +0000 (12:53 +0100)
Some audio decoders (at least the MP3 decoder on MTK based devices) outputs
raw audio in batches of multiple audio frames. We need to handle that
properly, otherwise the base class will be kind of unhappy.

sys/androidmedia/gstamcaudiodec.c
sys/androidmedia/gstamcaudiodec.h

index e8526752f4d923faec82c9177d345a0b6d93bb9f..f8649e89606a538c9c92500f51ace6a7f924acfa 100644 (file)
@@ -612,6 +612,7 @@ retry:
     GstBuffer *outbuf;
     GstAmcBuffer *buf;
     GstMapInfo minfo;
+    gint nframes;
 
     /* This sometimes happens at EOS or if the input is not properly framed,
      * let's handle it gracefully by allocating a new buffer for the current
@@ -661,12 +662,18 @@ retry:
     }
     gst_buffer_unmap (outbuf, &minfo);
 
-    /* FIXME: We should get one decoded input frame here for
-     * every buffer. If this is not the case somewhere, we will
-     * error out at some point and will need to add workarounds
-     */
+    nframes = 1;
+    if (self->spf != -1) {
+      nframes = buffer_info.size / self->info.bpf;
+      if (nframes % self->spf != 0)
+        GST_WARNING_OBJECT (self, "Output buffer does not contain an integer "
+            "number of input frames (frames: %d, spf: %d)", nframes, self->spf);
+      nframes = (nframes + self->spf - 1) / self->spf;
+    }
+
     flow_ret =
-        gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (self), outbuf, 1);
+        gst_audio_decoder_finish_frame (GST_AUDIO_DECODER (self), outbuf,
+        nframes);
   }
 
 done:
@@ -1008,6 +1015,26 @@ gst_amc_audio_dec_set_format (GstAudioDecoder * decoder, GstCaps * caps)
     return FALSE;
   }
 
+  self->spf = -1;
+  /* TODO: Implement for other codecs too */
+  if (gst_structure_has_name (s, "audio/mpeg")) {
+    gint mpegversion = -1;
+
+    gst_structure_get_int (s, "mpegversion", &mpegversion);
+    if (mpegversion == 1) {
+      gint layer = -1, mpegaudioversion = -1;
+
+      gst_structure_get_int (s, "layer", &layer);
+      gst_structure_get_int (s, "mpegaudioversion", &mpegaudioversion);
+      if (layer == 1)
+        self->spf = 384;
+      else if (layer == 2)
+        self->spf = 1152;
+      else if (layer == 3 && mpegaudioversion != -1)
+        self->spf = (mpegaudioversion == 1 ? 1152 : 576);
+    }
+  }
+
   self->started = TRUE;
   self->input_caps_changed = TRUE;
 
index ee52181900862fd34b1b05bb8ba1734df6c34c51..50500a862c5250f98bbe292012f7b3c935d93293 100644 (file)
@@ -57,6 +57,7 @@ struct _GstAmcAudioDec
   GstCaps *input_caps;
   GList *codec_datas;
   gboolean input_caps_changed;
+  gint spf;
 
   /* Output format of the codec */
   GstAudioInfo info;