mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-02 04:22:27 +00:00
flvmux: Insert AVC end of sequence
This FLV specific mark is needed to prevent Flow Player (most likely all Flash base player) from going into buffering state when near EOS. https://bugzilla.gnome.org/show_bug.cgi?id=751320
This commit is contained in:
parent
9a1ed36b7a
commit
bbea34bb6e
1 changed files with 58 additions and 16 deletions
|
@ -1005,8 +1005,8 @@ gst_flv_mux_buffer_to_tag_internal (GstFlvMux * mux, GstBuffer * buffer,
|
|||
GstMapInfo map;
|
||||
guint size;
|
||||
guint32 pts, dts, cts;
|
||||
guint8 *data, *bdata;
|
||||
gsize bsize;
|
||||
guint8 *data, *bdata = NULL;
|
||||
gsize bsize = 0;
|
||||
|
||||
if (!GST_CLOCK_STIME_IS_VALID (cpad->dts)) {
|
||||
pts = dts = cpad->last_timestamp / GST_MSECOND;
|
||||
|
@ -1029,9 +1029,11 @@ gst_flv_mux_buffer_to_tag_internal (GstFlvMux * mux, GstBuffer * buffer,
|
|||
|
||||
GST_LOG_OBJECT (mux, "got pts %i dts %i cts %i\n", pts, dts, cts);
|
||||
|
||||
gst_buffer_map (buffer, &map, GST_MAP_READ);
|
||||
bdata = map.data;
|
||||
bsize = map.size;
|
||||
if (buffer != NULL) {
|
||||
gst_buffer_map (buffer, &map, GST_MAP_READ);
|
||||
bdata = map.data;
|
||||
bsize = map.size;
|
||||
}
|
||||
|
||||
size = 11;
|
||||
if (cpad->video) {
|
||||
|
@ -1064,7 +1066,7 @@ gst_flv_mux_buffer_to_tag_internal (GstFlvMux * mux, GstBuffer * buffer,
|
|||
data[8] = data[9] = data[10] = 0;
|
||||
|
||||
if (cpad->video) {
|
||||
if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT))
|
||||
if (buffer && GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT))
|
||||
data[11] |= 2 << 4;
|
||||
else
|
||||
data[11] |= 1 << 4;
|
||||
|
@ -1075,6 +1077,10 @@ gst_flv_mux_buffer_to_tag_internal (GstFlvMux * mux, GstBuffer * buffer,
|
|||
if (is_codec_data) {
|
||||
data[12] = 0;
|
||||
GST_WRITE_UINT24_BE (data + 13, 0);
|
||||
} else if (bsize == 0) {
|
||||
/* AVC end of sequence */
|
||||
data[12] = 2;
|
||||
GST_WRITE_UINT24_BE (data + 13, 0);
|
||||
} else {
|
||||
/* ACV NALU */
|
||||
data[12] = 1;
|
||||
|
@ -1099,24 +1105,29 @@ gst_flv_mux_buffer_to_tag_internal (GstFlvMux * mux, GstBuffer * buffer,
|
|||
}
|
||||
}
|
||||
|
||||
gst_buffer_unmap (buffer, &map);
|
||||
if (buffer)
|
||||
gst_buffer_unmap (buffer, &map);
|
||||
|
||||
GST_WRITE_UINT32_BE (data + size - 4, size - 4);
|
||||
|
||||
GST_BUFFER_PTS (tag) = GST_CLOCK_TIME_NONE;
|
||||
GST_BUFFER_DTS (tag) = GST_CLOCK_TIME_NONE;
|
||||
GST_BUFFER_DURATION (tag) = GST_CLOCK_TIME_NONE;
|
||||
GST_BUFFER_OFFSET (tag) = GST_BUFFER_OFFSET (buffer);
|
||||
GST_BUFFER_OFFSET_END (tag) = GST_BUFFER_OFFSET_END (buffer);
|
||||
|
||||
/* mark the buffer if it's an audio buffer and there's also video being muxed
|
||||
* or it's a video interframe */
|
||||
if ((mux->have_video && !cpad->video) ||
|
||||
GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT))
|
||||
if (buffer) {
|
||||
GST_BUFFER_OFFSET (tag) = GST_BUFFER_OFFSET (buffer);
|
||||
GST_BUFFER_OFFSET_END (tag) = GST_BUFFER_OFFSET_END (buffer);
|
||||
|
||||
/* mark the buffer if it's an audio buffer and there's also video being muxed
|
||||
* or it's a video interframe */
|
||||
if ((mux->have_video && !cpad->video) ||
|
||||
GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT))
|
||||
GST_BUFFER_FLAG_SET (tag, GST_BUFFER_FLAG_DELTA_UNIT);
|
||||
} else {
|
||||
GST_BUFFER_FLAG_SET (tag, GST_BUFFER_FLAG_DELTA_UNIT);
|
||||
|
||||
GST_BUFFER_OFFSET (tag) = GST_BUFFER_OFFSET_END (tag) =
|
||||
GST_BUFFER_OFFSET_NONE;
|
||||
GST_BUFFER_OFFSET (tag) = GST_BUFFER_OFFSET_END (tag) =
|
||||
GST_BUFFER_OFFSET_NONE;
|
||||
}
|
||||
|
||||
return tag;
|
||||
}
|
||||
|
@ -1135,6 +1146,12 @@ gst_flv_mux_codec_data_buffer_to_tag (GstFlvMux * mux, GstBuffer * buffer,
|
|||
return gst_flv_mux_buffer_to_tag_internal (mux, buffer, cpad, TRUE);
|
||||
}
|
||||
|
||||
static inline GstBuffer *
|
||||
gst_flv_mux_eos_to_tag (GstFlvMux * mux, GstFlvPad * cpad)
|
||||
{
|
||||
return gst_flv_mux_buffer_to_tag_internal (mux, NULL, cpad, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
gst_flv_mux_put_buffer_in_streamheader (GValue * streamheader,
|
||||
GstBuffer * buffer)
|
||||
|
@ -1344,6 +1361,29 @@ gst_flv_mux_determine_duration (GstFlvMux * mux)
|
|||
return duration;
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_flv_mux_write_eos (GstFlvMux * mux)
|
||||
{
|
||||
GstBuffer *tag;
|
||||
GstFlvPad *video_pad = NULL;
|
||||
GSList *l = mux->collect->data;
|
||||
|
||||
if (!mux->have_video)
|
||||
return GST_FLOW_OK;
|
||||
|
||||
for (; l; l = l->next) {
|
||||
GstFlvPad *cpad = l->data;
|
||||
if (cpad && cpad->video) {
|
||||
video_pad = cpad;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tag = gst_flv_mux_eos_to_tag (mux, video_pad);
|
||||
|
||||
return gst_flv_mux_push (mux, tag);
|
||||
}
|
||||
|
||||
static GstFlowReturn
|
||||
gst_flv_mux_rewrite_header (GstFlvMux * mux)
|
||||
{
|
||||
|
@ -1550,6 +1590,8 @@ gst_flv_mux_handle_buffer (GstCollectPads * pads, GstCollectData * cdata,
|
|||
if (best) {
|
||||
return gst_flv_mux_write_buffer (mux, best, buffer);
|
||||
} else {
|
||||
/* FIXME check return values */
|
||||
gst_flv_mux_write_eos (mux);
|
||||
gst_flv_mux_rewrite_header (mux);
|
||||
gst_pad_push_event (mux->srcpad, gst_event_new_eos ());
|
||||
return GST_FLOW_EOS;
|
||||
|
|
Loading…
Reference in a new issue