Send seek event to baseparse when aacparse seek failed in push mode
[platform/upstream/gst-plugins-good.git] / gst / audioparsers / gstaacparse.c
index e1f882d..cd15f01 100644 (file)
@@ -68,6 +68,7 @@ GST_DEBUG_CATEGORY_STATIC (aacparse_debug);
 #define ADIF_MAX_SIZE 40        /* Should be enough */
 #define ADTS_MAX_SIZE 10        /* Should be enough */
 #define LOAS_MAX_SIZE 3         /* Should be enough */
+#define RAW_MAX_SIZE  1         /* Correct framing is required */
 
 #define ADTS_HEADERS_LENGTH 7UL /* Total byte-length of fixed and variable
                                    headers prepended during raw to ADTS
@@ -115,14 +116,13 @@ static gboolean gst_aac_parse_read_audio_specific_config (GstAacParse *
 
 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
 static guint gst_aac_parse_adts_get_fast_frame_len (const guint8 * data);
-static gboolean gst_aac_parse_src_eventfunc (GstBaseParse * parse,
-    GstEvent * event);
 /* make full aac(adts) index table when seek */
 static gboolean gst_aac_parse_adts_src_eventfunc (GstBaseParse * parse,
     GstEvent * event);
 int get_aac_parse_get_adts_frame_length (const unsigned char *data,
     gint64 offset);
 static gboolean gst_aac_parse_estimate_duration (GstBaseParse * parse);
+static void gst_aac_parse_check_byte_seekability (GstBaseParse * parse);
 #endif
 
 #define gst_aac_parse_parent_class parent_class
@@ -263,6 +263,19 @@ gst_aac_parse_set_src_caps (GstAacParse * aacparse, GstCaps * sink_caps)
   if (stream_format)
     gst_structure_set (s, "stream-format", G_TYPE_STRING, stream_format, NULL);
 
+#ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
+  if (!gst_structure_get_value (s, "codec_data")) {
+    GstBuffer *codec_data_buffer;
+    GST_WARNING("Insert codec_data to src_caps");
+    /* The codec_data data is according to AudioSpecificConfig,
+       ISO/IEC 14496-3, 1.6.2.1 */
+    codec_data_buffer = gst_buffer_new_and_alloc (2);
+    gst_buffer_fill (codec_data_buffer, 0, codec_data, 2);
+    gst_caps_set_simple (src_caps, "codec_data", GST_TYPE_BUFFER, codec_data_buffer, NULL);
+    gst_buffer_unref (codec_data_buffer);
+  }
+#endif
+
   allowed = gst_pad_get_allowed_caps (GST_BASE_PARSE (aacparse)->srcpad);
   if (allowed && !gst_caps_can_intersect (src_caps, allowed)) {
     GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
@@ -285,6 +298,7 @@ gst_aac_parse_set_src_caps (GstAacParse * aacparse, GstCaps * sink_caps)
         gst_buffer_fill (codec_data_buffer, 0, codec_data, 2);
         gst_caps_set_simple (src_caps, "codec_data", GST_TYPE_BUFFER,
             codec_data_buffer, NULL);
+        gst_buffer_unref (codec_data_buffer);
       }
     } else if (aacparse->header_type == DSPAAC_HEADER_NONE) {
       GST_DEBUG_OBJECT (GST_BASE_PARSE (aacparse)->srcpad,
@@ -372,6 +386,9 @@ gst_aac_parse_sink_setcaps (GstBaseParse * parse, GstCaps * caps)
       gst_aac_parse_set_src_caps (aacparse, caps);
       if (aacparse->header_type == aacparse->output_header_type)
         gst_base_parse_set_passthrough (parse, TRUE);
+
+      /* input is already correctly framed */
+      gst_base_parse_set_min_frame_size (parse, RAW_MAX_SIZE);
     } else {
       return FALSE;
     }
@@ -1270,7 +1287,7 @@ gst_aac_parse_prepend_adts_headers (GstAacParse * aacparse,
   adts_headers[0] = 0xFFU;
   adts_headers[1] = 0xF0U | (id << 3) | 0x1U;
   adts_headers[2] = (profile << 6) | (sampling_frequency_index << 2) | 0x2U |
-      (channel_configuration & 0x4U);
+      ((channel_configuration & 0x4U) >> 2);
   adts_headers[3] = ((channel_configuration & 0x3U) << 6) | 0x30U |
       (guint8) (frame_size >> 11);
   adts_headers[4] = (guint8) ((frame_size >> 3) & 0x00FF);
@@ -1406,6 +1423,7 @@ gst_aac_parse_handle_frame (GstBaseParse * parse,
         GST_WARNING_OBJECT (aacparse, "can not estimate total duration");
         ret = GST_FLOW_NOT_SUPPORTED;
       }
+      gst_aac_parse_check_byte_seekability (parse);
     }
 #endif
   } else if (aacparse->header_type == DSPAAC_HEADER_LOAS) {
@@ -1726,12 +1744,10 @@ gst_aac_parse_src_event (GstBaseParse * parse, GstEvent * event)
     aacparse->last_parsed_sample_rate = 0;
   }
 #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
-  GST_DEBUG ("Entering gst_aac_parse_src_eventfunc header type = %d",
+  GST_DEBUG ("Entering gst_aac_parse_src_event header type = %d",
       aacparse->header_type);
   if (aacparse->header_type == DSPAAC_HEADER_ADTS)
     return gst_aac_parse_adts_src_eventfunc (parse, event);
-
-aac_seek_null_exit:
 #endif
   return GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
 
@@ -2123,10 +2139,18 @@ gst_aac_parse_adts_src_eventfunc (GstBaseParse * parse, GstEvent * event)
         GstPad *srcpad = parse->srcpad;
         GST_INFO_OBJECT (aacparse, "aac parser is PUSH MODE.");
         /* check NULL */
-        ret = gst_aac_audio_parse_do_push_seek (parse, srcpad, event);
-        gst_object_unref (srcpad);
-        return ret;
+        if (aacparse->byte_seekable) {
+          ret = gst_aac_audio_parse_do_push_seek (parse, srcpad, event);
+          if (!ret) {
+            GST_INFO_OBJECT (aacparse, "PUSH mode seek() failed, Trying base seek()");
+            goto aac_seek_null_exit;
+          }
+          return ret;
+        }
+        GST_INFO_OBJECT (aacparse, "not support byte seek");
+        goto aac_seek_null_exit;
       }
+
       gst_base_parse_get_upstream_size (parse, &total_file_size);
       gst_base_parse_get_index_last_offset (parse, &start_offset);
       gst_base_parse_get_index_last_ts (parse, &current_ts);
@@ -2313,4 +2337,25 @@ aac_seek_null_exit:
   handled = GST_BASE_PARSE_CLASS (parent_class)->src_event (parse, event);
   return handled;
 }
-#endif //end of #ifdef TIZEN_FEATURE_AACPARSE_MODIFICATION
+
+static void
+gst_aac_parse_check_byte_seekability (GstBaseParse * parse)
+{
+  GstQuery *query;
+  gboolean seekable = FALSE;
+  GstAacParse *aacparse = GST_AAC_PARSE (parse);
+  GST_LOG_OBJECT (aacparse, "gst_aac_parse_check_byte_seekability enter");
+
+  query = gst_query_new_seeking (GST_FORMAT_BYTES);
+  if (gst_pad_peer_query (parse->sinkpad, query))
+    gst_query_parse_seeking (query, NULL, &seekable, NULL, NULL);
+  else
+    GST_DEBUG_OBJECT (aacparse, "seeking query failed");
+
+  gst_query_unref (query);
+
+  GST_INFO_OBJECT (aacparse, "byte seekable: %d", seekable);
+
+  aacparse->byte_seekable = seekable;
+}
+#endif /* TIZEN_FEATURE_AACPARSE_MODIFICATION */