summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gst/isomp4/gstqtmux.c121
1 files changed, 85 insertions, 36 deletions
diff --git a/gst/isomp4/gstqtmux.c b/gst/isomp4/gstqtmux.c
index 81eee0d9b..bab212654 100644
--- a/gst/isomp4/gstqtmux.c
+++ b/gst/isomp4/gstqtmux.c
@@ -919,10 +919,13 @@ gst_qt_mux_prepare_caption_buffer (GstQTPad * qtpad, GstBuffer * buf,
GstBuffer *newbuf = NULL;
GstMapInfo map, inmap;
gsize size;
+ gboolean in_prefill;
if (buf == NULL)
return NULL;
+ in_prefill = (qtmux->mux_mode == GST_QT_MUX_MODE_ROBUST_RECORDING_PREFILL);
+
size = gst_buffer_get_size (buf);
gst_buffer_map (buf, &inmap, GST_MAP_READ);
@@ -951,23 +954,39 @@ gst_qt_mux_prepare_caption_buffer (GstQTPad * qtpad, GstBuffer * buf,
break;
}
- newbuf = gst_buffer_new_and_alloc (total_size);
+ newbuf = gst_buffer_new_and_alloc (in_prefill ? 20 : total_size);
/* Let's copy over all metadata and not the memory */
gst_buffer_copy_into (newbuf, buf, GST_BUFFER_COPY_METADATA, 0, size);
gst_buffer_map (newbuf, &map, GST_MAP_WRITE);
- if (cdat_size) {
- GST_WRITE_UINT32_BE (map.data, cdat_size + 8);
+ if (cdat_size || in_prefill) {
+ GST_WRITE_UINT32_BE (map.data, in_prefill ? 10 : cdat_size + 8);
GST_WRITE_UINT32_LE (map.data + 4, FOURCC_cdat);
- memcpy (map.data + 8, cdat, cdat_size);
- write_offs = cdat_size + 8;
- g_free (cdat);
+ if (cdat_size)
+ memcpy (map.data + 8, cdat, in_prefill ? 2 : cdat_size);
+ else {
+ /* Write 'empty' CC */
+ map.data[8] = 0x80;
+ map.data[9] = 0x80;
+ }
+ write_offs = in_prefill ? 10 : cdat_size + 8;
+ if (cdat_size)
+ g_free (cdat);
}
- if (cdt2_size) {
- GST_WRITE_UINT32_BE (map.data + write_offs, cdt2_size + 8);
+
+ if (cdt2_size || in_prefill) {
+ GST_WRITE_UINT32_BE (map.data + write_offs,
+ in_prefill ? 10 : cdt2_size + 8);
GST_WRITE_UINT32_LE (map.data + write_offs + 4, FOURCC_cdt2);
- memcpy (map.data + write_offs + 8, cdt2, cdt2_size);
- g_free (cdt2);
+ if (cdt2_size)
+ memcpy (map.data + write_offs + 8, cdt2, in_prefill ? 2 : cdt2_size);
+ else {
+ /* Write 'empty' CC */
+ map.data[write_offs + 8] = 0x80;
+ map.data[write_offs + 9] = 0x80;
+ }
+ if (cdt2_size)
+ g_free (cdt2);
}
gst_buffer_unmap (newbuf, &map);
break;
@@ -976,7 +995,11 @@ gst_qt_mux_prepare_caption_buffer (GstQTPad * qtpad, GstBuffer * buf,
case FOURCC_c708:
{
/* Take the whole CDP */
- newbuf = gst_buffer_new_and_alloc (size + 8);
+ if (in_prefill && size > 92) {
+ GST_ERROR_OBJECT (qtmux, "Input C708 CDP too big for prefill mode !");
+ break;
+ }
+ newbuf = gst_buffer_new_and_alloc (in_prefill ? 100 : size + 8);
/* Let's copy over all metadata and not the memory */
gst_buffer_copy_into (newbuf, buf, GST_BUFFER_COPY_METADATA, 0, size);
@@ -2402,6 +2425,8 @@ prefill_get_block_index (GstQTMux * qtmux, GstQTPad * qpad)
case FOURCC_apco:
case FOURCC_ap4h:
case FOURCC_ap4x:
+ case FOURCC_c608:
+ case FOURCC_c708:
return qpad->sample_offset;
case FOURCC_sowt:
case FOURCC_twos:
@@ -2470,6 +2495,12 @@ prefill_get_sample_size (GstQTMux * qtmux, GstQTPad * qpad)
return 900000;
}
break;
+ case FOURCC_c608:
+ /* We always write both cdat and cdt2 atom in prefill mode */
+ return 20;
+ case FOURCC_c708:
+ /* We're cheating a bit by always allocating 100bytes even if we use less */
+ return 100;
case FOURCC_sowt:
case FOURCC_twos:{
guint64 block_idx;
@@ -2504,6 +2535,8 @@ prefill_get_next_timestamp (GstQTMux * qtmux, GstQTPad * qpad)
case FOURCC_apco:
case FOURCC_ap4h:
case FOURCC_ap4x:
+ case FOURCC_c608:
+ case FOURCC_c708:
return gst_util_uint64_scale (qpad->sample_offset + 1,
qpad->expected_sample_duration_d * GST_SECOND,
qpad->expected_sample_duration_n);
@@ -2600,6 +2633,33 @@ prefill_raw_audio_prepare_buf_func (GstQTPad * qtpad, GstBuffer * buf,
return buf;
}
+static void
+find_video_sample_duration (GstQTMux * qtmux, guint * dur_n, guint * dur_d)
+{
+ GSList *walk;
+
+ /* Find the (first) video track and assume that we have to output
+ * in that size */
+ for (walk = qtmux->collect->data; walk; walk = g_slist_next (walk)) {
+ GstCollectData *cdata = (GstCollectData *) walk->data;
+ GstQTPad *tmp_qpad = (GstQTPad *) cdata;
+
+ if (tmp_qpad->trak->is_video) {
+ *dur_n = tmp_qpad->expected_sample_duration_n;
+ *dur_d = tmp_qpad->expected_sample_duration_d;
+ break;
+ }
+ }
+
+ if (walk == NULL) {
+ GST_INFO_OBJECT (qtmux,
+ "Found no video framerate, using 40ms audio buffers");
+ *dur_n = 25;
+ *dur_d = 1;
+ }
+}
+
+/* Called when all pads are prerolled to adjust and */
static gboolean
prefill_update_sample_size (GstQTMux * qtmux, GstQTPad * qpad)
{
@@ -2609,37 +2669,26 @@ prefill_update_sample_size (GstQTMux * qtmux, GstQTPad * qpad)
case FOURCC_apcs:
case FOURCC_apco:
case FOURCC_ap4h:
- case FOURCC_ap4x:{
+ case FOURCC_ap4x:
+ {
+ guint sample_size = prefill_get_sample_size (qtmux, qpad);
+ atom_trak_set_constant_size_samples (qpad->trak, sample_size);
+ return TRUE;
+ }
+ case FOURCC_c608:
+ case FOURCC_c708:
+ {
guint sample_size = prefill_get_sample_size (qtmux, qpad);
+ /* We need a "valid" duration */
+ find_video_sample_duration (qtmux, &qpad->expected_sample_duration_n,
+ &qpad->expected_sample_duration_d);
atom_trak_set_constant_size_samples (qpad->trak, sample_size);
return TRUE;
}
case FOURCC_sowt:
case FOURCC_twos:{
- GSList *walk;
-
- /* Find the (first) video track and assume that we have to output
- * in that size */
- for (walk = qtmux->collect->data; walk; walk = g_slist_next (walk)) {
- GstCollectData *cdata = (GstCollectData *) walk->data;
- GstQTPad *tmp_qpad = (GstQTPad *) cdata;
-
- if (tmp_qpad->trak->is_video) {
- qpad->expected_sample_duration_n =
- tmp_qpad->expected_sample_duration_n;
- qpad->expected_sample_duration_d =
- tmp_qpad->expected_sample_duration_d;
- break;
- }
- }
-
- if (walk == NULL) {
- GST_INFO_OBJECT (qpad->collect.pad,
- "Found no video framerate, using 40ms audio buffers");
- qpad->expected_sample_duration_n = 25;
- qpad->expected_sample_duration_d = 1;
- }
-
+ find_video_sample_duration (qtmux, &qpad->expected_sample_duration_n,
+ &qpad->expected_sample_duration_d);
/* Set a prepare_buf_func that ensures this */
qpad->prepare_buf_func = prefill_raw_audio_prepare_buf_func;
qpad->raw_audio_adapter = gst_adapter_new ();