Apply GStreamer 1.22.0 into Tizen
[platform/upstream/gstreamer.git] / subprojects / gst-plugins-good / gst / isomp4 / gstqtmux.c
index f6e76b9..173661d 100644 (file)
@@ -836,9 +836,9 @@ gst_qt_mux_class_init (GstQTMuxClass * klass)
    *
    * Currently, two options exist:
    * - "dash-or-mss": for the original fragmented mode that supports dash or
-   *   mocrosoft smoothstreaming with a single input stream
+   *   microsoft smoothstreaming with a single input stream
    * - "first-moov-then-finalise" is a fragmented mode that will start with a
-   *   self-contained 'moov' atom fo the first fragment, then produce fragments.
+   *   self-contained 'moov' atom for the first fragment, then produce fragments.
    *   When the file is finalised, the initial 'moov' is invalidated and a
    *   new 'moov' is written covering the entire file.
    *
@@ -847,7 +847,7 @@ gst_qt_mux_class_init (GstQTMuxClass * klass)
   g_object_class_install_property (gobject_class, PROP_FRAGMENT_MODE,
       g_param_spec_enum ("fragment-mode", "Fragment Mode",
           "How to to write fragments to the file.  Only used when "
-          "\'fragment-duration\' is greather than 0",
+          "\'fragment-duration\' is greater than 0",
           GST_TYPE_QT_MUX_FRAGMENT_MODE, DEFAULT_FRAGMENT_MODE,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
@@ -872,6 +872,7 @@ gst_qt_mux_class_init (GstQTMuxClass * klass)
   gstagg_class->start = gst_qt_mux_start;
   gstagg_class->stop = gst_qt_mux_stop;
   gstagg_class->create_new_pad = gst_qt_mux_create_new_pad;
+  gstagg_class->negotiate = NULL;
 
   gst_type_mark_as_plugin_api (GST_TYPE_QT_MUX_PAD, 0);
   gst_type_mark_as_plugin_api (GST_TYPE_QT_MUX_DTS_METHOD, 0);
@@ -881,6 +882,8 @@ gst_qt_mux_class_init (GstQTMuxClass * klass)
 static void
 gst_qt_mux_pad_reset (GstQTMuxPad * qtpad)
 {
+  guint i;
+
   qtpad->fourcc = 0;
   qtpad->is_out_of_order = FALSE;
   qtpad->sample_size = 0;
@@ -918,7 +921,13 @@ gst_qt_mux_pad_reset (GstQTMuxPad * qtpad)
     atom_traf_free (qtpad->traf);
     qtpad->traf = NULL;
   }
+  for (i = 0; i < atom_array_get_len (&qtpad->fragment_buffers); i++) {
+    GstBuffer *buf = atom_array_index (&qtpad->fragment_buffers, i);
+    if (buf != NULL)
+      gst_buffer_unref (atom_array_index (&qtpad->fragment_buffers, i));
+  }
   atom_array_clear (&qtpad->fragment_buffers);
+
   if (qtpad->samples)
     g_array_unref (qtpad->samples);
   qtpad->samples = NULL;
@@ -2943,7 +2952,8 @@ prefill_raw_audio_prepare_buf_func (GstQTMuxPad * qtpad, GstBuffer * buf,
       qtpad->sample_size : gst_adapter_available (qtpad->raw_audio_adapter));
   GST_BUFFER_PTS (buf) = input_timestamp;
   GST_BUFFER_DTS (buf) = GST_CLOCK_TIME_NONE;
-  GST_BUFFER_DURATION (buf) = GST_CLOCK_TIME_NONE;
+  GST_BUFFER_DURATION (buf) = gst_util_uint64_scale (nsamples, GST_SECOND,
+      atom_trak_get_timescale (qtpad->trak));
 
   qtpad->raw_audio_adapter_offset += nsamples;
 
@@ -4294,11 +4304,10 @@ gst_qt_mux_stop_file (GstQTMux * qtmux)
 
         if (qpad->trak->edts
             && g_slist_length (qpad->trak->edts->elst.entries) > 1) {
+          GST_OBJECT_UNLOCK (qtmux);
           GST_ELEMENT_ERROR (qtmux, STREAM, MUX, (NULL),
               ("Can't support gaps in prefill mode"));
 
-          GST_OBJECT_UNLOCK (qtmux);
-
           return GST_FLOW_ERROR;
         }
       }
@@ -5665,7 +5674,10 @@ not_negotiated:
   }
 sample_error:
   {
-    GST_ELEMENT_ERROR (qtmux, STREAM, MUX, (NULL), ("Failed to push sample."));
+    /* Only post an error message for actual errors that are not flushing */
+    if (pad->flow_status < GST_FLOW_OK && pad->flow_status != GST_FLOW_FLUSHING)
+      GST_ELEMENT_ERROR (qtmux, STREAM, MUX, (NULL),
+          ("Failed to push sample."));
     return pad->flow_status;
   }
 }
