mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-10-04 17:52:29 +00:00
vorbisdec: Handle headers in caps
This commit is contained in:
parent
7197831605
commit
0f7522e449
1 changed files with 87 additions and 2 deletions
|
@ -929,7 +929,8 @@ vorbis_handle_data_packet (GstVorbisDec * vd, ogg_packet * packet,
|
||||||
/* get samples ready for reading now, should be sample_count */
|
/* get samples ready for reading now, should be sample_count */
|
||||||
#ifdef USE_TREMOLO
|
#ifdef USE_TREMOLO
|
||||||
pcm = GST_BUFFER_DATA (out);
|
pcm = GST_BUFFER_DATA (out);
|
||||||
if (G_UNLIKELY ((vorbis_dsp_pcmout (&vd->vd, pcm, sample_count)) != sample_count))
|
if (G_UNLIKELY ((vorbis_dsp_pcmout (&vd->vd, pcm,
|
||||||
|
sample_count)) != sample_count))
|
||||||
#else
|
#else
|
||||||
if (G_UNLIKELY ((vorbis_synthesis_pcmout (&vd->vd, &pcm)) != sample_count))
|
if (G_UNLIKELY ((vorbis_synthesis_pcmout (&vd->vd, &pcm)) != sample_count))
|
||||||
#endif
|
#endif
|
||||||
|
@ -960,7 +961,6 @@ done:
|
||||||
/* no output, still keep track of timestamps */
|
/* no output, still keep track of timestamps */
|
||||||
vorbis_do_timestamps (vd, NULL, FALSE, timestamp, duration);
|
vorbis_do_timestamps (vd, NULL, FALSE, timestamp, duration);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_TREMOLO
|
#ifdef USE_TREMOLO
|
||||||
vorbis_dsp_read (&vd->vd, sample_count);
|
vorbis_dsp_read (&vd->vd, sample_count);
|
||||||
#else
|
#else
|
||||||
|
@ -997,6 +997,77 @@ wrong_samples:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GstFlowReturn
|
||||||
|
vorbis_dec_handle_header_buffer (GstVorbisDec * vd, GstBuffer * buffer)
|
||||||
|
{
|
||||||
|
ogg_packet *packet;
|
||||||
|
ogg_packet_wrapper packet_wrapper;
|
||||||
|
|
||||||
|
gst_ogg_packet_wrapper_from_buffer (&packet_wrapper, buffer);
|
||||||
|
packet = gst_ogg_packet_from_wrapper (&packet_wrapper);
|
||||||
|
|
||||||
|
return vorbis_handle_header_packet (vd, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define MIN_NUM_HEADERS 3
|
||||||
|
static GstFlowReturn
|
||||||
|
vorbis_dec_handle_header_caps (GstVorbisDec * vd, GstBuffer * buffer)
|
||||||
|
{
|
||||||
|
GstFlowReturn result = GST_FLOW_OK;
|
||||||
|
GstCaps *caps = GST_PAD_CAPS (vd->sinkpad);
|
||||||
|
GstStructure *s = gst_caps_get_structure (caps, 0);
|
||||||
|
const GValue *array = gst_structure_get_value (s, "streamheader");
|
||||||
|
|
||||||
|
if (array && (gst_value_array_get_size (array) >= MIN_NUM_HEADERS)) {
|
||||||
|
const GValue *value = NULL;
|
||||||
|
GstBuffer *buf = NULL;
|
||||||
|
|
||||||
|
/* initial header */
|
||||||
|
value = gst_value_array_get_value (array, 0);
|
||||||
|
buf = gst_value_get_buffer (value);
|
||||||
|
if (!buf)
|
||||||
|
goto null_buffer;
|
||||||
|
result = vorbis_dec_handle_header_buffer (vd, buf);
|
||||||
|
|
||||||
|
/* comment header */
|
||||||
|
if (result == GST_FLOW_OK) {
|
||||||
|
value = gst_value_array_get_value (array, 1);
|
||||||
|
buf = gst_value_get_buffer (value);
|
||||||
|
if (!buf)
|
||||||
|
goto null_buffer;
|
||||||
|
result = vorbis_dec_handle_header_buffer (vd, buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* bitstream codebook header */
|
||||||
|
if (result == GST_FLOW_OK) {
|
||||||
|
value = gst_value_array_get_value (array, 2);
|
||||||
|
buf = gst_value_get_buffer (value);
|
||||||
|
if (!buf)
|
||||||
|
goto null_buffer;
|
||||||
|
result = vorbis_dec_handle_header_buffer (vd, buf);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
goto array_error;
|
||||||
|
|
||||||
|
done:
|
||||||
|
return (result != GST_FLOW_OK ? GST_FLOW_NOT_NEGOTIATED : GST_FLOW_OK);
|
||||||
|
|
||||||
|
array_error:
|
||||||
|
{
|
||||||
|
GST_WARNING_OBJECT (vd, "streamheader array not found");
|
||||||
|
result = GST_FLOW_ERROR;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
|
||||||
|
null_buffer:
|
||||||
|
{
|
||||||
|
GST_WARNING_OBJECT (vd, "streamheader with null buffer received");
|
||||||
|
result = GST_FLOW_ERROR;
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static GstFlowReturn
|
static GstFlowReturn
|
||||||
vorbis_dec_decode_buffer (GstVorbisDec * vd, GstBuffer * buffer)
|
vorbis_dec_decode_buffer (GstVorbisDec * vd, GstBuffer * buffer)
|
||||||
{
|
{
|
||||||
|
@ -1034,6 +1105,13 @@ vorbis_dec_decode_buffer (GstVorbisDec * vd, GstBuffer * buffer)
|
||||||
} else {
|
} else {
|
||||||
GstClockTime timestamp, duration;
|
GstClockTime timestamp, duration;
|
||||||
|
|
||||||
|
/* try to find header in caps so we can initialize the decoder */
|
||||||
|
if (!vd->initialized) {
|
||||||
|
result = vorbis_dec_handle_header_caps (vd, buffer);
|
||||||
|
if (result != GST_FLOW_OK)
|
||||||
|
goto invalid_caps_header;
|
||||||
|
}
|
||||||
|
|
||||||
timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
timestamp = GST_BUFFER_TIMESTAMP (buffer);
|
||||||
duration = GST_BUFFER_DURATION (buffer);
|
duration = GST_BUFFER_DURATION (buffer);
|
||||||
|
|
||||||
|
@ -1060,6 +1138,13 @@ empty_header:
|
||||||
vd->discont = TRUE;
|
vd->discont = TRUE;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
invalid_caps_header:
|
||||||
|
{
|
||||||
|
GST_ELEMENT_ERROR (vd, STREAM, DECODE, (NULL),
|
||||||
|
("invalid streamheader in caps"));
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue