mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-06-05 15:08:53 +00:00
theoraparse: be smarter when queuing headers
Look at the first byte of the buffer data (if we can) to decide if the packet is a header packet or not instead of counting packets.
This commit is contained in:
parent
51b5f33c3c
commit
9def0d8c61
2 changed files with 45 additions and 18 deletions
|
@ -54,7 +54,6 @@ struct _GstTheoraParse {
|
||||||
GstPad * sinkpad;
|
GstPad * sinkpad;
|
||||||
GstPad * srcpad;
|
GstPad * srcpad;
|
||||||
|
|
||||||
guint packetno;
|
|
||||||
gboolean send_streamheader;
|
gboolean send_streamheader;
|
||||||
gboolean streamheader_received;
|
gboolean streamheader_received;
|
||||||
gboolean is_old_bitstream;
|
gboolean is_old_bitstream;
|
||||||
|
|
|
@ -270,7 +270,9 @@ theora_parse_set_header_on_caps (GstTheoraParse * parse, GstCaps * caps)
|
||||||
g_value_init (&array, GST_TYPE_ARRAY);
|
g_value_init (&array, GST_TYPE_ARRAY);
|
||||||
|
|
||||||
for (i = 0; i < 3; i++) {
|
for (i = 0; i < 3; i++) {
|
||||||
g_assert (bufs[i]);
|
if (bufs[i] == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
bufs[i] = gst_buffer_make_metadata_writable (bufs[i]);
|
bufs[i] = gst_buffer_make_metadata_writable (bufs[i]);
|
||||||
GST_BUFFER_FLAG_SET (bufs[i], GST_BUFFER_FLAG_IN_CAPS);
|
GST_BUFFER_FLAG_SET (bufs[i], GST_BUFFER_FLAG_IN_CAPS);
|
||||||
|
|
||||||
|
@ -320,6 +322,9 @@ theora_parse_set_streamheader (GstTheoraParse * parse)
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
buf = parse->streamheader[i];
|
buf = parse->streamheader[i];
|
||||||
|
if (buf == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
gst_buffer_set_caps (buf, GST_PAD_CAPS (parse->srcpad));
|
gst_buffer_set_caps (buf, GST_PAD_CAPS (parse->srcpad));
|
||||||
|
|
||||||
packet.packet = GST_BUFFER_DATA (buf);
|
packet.packet = GST_BUFFER_DATA (buf);
|
||||||
|
@ -375,10 +380,12 @@ theora_parse_push_headers (GstTheoraParse * parse)
|
||||||
|
|
||||||
/* ignore return values, we pass along the result of pushing data packets only
|
/* ignore return values, we pass along the result of pushing data packets only
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++) {
|
||||||
gst_pad_push (parse->srcpad, gst_buffer_ref (parse->streamheader[i]));
|
GstBuffer *buf;
|
||||||
|
|
||||||
parse->send_streamheader = FALSE;
|
if ((buf = parse->streamheader[i]))
|
||||||
|
gst_pad_push (parse->srcpad, gst_buffer_ref (buf));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -568,7 +575,18 @@ theora_parse_drain_queue (GstTheoraParse * parse, gint64 granulepos)
|
||||||
|
|
||||||
parse_granulepos (parse, granulepos, &keyframe, &frame);
|
parse_granulepos (parse, granulepos, &keyframe, &frame);
|
||||||
|
|
||||||
|
GST_DEBUG ("draining queue of length %d",
|
||||||
|
g_queue_get_length (parse->buffer_queue));
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (parse, "gp %" G_GINT64_FORMAT ", kf %" G_GINT64_FORMAT
|
||||||
|
", frame %" G_GINT64_FORMAT, granulepos, keyframe, frame);
|
||||||
|
|
||||||
prev_frame = frame - g_queue_get_length (parse->buffer_queue);
|
prev_frame = frame - g_queue_get_length (parse->buffer_queue);
|
||||||
|
|
||||||
|
GST_LOG_OBJECT (parse,
|
||||||
|
"new prev %" G_GINT64_FORMAT ", prev %" G_GINT64_FORMAT, prev_frame,
|
||||||
|
parse->prev_frame);
|
||||||
|
|
||||||
if (prev_frame < parse->prev_frame) {
|
if (prev_frame < parse->prev_frame) {
|
||||||
GST_WARNING ("jumped %" G_GINT64_FORMAT
|
GST_WARNING ("jumped %" G_GINT64_FORMAT
|
||||||
" frames backwards! not sure what to do here",
|
" frames backwards! not sure what to do here",
|
||||||
|
@ -583,9 +601,6 @@ theora_parse_drain_queue (GstTheoraParse * parse, gint64 granulepos)
|
||||||
parse->prev_frame = prev_frame;
|
parse->prev_frame = prev_frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
GST_DEBUG ("draining queue of length %d",
|
|
||||||
g_queue_get_length (parse->buffer_queue));
|
|
||||||
|
|
||||||
while (!g_queue_is_empty (parse->buffer_queue)) {
|
while (!g_queue_is_empty (parse->buffer_queue)) {
|
||||||
GstBuffer *buf;
|
GstBuffer *buf;
|
||||||
|
|
||||||
|
@ -635,24 +650,38 @@ static GstFlowReturn
|
||||||
theora_parse_chain (GstPad * pad, GstBuffer * buffer)
|
theora_parse_chain (GstPad * pad, GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
GstFlowReturn ret;
|
GstFlowReturn ret;
|
||||||
GstBuffer *buf;
|
|
||||||
GstTheoraParse *parse;
|
GstTheoraParse *parse;
|
||||||
|
guint8 *data;
|
||||||
|
guint size;
|
||||||
|
gboolean have_header;
|
||||||
|
|
||||||
parse = GST_THEORA_PARSE (gst_pad_get_parent (pad));
|
parse = GST_THEORA_PARSE (gst_pad_get_parent (pad));
|
||||||
|
|
||||||
buf = GST_BUFFER (buffer);
|
data = GST_BUFFER_DATA (buffer);
|
||||||
parse->packetno++;
|
size = GST_BUFFER_SIZE (buffer);
|
||||||
|
|
||||||
if (parse->packetno <= 3) {
|
have_header = FALSE;
|
||||||
/* if 1 <= packetno <= 3, it's streamheader,
|
if (size >= 1) {
|
||||||
* so put it on the streamheader list and return */
|
if (data[0] & 0x80)
|
||||||
parse->streamheader[parse->packetno - 1] = buf;
|
have_header = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (have_header) {
|
||||||
|
if (parse->send_streamheader) {
|
||||||
|
/* we need to collect the headers still */
|
||||||
|
/* so put it on the streamheader list and return */
|
||||||
|
if (data[0] >= 0x80 && data[0] <= 0x82)
|
||||||
|
parse->streamheader[data[0] - 0x80] = buffer;
|
||||||
|
}
|
||||||
ret = GST_FLOW_OK;
|
ret = GST_FLOW_OK;
|
||||||
} else {
|
} else {
|
||||||
if (parse->send_streamheader)
|
/* data packet, push the headers we collected before */
|
||||||
|
if (parse->send_streamheader) {
|
||||||
theora_parse_push_headers (parse);
|
theora_parse_push_headers (parse);
|
||||||
|
parse->send_streamheader = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
ret = theora_parse_queue_buffer (parse, buf);
|
ret = theora_parse_queue_buffer (parse, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
gst_object_unref (parse);
|
gst_object_unref (parse);
|
||||||
|
@ -876,7 +905,6 @@ theora_parse_change_state (GstElement * element, GstStateChange transition)
|
||||||
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
case GST_STATE_CHANGE_READY_TO_PAUSED:
|
||||||
theora_info_init (&parse->info);
|
theora_info_init (&parse->info);
|
||||||
theora_comment_init (&parse->comment);
|
theora_comment_init (&parse->comment);
|
||||||
parse->packetno = 0;
|
|
||||||
parse->send_streamheader = TRUE;
|
parse->send_streamheader = TRUE;
|
||||||
parse->buffer_queue = g_queue_new ();
|
parse->buffer_queue = g_queue_new ();
|
||||||
parse->event_queue = g_queue_new ();
|
parse->event_queue = g_queue_new ();
|
||||||
|
|
Loading…
Reference in a new issue