void GstEnginePipeline::SourceDrainedCallback(GstURIDecodeBin* bin, gpointer self) { GstEnginePipeline* instance = reinterpret_cast<GstEnginePipeline*>(self); if (instance->has_next_valid_url()) { instance->TransitionToNext(); } }
void GstEnginePipeline::SourceDrainedCallback(GstURIDecodeBin* bin, gpointer self) { GstEnginePipeline* instance = reinterpret_cast<GstEnginePipeline*>(self); if (instance->has_next_valid_url() && // I'm not sure why, but calling this when previous track is a local song // and the next track is a Spotify song is buggy: the Spotify song will // not start or with some offset. So just do nothing here: when the song // finished, EndOfStreamReached/TrackEnded will be emitted anyway so // NextItem will be called. !(instance->url_.scheme() != "spotify" && instance->next_url_.scheme() == "spotify")) { instance->TransitionToNext(); } }
bool GstEnginePipeline::HandoffCallback(GstPad*, GstBuffer* buf, gpointer self) { GstEnginePipeline* instance = reinterpret_cast<GstEnginePipeline*>(self); QList<BufferConsumer*> consumers; { QMutexLocker l(&instance->buffer_consumers_mutex_); consumers = instance->buffer_consumers_; } for (BufferConsumer* consumer : consumers) { gst_buffer_ref(buf); consumer->ConsumeBuffer(buf, instance->id()); } // Calculate the end time of this buffer so we can stop playback if it's // after the end time of this song. if (instance->end_offset_nanosec_ > 0) { quint64 start_time = GST_BUFFER_TIMESTAMP(buf) - instance->segment_start_; quint64 duration = GST_BUFFER_DURATION(buf); quint64 end_time = start_time + duration; if (end_time > instance->end_offset_nanosec_) { if (instance->has_next_valid_url()) { if (instance->next_url_ == instance->url_ && instance->next_beginning_offset_nanosec_ == instance->end_offset_nanosec_) { // The "next" song is actually the next segment of this file - so // cheat and keep on playing, but just tell the Engine we've moved on. instance->end_offset_nanosec_ = instance->next_end_offset_nanosec_; instance->next_url_ = QUrl(); instance->next_beginning_offset_nanosec_ = 0; instance->next_end_offset_nanosec_ = 0; // GstEngine will try to seek to the start of the new section, but // we're already there so ignore it. instance->ignore_next_seek_ = true; emit instance->EndOfStreamReached(instance->id(), true); } else { // We have a next song but we can't cheat, so move to it normally. instance->TransitionToNext(); } } else { // There's no next song emit instance->EndOfStreamReached(instance->id(), false); } } } if (instance->emit_track_ended_on_time_discontinuity_) { if (GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_DISCONT) || GST_BUFFER_OFFSET(buf) < instance->last_buffer_offset_) { qLog(Debug) << "Buffer discontinuity - emitting EOS"; instance->emit_track_ended_on_time_discontinuity_ = false; emit instance->EndOfStreamReached(instance->id(), true); } } instance->last_buffer_offset_ = GST_BUFFER_OFFSET(buf); return true; }