oggstream: reject Ogg/Opus streams with nonsensical preskip/granpos setup
As the spec mandates.
This commit is contained in:
parent
bc221fba78
commit
078dd2e896
@ -556,8 +556,15 @@ gst_ogg_demux_chain_peer (GstOggPad * pad, ogg_packet * packet,
|
|||||||
out_offset_end = -1;
|
out_offset_end = -1;
|
||||||
} else {
|
} else {
|
||||||
if (packet->granulepos != -1) {
|
if (packet->granulepos != -1) {
|
||||||
pad->current_granule = gst_ogg_stream_granulepos_to_granule (&pad->map,
|
gint64 granule = gst_ogg_stream_granulepos_to_granule (&pad->map,
|
||||||
packet->granulepos);
|
packet->granulepos);
|
||||||
|
if (granule < 0) {
|
||||||
|
GST_ERROR_OBJECT (ogg,
|
||||||
|
"granulepos %" G_GINT64_FORMAT " yielded granule %" G_GINT64_FORMAT,
|
||||||
|
packet->granulepos, granule);
|
||||||
|
return GST_FLOW_ERROR;
|
||||||
|
}
|
||||||
|
pad->current_granule = granule;
|
||||||
pad->keyframe_granule =
|
pad->keyframe_granule =
|
||||||
gst_ogg_stream_granulepos_to_key_granule (&pad->map,
|
gst_ogg_stream_granulepos_to_key_granule (&pad->map,
|
||||||
packet->granulepos);
|
packet->granulepos);
|
||||||
@ -866,6 +873,11 @@ gst_ogg_pad_submit_packet (GstOggPad * pad, ogg_packet * packet)
|
|||||||
if (granule != -1) {
|
if (granule != -1) {
|
||||||
GST_DEBUG_OBJECT (ogg, "%p has granulepos %" G_GINT64_FORMAT, pad, granule);
|
GST_DEBUG_OBJECT (ogg, "%p has granulepos %" G_GINT64_FORMAT, pad, granule);
|
||||||
pad->current_granule = granule;
|
pad->current_granule = granule;
|
||||||
|
} else if (granule != -1) {
|
||||||
|
GST_ERROR_OBJECT (ogg,
|
||||||
|
"granulepos %" G_GINT64_FORMAT " yielded granule %" G_GINT64_FORMAT,
|
||||||
|
packet->granulepos, granule);
|
||||||
|
return GST_FLOW_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* restart header packet count when seeing a b_o_s page;
|
/* restart header packet count when seeing a b_o_s page;
|
||||||
@ -903,6 +915,12 @@ gst_ogg_pad_submit_packet (GstOggPad * pad, ogg_packet * packet)
|
|||||||
|
|
||||||
granule = gst_ogg_stream_granulepos_to_granule (&pad->map,
|
granule = gst_ogg_stream_granulepos_to_granule (&pad->map,
|
||||||
packet->granulepos);
|
packet->granulepos);
|
||||||
|
if (granule < 0) {
|
||||||
|
GST_ERROR_OBJECT (ogg,
|
||||||
|
"granulepos %" G_GINT64_FORMAT " yielded granule %"
|
||||||
|
G_GINT64_FORMAT, packet->granulepos, granule);
|
||||||
|
return GST_FLOW_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (granule > pad->map.accumulated_granule)
|
if (granule > pad->map.accumulated_granule)
|
||||||
start_granule = granule - pad->map.accumulated_granule;
|
start_granule = granule - pad->map.accumulated_granule;
|
||||||
|
@ -1873,6 +1873,7 @@ setup_opus_mapper (GstOggStream * pad, ogg_packet * packet)
|
|||||||
pad->granulerate_d = 1;
|
pad->granulerate_d = 1;
|
||||||
pad->granuleshift = 0;
|
pad->granuleshift = 0;
|
||||||
pad->n_header_packets = 2;
|
pad->n_header_packets = 2;
|
||||||
|
pad->first_granpos = -1;
|
||||||
|
|
||||||
/* pre-skip is in samples at 48000 Hz, which matches granule one for one */
|
/* pre-skip is in samples at 48000 Hz, which matches granule one for one */
|
||||||
pad->granule_offset = -GST_READ_UINT16_LE (packet->packet + 10);
|
pad->granule_offset = -GST_READ_UINT16_LE (packet->packet + 10);
|
||||||
@ -1890,6 +1891,29 @@ is_header_opus (GstOggStream * pad, ogg_packet * packet)
|
|||||||
return packet->bytes >= 8 && !memcmp (packet->packet, "Opus", 4);
|
return packet->bytes >= 8 && !memcmp (packet->packet, "Opus", 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gint64
|
||||||
|
granulepos_to_granule_opus (GstOggStream * pad, gint64 granulepos)
|
||||||
|
{
|
||||||
|
if (granulepos == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* We must reject some particular cases for the first granpos */
|
||||||
|
|
||||||
|
if (pad->first_granpos < 0 || granulepos < pad->first_granpos)
|
||||||
|
pad->first_granpos = granulepos;
|
||||||
|
|
||||||
|
if (pad->first_granpos == granulepos) {
|
||||||
|
if (granulepos < -pad->granule_offset) {
|
||||||
|
GST_ERROR ("Invalid Opus stream: first granulepos (%" G_GINT64_FORMAT
|
||||||
|
") less than preskip (%" G_GINT64_FORMAT ")", granulepos,
|
||||||
|
-pad->granule_offset);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return granulepos;
|
||||||
|
}
|
||||||
|
|
||||||
static gint64
|
static gint64
|
||||||
packet_duration_opus (GstOggStream * pad, ogg_packet * packet)
|
packet_duration_opus (GstOggStream * pad, ogg_packet * packet)
|
||||||
{
|
{
|
||||||
@ -2147,7 +2171,7 @@ const GstOggMap mappers[] = {
|
|||||||
"OpusHead", 8, 0,
|
"OpusHead", 8, 0,
|
||||||
"audio/x-opus",
|
"audio/x-opus",
|
||||||
setup_opus_mapper,
|
setup_opus_mapper,
|
||||||
granulepos_to_granule_default,
|
granulepos_to_granule_opus,
|
||||||
granule_to_granulepos_default,
|
granule_to_granulepos_default,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -93,6 +93,8 @@ struct _GstOggStream
|
|||||||
gboolean theora_has_zero_keyoffset;
|
gboolean theora_has_zero_keyoffset;
|
||||||
/* VP8 stuff */
|
/* VP8 stuff */
|
||||||
gboolean is_vp8;
|
gboolean is_vp8;
|
||||||
|
/* opus stuff */
|
||||||
|
gint64 first_granpos;
|
||||||
/* OGM stuff */
|
/* OGM stuff */
|
||||||
gboolean is_ogm;
|
gboolean is_ogm;
|
||||||
gboolean is_ogm_text;
|
gboolean is_ogm_text;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user