*
* 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.
*
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));
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);
static void
gst_qt_mux_pad_reset (GstQTMuxPad * qtpad)
{
+ guint i;
+
qtpad->fourcc = 0;
qtpad->is_out_of_order = FALSE;
qtpad->sample_size = 0;
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;
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;
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;
}
}
}
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;
}
}
* 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;
} 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) {