dec->decode = g_list_prepend (dec->decode, gbuf);
/* if we copied a keyframe, flush and decode the decode queue */
- gst_buffer_extract (gbuf, 0, data, 1);
- if ((data[0] & 0x40) == 0) {
- data = GST_BUFFER_DATA (gbuf);
- if (data && (data[0] & 0x40) == 0) {
-- GST_DEBUG_OBJECT (dec, "copied keyframe");
-- res = theora_dec_flush_decode (dec);
++ if (gst_buffer_extract (gbuf, 0, data, 1) == 1) {
++ if ((data[0] & 0x40) == 0) {
++ GST_DEBUG_OBJECT (dec, "copied keyframe");
++ res = theora_dec_flush_decode (dec);
++ }
}
}
}
GST_TIME_ARGS (render_start), GST_TIME_ARGS (render_stop));
/* bring to position in the ringbuffer */
- if (sink->priv->do_time_offset) {
- time_offset =
- GST_AUDIO_CLOCK_CAST (sink->provided_clock)->abidata.ABI.time_offset;
- GST_DEBUG_OBJECT (sink,
- "time offset %" GST_TIME_FORMAT, GST_TIME_ARGS (time_offset));
- if (render_start > time_offset)
- render_start -= time_offset;
- else
- render_start = 0;
- if (render_stop > time_offset)
- render_stop -= time_offset;
- else
- render_stop = 0;
- }
+ time_offset = GST_AUDIO_CLOCK_CAST (sink->provided_clock)->time_offset;
+ GST_DEBUG_OBJECT (sink,
+ "time offset %" GST_TIME_FORMAT, GST_TIME_ARGS (time_offset));
+ if (render_start > time_offset)
+ render_start -= time_offset;
+ else
+ render_start = 0;
+ if (render_stop > time_offset)
+ render_stop -= time_offset;
+ else
+ render_stop = 0;
+ /* in some clock slaving cases, all late samples end up at 0 first,
+ * and subsequent ones align with that until threshold exceeded,
+ * and then sync back to 0 and so on, so avoid that altogether */
+ if (G_UNLIKELY (render_start == 0 && render_stop == 0))
+ goto too_late;
+
/* and bring the time to the rate corrected offset in the buffer */
render_start = gst_util_uint64_scale_int (render_start,
ringbuf->spec.rate, GST_SECOND);
{
GType tagtype;
gchar *str;
+ gchar *utfstr;
guint32 real_offset;
+ GError *error = NULL;
if (count > 4) {
+ guint8 *data;
+ gsize size;
+
if (offset < reader->base_offset) {
GST_WARNING ("Offset is smaller (%u) than base offset (%u)", offset,
reader->base_offset);
guint image_data_len,
guint id3_picture_type);
+ GstTagList * gst_tag_list_from_id3v2_tag (GstBuffer * buffer);
+
+ guint gst_tag_get_id3v2_tag_size (GstBuffer * buffer);
+
/* functions to convert GstBuffers with xmp packets contents to GstTagLists and back */
-GstTagList * gst_tag_list_from_xmp_buffer (const GstBuffer * buffer);
+GstTagList * gst_tag_list_from_xmp_buffer (GstBuffer * buffer);
GstBuffer * gst_tag_list_to_xmp_buffer (const GstTagList * list,
gboolean read_only);
GstBuffer * gst_tag_list_to_xmp_buffer_full (const GstTagList * list,
adder = GST_ADDER (gst_pad_get_parent (pad));
- GST_DEBUG ("Got %s event on pad %s:%s", GST_EVENT_TYPE_NAME (event),
- GST_DEBUG_PAD_NAME (pad));
+ GST_DEBUG_OBJECT (pad, "Got %s event on sink pad",
+ GST_EVENT_TYPE_NAME (event));
switch (GST_EVENT_TYPE (event)) {
+ case GST_EVENT_CAPS:
+ {
+ GstCaps *caps;
+
+ gst_event_parse_caps (event, &caps);
+ ret = gst_adder_setcaps (adder, pad, caps);
+ gst_event_unref (event);
+
+ goto beach;
+ }
case GST_EVENT_FLUSH_STOP:
/* we received a flush-stop. The collect_event function will push the
* event past our element. We simply forward all flush-stop events, even
case GST_STATE_CHANGE_NULL_TO_READY:
break;
case GST_STATE_CHANGE_READY_TO_PAUSED:
- adder->timestamp = 0;
+ adder->segment.position = 0;
adder->offset = 0;
adder->flush_stop_pending = FALSE;
- adder->segment_pending = TRUE;
+ adder->new_segment_pending = TRUE;
+ adder->wait_for_new_segment = FALSE;
- adder->segment_start = 0;
- adder->segment_end = GST_CLOCK_TIME_NONE;
- adder->segment_rate = 1.0;
- gst_segment_init (&adder->segment, GST_FORMAT_UNDEFINED);
+ gst_segment_init (&adder->segment, GST_FORMAT_TIME);
gst_collect_pads_start (adder->collect);
break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
/* sink event handling */
GstPadEventFunction collect_event;
GstSegment segment;
- gboolean segment_pending;
- guint64 segment_start, segment_end;
- gdouble segment_rate;
+ volatile gboolean new_segment_pending;
+ volatile gboolean wait_for_new_segment;
/* src event handling */
- gboolean flush_stop_pending;
-
+ volatile gboolean flush_stop_pending;
-
++
/* target caps */
GstCaps *filter_caps;
const spx_word16_t *sinc = &sinc_table[samp_frac_num * N];
const spx_word16_t *iptr = &in[last_sample];
- #ifndef OVERRIDE_INNER_PRODUCT_SINGLE
- sum = 0;
+ SSE_FALLBACK (INNER_PRODUCT_SINGLE)
- sum = 0;
++ sum = 0;
for (j = 0; j < N; j++)
sum += MULT16_16 (sinc[j], iptr[j]);
}
sum = accum[0] + accum[1] + accum[2] + accum[3];
*/
- #else
- sum = inner_product_single (sinc, iptr, N);
+ #ifdef OVERRIDE_INNER_PRODUCT_SINGLE
+ SSE_IMPLEMENTATION (INNER_PRODUCT_SINGLE)
- sum = inner_product_single (sinc, iptr, N);
- SSE_END(INNER_PRODUCT_SINGLE)
++ sum = inner_product_single (sinc, iptr, N);
++ SSE_END (INNER_PRODUCT_SINGLE)
#endif
--
-- out[out_stride * out_sample++] = SATURATE32 (PSHR32 (sum, 15), 32767);
++ out[out_stride * out_sample++] = SATURATE32 (PSHR32 (sum, 15), 32767);
last_sample += int_advance;
samp_frac_num += frac_advance;
if (samp_frac_num >= den_rate) {
accum[3] += sinc[j + 3] * iptr[j + 3];
}
sum = accum[0] + accum[1] + accum[2] + accum[3];
- #else
- sum = inner_product_double (sinc, iptr, N);
+ #ifdef OVERRIDE_INNER_PRODUCT_DOUBLE
+ SSE2_IMPLEMENTATION (INNER_PRODUCT_DOUBLE)
- sum = inner_product_double (sinc, iptr, N);
++ sum = inner_product_double (sinc, iptr, N);
+ SSE2_END (INNER_PRODUCT_DOUBLE)
#endif
--
-- out[out_stride * out_sample++] = PSHR32 (sum, 15);
++ out[out_stride * out_sample++] = PSHR32 (sum, 15);
last_sample += int_advance;
samp_frac_num += frac_advance;
if (samp_frac_num >= den_rate) {
1)) + MULT16_32_Q15 (interp[1], SHR32 (accum[1],
1)) + MULT16_32_Q15 (interp[2], SHR32 (accum[2],
1)) + MULT16_32_Q15 (interp[3], SHR32 (accum[3], 1));
- #else
- cubic_coef (frac, interp);
+ #ifdef OVERRIDE_INTERPOLATE_PRODUCT_SINGLE
+ SSE_IMPLEMENTATION (INTERPOLATE_PRODUCT_SINGLE)
- cubic_coef (frac, interp);
++ cubic_coef (frac, interp);
sum =
interpolate_product_single (iptr,
st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample,
interp);
+ SSE_END (INTERPOLATE_PRODUCT_SINGLE)
#endif
--
-- out[out_stride * out_sample++] = SATURATE32 (PSHR32 (sum, 14), 32767);
++ out[out_stride * out_sample++] = SATURATE32 (PSHR32 (sum, 14), 32767);
last_sample += int_advance;
samp_frac_num += frac_advance;
if (samp_frac_num >= den_rate) {
MULT16_32_Q15 (interp[0], accum[0]) + MULT16_32_Q15 (interp[1],
accum[1]) + MULT16_32_Q15 (interp[2],
accum[2]) + MULT16_32_Q15 (interp[3], accum[3]);
- #else
- cubic_coef (frac, interp);
+ #ifdef OVERRIDE_INTERPOLATE_PRODUCT_DOUBLE
+ SSE2_IMPLEMENTATION (INTERPOLATE_PRODUCT_DOUBLE)
- cubic_coef (frac, interp);
++ cubic_coef (frac, interp);
sum =
interpolate_product_double (iptr,
st->sinc_table + st->oversample + 4 - offset - 2, N, st->oversample,
interp);
+ SSE2_END (INTERPOLATE_PRODUCT_DOUBLE)
#endif
--
-- out[out_stride * out_sample++] = PSHR32 (sum, 15);
++ out[out_stride * out_sample++] = PSHR32 (sum, 15);
last_sample += int_advance;
samp_frac_num += frac_advance;
if (samp_frac_num >= den_rate) {
/* 3.2. restriction elements */
/* FIXME : Once we have properties for specific converters, use those */
if (GST_IS_ENCODING_VIDEO_PROFILE (sprof)) {
- const gboolean native_video = !!(ebin->flags & GST_ENC_FLAG_NATIVE_VIDEO);
+ const gboolean native_video =
- ! !(ebin->flags & GST_ENC_FLAG_NO_VIDEO_CONVERSION);
++ !!(ebin->flags & GST_ENC_FLAG_NO_VIDEO_CONVERSION);
GstElement *cspace = NULL, *scale, *vrate, *cspace2 = NULL;
GST_LOG ("Adding conversion elements for video stream");
chain = dpad->chain;
dbin = chain->dbin;
- GST_LOG_OBJECT (dpad, "blocked:%d, dpad->chain:%p", blocked, chain);
+ GST_LOG_OBJECT (dpad, "blocked: dpad->chain:%p", chain);
- dpad->blocked = blocked;
+ dpad->blocked = TRUE;
- if (dpad->blocked) {
- EXPOSE_LOCK (dbin);
- if (gst_decode_chain_is_complete (dbin->decode_chain)) {
- if (!gst_decode_bin_expose (dbin))
- GST_WARNING_OBJECT (dbin, "Couldn't expose group");
- }
- EXPOSE_UNLOCK (dbin);
+ EXPOSE_LOCK (dbin);
+ if (gst_decode_chain_is_complete (dbin->decode_chain)) {
+ if (!gst_decode_bin_expose (dbin))
+ GST_WARNING_OBJECT (dbin, "Couldn't expose group");
}
+ EXPOSE_UNLOCK (dbin);
+
+ return GST_PROBE_OK;
}
-static gboolean
-source_pad_event_probe (GstPad * pad, GstEvent * event, GstDecodePad * dpad)
+static GstProbeReturn
+source_pad_event_probe (GstPad * pad, GstProbeType type, gpointer type_data,
+ gpointer user_data)
{
+ GstEvent *event = type_data;
+ GstDecodePad *dpad = user_data;
+ gboolean res = TRUE;
GST_LOG_OBJECT (pad, "%s dpad:%p", GST_EVENT_TYPE_NAME (event), dpad);
if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) {
GST_DEBUG_OBJECT (pad, "we received EOS");
- /* Check if all pads are drained. If there is a next group to expose, we
- * will remove the ghostpad of the current group first, which unlinks the
- * peer and so drops the EOS. */
- gst_decode_pad_handle_eos (dpad);
- }
- /* never drop events */
- return GST_PROBE_OK;
+ /* Check if all pads are drained.
+ * * If there is no next group, we will let the EOS go through.
+ * * If there is a next group but the current group isn't completely
+ * drained, we will drop the EOS event.
+ * * If there is a next group to expose and this was the last non-drained
+ * pad for that group, we will remove the ghostpad of the current group
+ * first, which unlinks the peer and so drops the EOS. */
+ res = gst_decode_pad_handle_eos (dpad);
+ }
-
- return res;
++ if (res)
++ return GST_PROBE_OK;
++ else
++ return GST_PROBE_DROP;
}
static void
ret = gst_pad_peer_query (self->sinkpad, query);
} else {
ret = TRUE;
- gst_query_set_position (query, GST_FORMAT_TIME,
- self->segment.last_stop);
+ gst_query_set_position (query, GST_FORMAT_TIME, self->segment.position);
}
+ break;
}
case GST_QUERY_SEEKING:
{
gst_tag_list_add_id3_image
gst_tag_list_from_exif_buffer
gst_tag_list_from_exif_buffer_with_tiff_header
+ gst_tag_list_from_vorbiscomment
+ gst_tag_list_from_id3v2_tag
gst_tag_list_from_vorbiscomment_buffer
gst_tag_list_from_xmp_buffer
gst_tag_list_new_from_id3v1