mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
avimux: put the codec_data blob into the actual data for MPEG4 video,
to match other implementations in the wild.
This commit is contained in:
parent
efc54acc15
commit
c3b0509beb
2 changed files with 42 additions and 9 deletions
|
@ -338,6 +338,11 @@ gst_avi_mux_pad_reset (GstAviPad * avipad, gboolean free)
|
||||||
vidpad->vids_codec_data = NULL;
|
vidpad->vids_codec_data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vidpad->prepend_buffer) {
|
||||||
|
gst_buffer_unref (vidpad->prepend_buffer);
|
||||||
|
vidpad->prepend_buffer = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
memset (&(vidpad->vids), 0, sizeof (gst_riff_strf_vids));
|
memset (&(vidpad->vids), 0, sizeof (gst_riff_strf_vids));
|
||||||
memset (&(vidpad->vprp), 0, sizeof (gst_riff_vprp));
|
memset (&(vidpad->vprp), 0, sizeof (gst_riff_vprp));
|
||||||
} else {
|
} else {
|
||||||
|
@ -433,6 +438,7 @@ gst_avi_mux_vidsink_set_caps (GstPad * pad, GstCaps * vscaps)
|
||||||
const GValue *codec_data;
|
const GValue *codec_data;
|
||||||
gint width, height;
|
gint width, height;
|
||||||
gint par_n, par_d;
|
gint par_n, par_d;
|
||||||
|
gboolean codec_data_in_headers = TRUE;
|
||||||
|
|
||||||
avimux = GST_AVI_MUX (gst_pad_get_parent (pad));
|
avimux = GST_AVI_MUX (gst_pad_get_parent (pad));
|
||||||
|
|
||||||
|
@ -498,15 +504,6 @@ gst_avi_mux_vidsink_set_caps (GstPad * pad, GstCaps * vscaps)
|
||||||
avipad->vprp.field_info[0].valid_bm_width = width;
|
avipad->vprp.field_info[0].valid_bm_width = width;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* codec initialization data, if any */
|
|
||||||
codec_data = gst_structure_get_value (structure, "codec_data");
|
|
||||||
if (codec_data) {
|
|
||||||
avipad->vids_codec_data = gst_value_get_buffer (codec_data);
|
|
||||||
gst_buffer_ref (avipad->vids_codec_data);
|
|
||||||
/* keep global track of size */
|
|
||||||
avimux->codec_data_size += GST_BUFFER_SIZE (avipad->vids_codec_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!strcmp (mimetype, "video/x-raw-yuv")) {
|
if (!strcmp (mimetype, "video/x-raw-yuv")) {
|
||||||
guint32 format;
|
guint32 format;
|
||||||
|
|
||||||
|
@ -586,6 +583,11 @@ gst_avi_mux_vidsink_set_caps (GstPad * pad, GstCaps * vscaps)
|
||||||
case 4:
|
case 4:
|
||||||
/* mplayer/ffmpeg might not work with DIVX, but with FMP4 */
|
/* mplayer/ffmpeg might not work with DIVX, but with FMP4 */
|
||||||
avipad->vids.compression = GST_MAKE_FOURCC ('D', 'I', 'V', 'X');
|
avipad->vids.compression = GST_MAKE_FOURCC ('D', 'I', 'V', 'X');
|
||||||
|
|
||||||
|
/* DIVX/XVID in AVI store the codec_data chunk as part of the
|
||||||
|
first data buffer. So for this case, we prepend the codec_data
|
||||||
|
blob (if any) to that first buffer */
|
||||||
|
codec_data_in_headers = FALSE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
GST_INFO ("unhandled mpegversion : %d, fall back to fourcc=MPEG",
|
GST_INFO ("unhandled mpegversion : %d, fall back to fourcc=MPEG",
|
||||||
|
@ -620,6 +622,20 @@ gst_avi_mux_vidsink_set_caps (GstPad * pad, GstCaps * vscaps)
|
||||||
goto refuse_caps;
|
goto refuse_caps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* codec initialization data, if any */
|
||||||
|
codec_data = gst_structure_get_value (structure, "codec_data");
|
||||||
|
if (codec_data) {
|
||||||
|
if (codec_data_in_headers) {
|
||||||
|
avipad->vids_codec_data = gst_value_get_buffer (codec_data);
|
||||||
|
gst_buffer_ref (avipad->vids_codec_data);
|
||||||
|
/* keep global track of size */
|
||||||
|
avimux->codec_data_size += GST_BUFFER_SIZE (avipad->vids_codec_data);
|
||||||
|
} else {
|
||||||
|
avipad->prepend_buffer =
|
||||||
|
gst_buffer_ref (gst_value_get_buffer (codec_data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
avipad->parent.hdr.fcc_handler = avipad->vids.compression;
|
avipad->parent.hdr.fcc_handler = avipad->vids.compression;
|
||||||
avipad->vids.image_size = avipad->vids.height * avipad->vids.width;
|
avipad->vids.image_size = avipad->vids.height * avipad->vids.width;
|
||||||
/* hm, maybe why avi only handles one stream well ... */
|
/* hm, maybe why avi only handles one stream well ... */
|
||||||
|
@ -1940,6 +1956,21 @@ gst_avi_mux_do_buffer (GstAviMux * avimux, GstAviPad * avipad)
|
||||||
|
|
||||||
data = gst_collect_pads_pop (avimux->collect, avipad->collect);
|
data = gst_collect_pads_pop (avimux->collect, avipad->collect);
|
||||||
|
|
||||||
|
/* Prepend a special buffer to the first one for some formats */
|
||||||
|
if (avipad->is_video) {
|
||||||
|
GstAviVideoPad *vidpad = (GstAviVideoPad *) avipad;
|
||||||
|
|
||||||
|
if (vidpad->prepend_buffer) {
|
||||||
|
GstBuffer *newdata = gst_buffer_merge (vidpad->prepend_buffer, data);
|
||||||
|
gst_buffer_copy_metadata (newdata, data, GST_BUFFER_COPY_TIMESTAMPS);
|
||||||
|
gst_buffer_unref (data);
|
||||||
|
gst_buffer_unref (vidpad->prepend_buffer);
|
||||||
|
|
||||||
|
data = newdata;
|
||||||
|
vidpad->prepend_buffer = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (avimux->restart) {
|
if (avimux->restart) {
|
||||||
if ((res = gst_avi_mux_restart_file (avimux)) != GST_FLOW_OK)
|
if ((res = gst_avi_mux_restart_file (avimux)) != GST_FLOW_OK)
|
||||||
return res;
|
return res;
|
||||||
|
|
|
@ -105,6 +105,8 @@ typedef struct _GstAviVideoPad {
|
||||||
/* ODML video properties */
|
/* ODML video properties */
|
||||||
gst_riff_vprp vprp;
|
gst_riff_vprp vprp;
|
||||||
|
|
||||||
|
GstBuffer *prepend_buffer;
|
||||||
|
|
||||||
} GstAviVideoPad;
|
} GstAviVideoPad;
|
||||||
|
|
||||||
typedef struct _GstAviAudioPad {
|
typedef struct _GstAviAudioPad {
|
||||||
|
|
Loading…
Reference in a new issue