Bug 973379 - GStreamerReader::ReadMetadata()'s element config loop should break on error to avoid timeout. r=edwin
authorAlessandro Decina <alessandro.d@gmail.com>
Tue, 18 Feb 2014 11:28:04 +1300
changeset 169503 047ac8e24409b423ee3042000e62451f52fb5928
parent 169502 2dd72beeb8f23852a2950010fe3e4d8ac1c4abdf
child 169504 9945bc3b7d36c659395bf69f2306f7ba74427ddb
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersedwin
bugs973379
milestone30.0a1
Bug 973379 - GStreamerReader::ReadMetadata()'s element config loop should break on error to avoid timeout. r=edwin
content/media/gstreamer/GStreamerReader.cpp
--- a/content/media/gstreamer/GStreamerReader.cpp
+++ b/content/media/gstreamer/GStreamerReader.cpp
@@ -332,40 +332,50 @@ nsresult GStreamerReader::ReadMetadata(M
        */
       GstCaps* filterCaps = gst_caps_new_simple ("skip", nullptr, nullptr);
       g_object_set(filter, "caps", filterCaps, nullptr);
       gst_caps_unref(filterCaps);
       gst_object_unref(filter);
     }
 
     LOG(PR_LOG_DEBUG, ("starting metadata pipeline"));
-    gst_element_set_state(mPlayBin, GST_STATE_PAUSED);
+    if (gst_element_set_state(mPlayBin, GST_STATE_PAUSED) == GST_STATE_CHANGE_FAILURE) {
+      LOG(PR_LOG_DEBUG, ("metadata pipeline state change failed"));
+      ret = NS_ERROR_FAILURE;
+      continue;
+    }
 
     /* Wait for ASYNC_DONE, which is emitted when the pipeline is built,
      * prerolled and ready to play. Also watch for errors.
      */
     message = gst_bus_timed_pop_filtered(mBus, GST_CLOCK_TIME_NONE,
-                 (GstMessageType)(GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR));
-    if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_ERROR) {
-      GError* error;
-      gchar* debug;
-
-      gst_message_parse_error(message, &error, &debug);
-      LOG(PR_LOG_ERROR, ("read metadata error: %s: %s", error->message,
-                         debug));
-      g_error_free(error);
-      g_free(debug);
-      gst_element_set_state(mPlayBin, GST_STATE_NULL);
-      gst_message_unref(message);
-      ret = NS_ERROR_FAILURE;
-    } else {
+                 (GstMessageType)(GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR | GST_MESSAGE_EOS));
+    if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_ASYNC_DONE) {
       LOG(PR_LOG_DEBUG, ("read metadata pipeline prerolled"));
       gst_message_unref(message);
       ret = NS_OK;
       break;
+    } else {
+      LOG(PR_LOG_DEBUG, ("read metadata pipeline failed to preroll: %s",
+            gst_message_type_get_name (GST_MESSAGE_TYPE (message))));
+
+      if (GST_MESSAGE_TYPE(message) == GST_MESSAGE_ERROR) {
+        GError* error;
+        gchar* debug;
+        gst_message_parse_error(message, &error, &debug);
+        LOG(PR_LOG_ERROR, ("read metadata error: %s: %s", error->message,
+                           debug));
+        g_error_free(error);
+        g_free(debug);
+      }
+      /* Unexpected stream close/EOS or other error. We'll give up if all
+       * streams are in error/eos. */
+      gst_element_set_state(mPlayBin, GST_STATE_NULL);
+      gst_message_unref(message);
+      ret = NS_ERROR_FAILURE;
     }
   }
 
   if (NS_SUCCEEDED(ret))
     ret = CheckSupportedFormats();
 
   if (NS_FAILED(ret))
     /* we couldn't get this to play */
@@ -374,22 +384,25 @@ nsresult GStreamerReader::ReadMetadata(M
   /* FIXME: workaround for a bug in matroskademux. This seek makes matroskademux
    * parse the index */
   LOG(PR_LOG_DEBUG, ("doing matroskademux seek hack"));
   if (gst_element_seek_simple(mPlayBin, GST_FORMAT_TIME,
         GST_SEEK_FLAG_FLUSH, 0)) {
     /* after a seek we need to wait again for ASYNC_DONE */
     message = gst_bus_timed_pop_filtered(mBus, 5 * GST_SECOND,
        (GstMessageType)(GST_MESSAGE_ASYNC_DONE | GST_MESSAGE_ERROR));
-    LOG(PR_LOG_DEBUG, ("matroskademux seek hack done"));
-    if (GST_MESSAGE_TYPE(message) != GST_MESSAGE_ASYNC_DONE) {
+    if (message == NULL || GST_MESSAGE_TYPE(message) != GST_MESSAGE_ASYNC_DONE) {
+      LOG(PR_LOG_DEBUG, ("matroskademux seek hack failed: %p", message));
       gst_element_set_state(mPlayBin, GST_STATE_NULL);
-      gst_message_unref(message);
+      if (message) {
+        gst_message_unref(message);
+      }
       return NS_ERROR_FAILURE;
     }
+    LOG(PR_LOG_DEBUG, ("matroskademux seek hack completed"));
   } else {
     LOG(PR_LOG_DEBUG, ("matroskademux seek hack failed (non fatal)"));
   }
 
   bool isMP3 = mDecoder->GetResource()->GetContentType().EqualsASCII(AUDIO_MP3);
   if (isMP3) {
     ParseMP3Headers();
   }