@@ -5751,6 +5763,7 @@ find_best_pad (GstQTMux * qtmux)
        * to be written at */
       block_idx = current_block_idx = prefill_get_block_index (qtmux, qtpad);
       if (!qtpad->samples || block_idx >= qtpad->samples->len) {
+        GST_OBJECT_UNLOCK (qtmux);
         GST_ELEMENT_ERROR (qtmux, RESOURCE, SETTINGS,
             ("Failed to create samples in prefill mode"), (NULL));
         return NULL;
@@ -6733,7 +6746,66 @@ gst_qt_mux_video_sink_set_caps (GstQTMuxPad * qtpad, GstCaps * caps)
   } else if (strcmp (mimetype, "video/x-vp8") == 0) {
     entry.fourcc = FOURCC_vp08;
   } else if (strcmp (mimetype, "video/x-vp9") == 0) {
+    const char *profile_str, *chroma_format_str, *colorimetry_str;
+    guint bitdepth_luma, bitdepth_chroma;
+    guint8 profile = -1, chroma_format = -1;
+    gboolean video_full_range;
+    GstVideoColorimetry cinfo = { 0, };
+
     entry.fourcc = FOURCC_vp09;
+
+    profile_str = gst_structure_get_string (structure, "profile");
+    if (g_strcmp0 (profile_str, "0") == 0) {
+      profile = 0;
+    } else if (g_strcmp0 (profile_str, "1") == 0) {
+      profile = 1;
+    } else if (g_strcmp0 (profile_str, "2") == 0) {
+      profile = 2;
+    } else if (g_strcmp0 (profile_str, "3") == 0) {
+      profile = 3;
+    }
+
+    colorimetry_str = gst_structure_get_string (structure, "colorimetry");
+    gst_video_colorimetry_from_string (&cinfo, colorimetry_str);
+    video_full_range = cinfo.range == GST_VIDEO_COLOR_RANGE_0_255;
+
+    chroma_format_str = gst_structure_get_string (structure, "chroma-format");
+    if (g_strcmp0 (chroma_format_str, "4:2:0") == 0) {
+      const char *chroma_site_str;
+      GstVideoChromaSite chroma_site;
+
+      chroma_site_str = gst_structure_get_string (structure, "chroma-site");
+      chroma_site = gst_video_chroma_site_from_string (chroma_site_str);
+      if (chroma_site == GST_VIDEO_CHROMA_SITE_V_COSITED) {
+        chroma_format = 0;
+      } else if (chroma_site == GST_VIDEO_CHROMA_SITE_COSITED) {
+        chroma_format = 1;
+      } else {
+        chroma_format = 1;
+      }
+    } else if (g_strcmp0 (chroma_format_str, "4:2:2") == 0) {
+      chroma_format = 2;
+    } else if (g_strcmp0 (chroma_format_str, "4:4:4") == 0) {
+      chroma_format = 3;
+    }
+
+    gst_structure_get (structure, "bit-depth-luma", G_TYPE_UINT,
+        &bitdepth_luma, "bit-depth-chroma", G_TYPE_UINT, &bitdepth_chroma,
+        NULL);
+
+    if (profile == 0xFF || chroma_format == 0xFF
+        || bitdepth_luma != bitdepth_chroma || bitdepth_luma == 0) {
+      GST_WARNING_OBJECT (qtmux, "cannot construct vpcC atom from "
+          "incomplete caps");
+    } else {
+      ext_atom = build_vpcC_extension (profile, /* XXX: level */ 10,
+          bitdepth_luma, chroma_format, video_full_range,
+          gst_video_color_primaries_to_iso (cinfo.primaries),
+          gst_video_transfer_function_to_iso (cinfo.transfer),
+          gst_video_color_matrix_to_iso (cinfo.matrix));
+      if (ext_atom)
+        ext_atom_list = g_list_append (ext_atom_list, ext_atom);
+    }
   } else if (strcmp (mimetype, "video/x-dirac") == 0) {
     entry.fourcc = FOURCC_drac;
   } else if (strcmp (mimetype, "video/x-qt-part") == 0) {