mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-23 18:21:04 +00:00
dvdspu: Collect entire PGS packets and queue as events
Collect fragmented PGS packets and submit as complete events for processing at the correct moment.
This commit is contained in:
parent
4e847cb4ac
commit
871287ba2a
1 changed files with 56 additions and 11 deletions
|
@ -931,11 +931,15 @@ gst_dvd_spu_setup_cmd_blk (GstDVDSpu * dvdspu, guint16 cmd_blk_offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_dvd_spu_handle_new_spu_buf (GstDVDSpu * dvdspu, SpuPacket * packet)
|
gst_dvd_spu_handle_new_vobsub_buf (GstDVDSpu * dvdspu, SpuPacket * packet)
|
||||||
{
|
{
|
||||||
guint8 *start, *end;
|
guint8 *start, *end;
|
||||||
SpuState *state = &dvdspu->spu_state;
|
SpuState *state = &dvdspu->spu_state;
|
||||||
|
|
||||||
|
#if DUMP_DCSQ
|
||||||
|
gst_dvd_spu_dump_dcsq (dvdspu, packet->event_ts, packet->buf);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (G_UNLIKELY (GST_BUFFER_SIZE (packet->buf) < 4))
|
if (G_UNLIKELY (GST_BUFFER_SIZE (packet->buf) < 4))
|
||||||
goto invalid;
|
goto invalid;
|
||||||
|
|
||||||
|
@ -1127,12 +1131,20 @@ gst_dvd_spu_advance_spu (GstDVDSpu * dvdspu, GstClockTime new_ts)
|
||||||
packet->buf ? "buffer" : "event");
|
packet->buf ? "buffer" : "event");
|
||||||
|
|
||||||
if (packet->buf) {
|
if (packet->buf) {
|
||||||
#if DUMP_DCSQ
|
switch (dvdspu->spu_input_type) {
|
||||||
gst_dvd_spu_dump_dcsq (dvdspu, packet->event_ts, packet->buf);
|
case SPU_INPUT_TYPE_VOBSUB:
|
||||||
#endif
|
gst_dvd_spu_handle_new_vobsub_buf (dvdspu, packet);
|
||||||
gst_dvd_spu_handle_new_spu_buf (dvdspu, packet);
|
break;
|
||||||
}
|
case SPU_INPUT_TYPE_PGS:
|
||||||
if (packet->event)
|
gstspu_dump_pgs_buffer (packet->buf);
|
||||||
|
gst_buffer_unref (packet->buf);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_assert_not_reached ();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
g_assert (packet->event == NULL);
|
||||||
|
} else if (packet->event)
|
||||||
gst_dvd_spu_handle_dvd_event (dvdspu, packet->event);
|
gst_dvd_spu_handle_dvd_event (dvdspu, packet->event);
|
||||||
|
|
||||||
g_free (packet);
|
g_free (packet);
|
||||||
|
@ -1277,6 +1289,9 @@ gst_dvd_spu_subpic_chain (GstPad * pad, GstBuffer * buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dvdspu->partial_spu != NULL) {
|
if (dvdspu->partial_spu != NULL) {
|
||||||
|
if (GST_BUFFER_TIMESTAMP_IS_VALID (buf))
|
||||||
|
GST_WARNING_OBJECT (dvdspu,
|
||||||
|
"Joining subpicture buffer with timestamp to previous");
|
||||||
dvdspu->partial_spu = gst_buffer_join (dvdspu->partial_spu, buf);
|
dvdspu->partial_spu = gst_buffer_join (dvdspu->partial_spu, buf);
|
||||||
} else {
|
} else {
|
||||||
/* If we don't yet have a buffer, wait for one with a timestamp,
|
/* If we don't yet have a buffer, wait for one with a timestamp,
|
||||||
|
@ -1317,11 +1332,41 @@ gst_dvd_spu_subpic_chain (GstPad * pad, GstBuffer * buf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SPU_INPUT_TYPE_PGS:
|
case SPU_INPUT_TYPE_PGS:{
|
||||||
gstspu_dump_pgs_buffer (dvdspu->partial_spu);
|
/* Collect until we have a command buffer that ends exactly at the size
|
||||||
gst_buffer_unref (dvdspu->partial_spu);
|
* we've collected */
|
||||||
dvdspu->partial_spu = NULL;
|
guint8 packet_type;
|
||||||
|
guint16 packet_size;
|
||||||
|
guint8 *data = GST_BUFFER_DATA (dvdspu->partial_spu);
|
||||||
|
guint8 *end = data + GST_BUFFER_SIZE (dvdspu->partial_spu);
|
||||||
|
|
||||||
|
/* FIXME: There's no need to walk the command set each time. We can set a
|
||||||
|
* marker and resume where we left off next time */
|
||||||
|
while (data != end) {
|
||||||
|
if (data + 3 > end)
|
||||||
|
break;
|
||||||
|
packet_type = *data++;
|
||||||
|
packet_size = GST_READ_UINT16_BE (data);
|
||||||
|
data += 2;
|
||||||
|
if (data + packet_size > end)
|
||||||
|
break;
|
||||||
|
data += packet_size;
|
||||||
|
if (packet_type == PGS_COMMAND_END_DISPLAY && data != end) {
|
||||||
|
/* Extra cruft on the end of the packet -> assume invalid */
|
||||||
|
gst_buffer_unref (dvdspu->partial_spu);
|
||||||
|
dvdspu->partial_spu = NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dvdspu->partial_spu && data == end) {
|
||||||
|
g_print ("Complete packet of size %u\n",
|
||||||
|
GST_BUFFER_SIZE (dvdspu->partial_spu));
|
||||||
|
submit_new_spu_packet (dvdspu, dvdspu->partial_spu);
|
||||||
|
dvdspu->partial_spu = NULL;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
GST_ERROR_OBJECT (dvdspu, "Input type not configured before SPU passing");
|
GST_ERROR_OBJECT (dvdspu, "Input type not configured before SPU passing");
|
||||||
goto caps_not_set;
|
goto caps_not_set;
|
||||||
|
|
Loading…
Reference in a new issue