qtmux: Use size of first closed caption buffer in prefill mode

It must be accurate for all samples to work in Final Cut properly, so
the best we can do is to assume that all samples are the same as the
first. Bigger samples are truncated, smaller samples are padded.
This commit is contained in:
Sebastian Dröge 2018-09-05 21:10:51 +03:00
parent f554369ed5
commit 2bed2687bb
2 changed files with 34 additions and 11 deletions

View file

@ -681,6 +681,7 @@ gst_qt_mux_pad_reset (GstQTPad * qtpad)
qtpad->total_duration = 0; qtpad->total_duration = 0;
qtpad->total_bytes = 0; qtpad->total_bytes = 0;
qtpad->sparse = FALSE; qtpad->sparse = FALSE;
qtpad->first_cc_sample_size = 0;
gst_buffer_replace (&qtpad->last_buf, NULL); gst_buffer_replace (&qtpad->last_buf, NULL);
@ -1004,21 +1005,35 @@ gst_qt_mux_prepare_caption_buffer (GstQTPad * qtpad, GstBuffer * buf,
break; break;
case FOURCC_c708: case FOURCC_c708:
{ {
gsize actual_size;
/* Take the whole CDP */ /* Take the whole CDP */
if (in_prefill && size > 256) { if (in_prefill) {
GST_ERROR_OBJECT (qtmux, "Input C708 CDP too big for prefill mode !"); if (size > qtpad->first_cc_sample_size) {
break; GST_ELEMENT_WARNING (qtmux, RESOURCE, WRITE,
("Truncating too big CEA708 sample (%" G_GSIZE_FORMAT " > %u)",
size, qtpad->first_cc_sample_size), (NULL));
} else if (size < qtpad->first_cc_sample_size) {
GST_ELEMENT_WARNING (qtmux, RESOURCE, WRITE,
("Padding too small CEA708 sample (%" G_GSIZE_FORMAT " < %u)",
size, qtpad->first_cc_sample_size), (NULL));
} }
newbuf = gst_buffer_new_and_alloc (in_prefill ? 256 + 8 : size + 8);
actual_size = MIN (qtpad->first_cc_sample_size, size);
} else {
actual_size = size;
}
newbuf = gst_buffer_new_and_alloc (actual_size + 8);
/* Let's copy over all metadata and not the memory */ /* Let's copy over all metadata and not the memory */
gst_buffer_copy_into (newbuf, buf, GST_BUFFER_COPY_METADATA, 0, size); gst_buffer_copy_into (newbuf, buf, GST_BUFFER_COPY_METADATA, 0, -1);
gst_buffer_map (newbuf, &map, GST_MAP_WRITE); gst_buffer_map (newbuf, &map, GST_MAP_WRITE);
GST_WRITE_UINT32_BE (map.data, size + 8); GST_WRITE_UINT32_BE (map.data, actual_size + 8);
GST_WRITE_UINT32_LE (map.data + 4, FOURCC_ccdp); GST_WRITE_UINT32_LE (map.data + 4, FOURCC_ccdp);
memcpy (map.data + 8, inmap.data, inmap.size); memcpy (map.data + 8, inmap.data, actual_size);
gst_buffer_unmap (newbuf, &map); gst_buffer_unmap (newbuf, &map);
break; break;
@ -2508,10 +2523,17 @@ prefill_get_sample_size (GstQTMux * qtmux, GstQTPad * qpad)
case FOURCC_c608: case FOURCC_c608:
/* We always write both cdat and cdt2 atom in prefill mode */ /* We always write both cdat and cdt2 atom in prefill mode */
return 20; return 20;
case FOURCC_c708: case FOURCC_c708:{
/* We're cheating a bit by always allocating 256 bytes plus 8 bytes for the atom header if (qpad->first_cc_sample_size == 0) {
* even if we use less */ GstBuffer *buf =
return 256 + 8; gst_collect_pads_peek (qtmux->collect, (GstCollectData *) qpad);
g_assert (buf != NULL);
qpad->first_cc_sample_size = gst_buffer_get_size (buf);
g_assert (qpad->first_cc_sample_size != 0);
gst_buffer_unref (buf);
}
return qpad->first_cc_sample_size + 8;
}
case FOURCC_sowt: case FOURCC_sowt:
case FOURCC_twos:{ case FOURCC_twos:{
guint64 block_idx; guint64 block_idx;

View file

@ -154,6 +154,7 @@ struct _GstQTPad
/* for keeping track in pre-fill mode */ /* for keeping track in pre-fill mode */
GArray *samples; GArray *samples;
guint first_cc_sample_size;
/* current sample */ /* current sample */
GstAdapter *raw_audio_adapter; GstAdapter *raw_audio_adapter;
guint64 raw_audio_adapter_offset; guint64 raw_audio_adapter_offset;