mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-27 12:11:13 +00:00
qtmux: support muxing multiple codec_data for h264/h265
Each codec_data is put into its own SampleTableEntry inside the stsd. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/787>
This commit is contained in:
parent
d664f400aa
commit
9d74a60810
3 changed files with 44 additions and 19 deletions
|
@ -2334,11 +2334,15 @@ atom_stsc_copy_data (AtomSTSC * stsc, guint8 ** buffer, guint64 * size,
|
|||
|
||||
/* Last two entries might be the same size here as we only merge once the
|
||||
* next chunk is started */
|
||||
if ((len = atom_array_get_len (&stsc->entries)) > 1 &&
|
||||
((atom_array_index (&stsc->entries, len - 1)).samples_per_chunk ==
|
||||
(atom_array_index (&stsc->entries, len - 2)).samples_per_chunk)) {
|
||||
stsc->entries.len--;
|
||||
last_entries_merged = TRUE;
|
||||
if ((len = atom_array_get_len (&stsc->entries)) > 1) {
|
||||
STSCEntry *prev_entry = &atom_array_index (&stsc->entries, len - 2);
|
||||
STSCEntry *current_entry = &atom_array_index (&stsc->entries, len - 1);
|
||||
if (prev_entry->samples_per_chunk == current_entry->samples_per_chunk &&
|
||||
prev_entry->sample_description_index ==
|
||||
current_entry->sample_description_index) {
|
||||
stsc->entries.len--;
|
||||
last_entries_merged = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
prop_copy_uint32 (atom_array_get_len (&stsc->entries), buffer, size, offset);
|
||||
|
@ -3076,7 +3080,8 @@ atom_wave_copy_data (AtomWAVE * wave, guint8 ** buffer,
|
|||
/* add samples to tables */
|
||||
|
||||
void
|
||||
atom_stsc_add_new_entry (AtomSTSC * stsc, guint32 first_chunk, guint32 nsamples)
|
||||
atom_stsc_add_new_entry (AtomSTSC * stsc, guint32 first_chunk, guint32 nsamples,
|
||||
guint32 sample_description_index)
|
||||
{
|
||||
gint len;
|
||||
|
||||
|
@ -3089,13 +3094,13 @@ atom_stsc_add_new_entry (AtomSTSC * stsc, guint32 first_chunk, guint32 nsamples)
|
|||
nentry = &atom_array_index (&stsc->entries, len - 1);
|
||||
nentry->first_chunk = first_chunk;
|
||||
nentry->samples_per_chunk = nsamples;
|
||||
nentry->sample_description_index = 1;
|
||||
nentry->sample_description_index = sample_description_index;
|
||||
} else {
|
||||
STSCEntry nentry;
|
||||
|
||||
nentry.first_chunk = first_chunk;
|
||||
nentry.samples_per_chunk = nsamples;
|
||||
nentry.sample_description_index = 1;
|
||||
nentry.sample_description_index = sample_description_index;
|
||||
atom_array_append (&stsc->entries, nentry, 128);
|
||||
}
|
||||
}
|
||||
|
@ -3231,7 +3236,8 @@ atom_stbl_add_samples (AtomSTBL * stbl, guint32 nsamples, guint32 delta,
|
|||
atom_stsz_add_entry (&stbl->stsz, nsamples, size);
|
||||
if (atom_stco64_add_entry (&stbl->stco64, chunk_offset)) {
|
||||
atom_stsc_add_new_entry (&stbl->stsc,
|
||||
atom_stco64_get_entry_count (&stbl->stco64), nsamples);
|
||||
atom_stco64_get_entry_count (&stbl->stco64), nsamples,
|
||||
stbl->stsd.n_entries);
|
||||
} else {
|
||||
atom_stsc_update_entry (&stbl->stsc,
|
||||
atom_stco64_get_entry_count (&stbl->stco64), nsamples);
|
||||
|
@ -4001,7 +4007,7 @@ atom_trak_add_video_entry (AtomTRAK * trak, AtomsContext * context,
|
|||
mp4v->temporal_quality = 512;
|
||||
}
|
||||
|
||||
stsd->entries = g_list_prepend (stsd->entries, mp4v);
|
||||
stsd->entries = g_list_append (stsd->entries, mp4v);
|
||||
stsd->n_entries++;
|
||||
return mp4v;
|
||||
}
|
||||
|
@ -4374,14 +4380,14 @@ atom_trak_set_video_type (AtomTRAK * trak, AtomsContext * context,
|
|||
dheight = entry->height;
|
||||
}
|
||||
|
||||
atom_trak_set_video_commons (trak, context, scale, dwidth, dheight);
|
||||
atom_stsd_remove_entries (&trak->mdia.minf.stbl.stsd);
|
||||
if (trak->mdia.minf.stbl.stsd.n_entries < 1) {
|
||||
atom_trak_set_video_commons (trak, context, scale, dwidth, dheight);
|
||||
trak->is_video = TRUE;
|
||||
trak->is_h264 = (entry->fourcc == FOURCC_avc1
|
||||
|| entry->fourcc == FOURCC_avc3);
|
||||
}
|
||||
ste = atom_trak_add_video_entry (trak, context, entry->fourcc);
|
||||
|
||||
trak->is_video = TRUE;
|
||||
trak->is_h264 = (entry->fourcc == FOURCC_avc1
|
||||
|| entry->fourcc == FOURCC_avc3);
|
||||
|
||||
ste->version = entry->version;
|
||||
ste->width = entry->width;
|
||||
ste->height = entry->height;
|
||||
|
|
|
@ -952,7 +952,7 @@ void atom_stbl_add_samples (AtomSTBL * stbl, guint32 nsamples,
|
|||
guint64 chunk_offset, gboolean sync,
|
||||
gint64 pts_offset);
|
||||
void atom_stsc_add_new_entry (AtomSTSC * stsc,
|
||||
guint32 first_chunk, guint32 nsamples);
|
||||
guint32 first_chunk, guint32 nsamples, guint32 sample_description_index);
|
||||
|
||||
AtomMOOV* atom_moov_new (AtomsContext *context);
|
||||
void atom_moov_free (AtomMOOV *moov);
|
||||
|
|
|
@ -4004,7 +4004,7 @@ gst_qt_mux_stop_file (GstQTMux * qtmux)
|
|||
if (qpad->sample_offset - nsamples > 0) {
|
||||
stbl->stsc.entries.len = i;
|
||||
atom_stsc_add_new_entry (&stbl->stsc, chunk_index,
|
||||
qpad->sample_offset - nsamples);
|
||||
qpad->sample_offset - nsamples, stbl->stsd.n_entries);
|
||||
} else {
|
||||
stbl->stsc.entries.len = i;
|
||||
stbl->stco64.entries.len--;
|
||||
|
@ -4013,7 +4013,7 @@ gst_qt_mux_stop_file (GstQTMux * qtmux)
|
|||
/* Everything in a single chunk */
|
||||
stbl->stsc.entries.len = 0;
|
||||
atom_stsc_add_new_entry (&stbl->stsc, chunk_index,
|
||||
qpad->sample_offset);
|
||||
qpad->sample_offset, stbl->stsd.n_entries);
|
||||
}
|
||||
} else {
|
||||
stbl->stco64.entries.len = 0;
|
||||
|
@ -5718,6 +5718,22 @@ check_field (GQuark field_id, const GValue * value, gpointer user_data)
|
|||
{
|
||||
GstStructure *structure = (GstStructure *) user_data;
|
||||
const GValue *other = gst_structure_id_get_value (structure, field_id);
|
||||
const gchar *name = gst_structure_get_name (structure);
|
||||
|
||||
if (g_str_has_prefix (name, "video/")) {
|
||||
/* ignore framerate with video caps */
|
||||
if (g_strcmp0 (g_quark_to_string (field_id), "framerate") == 0)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (g_strcmp0 (name, "video/x-h264") == 0 ||
|
||||
g_strcmp0 (name, "video/x-h265") == 0) {
|
||||
/* we support muxing multiple codec_data structures */
|
||||
if (g_strcmp0 (g_quark_to_string (field_id), "codec_data") == 0) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (other == NULL)
|
||||
return FALSE;
|
||||
return gst_value_compare (value, other) == GST_VALUE_EQUAL;
|
||||
|
@ -5730,6 +5746,9 @@ gst_qtmux_caps_is_subset_full (GstQTMux * qtmux, GstCaps * subset,
|
|||
GstStructure *sub_s = gst_caps_get_structure (subset, 0);
|
||||
GstStructure *sup_s = gst_caps_get_structure (superset, 0);
|
||||
|
||||
if (!gst_structure_has_name (sup_s, gst_structure_get_name (sub_s)))
|
||||
return FALSE;
|
||||
|
||||
return gst_structure_foreach (sub_s, check_field, sup_s);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue