summaryrefslogtreecommitdiffstats
path: root/ext/resindvd
diff options
context:
space:
mode:
authorJan Schmidt <thaytan@noraisin.net>2009-05-11 14:17:42 +0100
committerJan Schmidt <thaytan@noraisin.net>2009-05-11 17:04:10 +0100
commit4204b644ef31c498ba27847dec3e8d6dbfd4eedd (patch)
tree9b0d8773b9b7cc38027d42c8487d14e66365327a /ext/resindvd
parent79f653fde8d6ff1ecee3147ca8afb42f8cec981a (diff)
downloadgst-plugins-bad-4204b644ef31c498ba27847dec3e8d6dbfd4eedd.tar.gz
gst-plugins-bad-4204b644ef31c498ba27847dec3e8d6dbfd4eedd.tar.bz2
gst-plugins-bad-4204b644ef31c498ba27847dec3e8d6dbfd4eedd.zip
resindvd: Manage timed still sequences better
Make timed still frames work better by extending the current segment when needed, and restarting the still sequence with the correct remaining duration when the wait it interrupted by activation of a highlight NAV packet.
Diffstat (limited to 'ext/resindvd')
-rw-r--r--ext/resindvd/resindvdsrc.c71
-rw-r--r--ext/resindvd/resindvdsrc.h3
2 files changed, 54 insertions, 20 deletions
diff --git a/ext/resindvd/resindvdsrc.c b/ext/resindvd/resindvdsrc.c
index f479da2a..15a2408d 100644
--- a/ext/resindvd/resindvdsrc.c
+++ b/ext/resindvd/resindvdsrc.c
@@ -590,6 +590,12 @@ rsn_dvdsrc_do_still (resinDvdSrc * src, int duration)
if (src->in_still_state == FALSE) {
GST_DEBUG_OBJECT (src, "**** Start STILL FRAME. Duration %d ****",
duration);
+
+ if (duration == 255)
+ src->still_time_remaining = GST_CLOCK_TIME_NONE;
+ else
+ src->still_time_remaining = GST_SECOND * duration;
+
/* Send a close-segment event, and a dvd-still start
* event, then sleep */
s = gst_structure_new ("application/x-gst-dvd",
@@ -622,7 +628,9 @@ rsn_dvdsrc_do_still (resinDvdSrc * src, int duration)
src->in_still_state = TRUE;
} else {
- GST_DEBUG_OBJECT (src, "Re-entering still wait");
+ GST_DEBUG_OBJECT (src,
+ "Re-entering still wait with %" GST_TIME_FORMAT " remaining",
+ GST_TIME_ARGS (src->still_time_remaining));
g_mutex_lock (src->branch_lock);
}
@@ -659,26 +667,42 @@ rsn_dvdsrc_do_still (resinDvdSrc * src, int duration)
GTimeVal end_time;
gboolean was_signalled;
- g_get_current_time (&end_time);
- g_time_val_add (&end_time, duration * G_USEC_PER_SEC);
+ if (src->still_time_remaining > 0) {
+ g_get_current_time (&end_time);
+ g_time_val_add (&end_time, src->still_time_remaining / GST_USECOND);
- /* FIXME: Implement timed stills by sleeping on the clock, possibly
- * in multiple steps if we get paused/unpaused */
- g_mutex_unlock (src->dvd_lock);
- GST_LOG_OBJECT (src, "cond_timed_wait still for %d sec", duration);
- was_signalled =
- g_cond_timed_wait (src->still_cond, src->branch_lock, &end_time);
- was_signalled |= src->branching;
+ /* Implement timed stills by sleeping, possibly
+ * in multiple steps if we get paused/unpaused */
+ g_mutex_unlock (src->dvd_lock);
+ GST_LOG_OBJECT (src, "cond_timed_wait still for %d sec", duration);
+ was_signalled =
+ g_cond_timed_wait (src->still_cond, src->branch_lock, &end_time);
+ was_signalled |= src->branching;
- g_mutex_unlock (src->branch_lock);
- g_mutex_lock (src->dvd_lock);
+ g_mutex_unlock (src->branch_lock);
+ g_mutex_lock (src->dvd_lock);
- if (was_signalled) {
- /* Signalled - must be flushing */
- GST_LOG_OBJECT (src,
- "cond_timed_wait still over. Signalled, branching = %d",
- src->branching);
- return TRUE;
+ if (was_signalled) {
+ /* Signalled - must be flushing */
+ GTimeVal cur_time;
+ GstClockTimeDiff remain;
+
+ g_get_current_time (&cur_time);
+ remain =
+ (end_time.tv_sec - cur_time.tv_sec) * GST_SECOND +
+ (end_time.tv_usec - cur_time.tv_usec) * GST_USECOND;
+ if (remain < 0)
+ src->still_time_remaining = 0;
+ else
+ src->still_time_remaining = remain;
+
+ GST_LOG_OBJECT (src,
+ "cond_timed_wait still aborted by signal with %" GST_TIME_FORMAT
+ " remaining. branching = %d",
+ GST_TIME_ARGS (src->still_time_remaining), src->branching);
+
+ return TRUE;
+ }
}
/* Else timed out, end the still */
@@ -690,12 +714,17 @@ rsn_dvdsrc_do_still (resinDvdSrc * src, int duration)
}
/* Tell downstream the still is over.
- * Later: We'll only do this if the still isn't interrupted: */
+ * We only do this if the still isn't interrupted: */
s = gst_structure_new ("application/x-gst-dvd",
"event", G_TYPE_STRING, "dvd-still",
"still-state", G_TYPE_BOOLEAN, FALSE, NULL);
still_event = gst_event_new_custom (GST_EVENT_CUSTOM_DOWNSTREAM, s);
+ /* If the segment was too short in a timed still, it may need extending */
+ if (segment->last_stop < segment->start + GST_SECOND * duration)
+ gst_segment_set_last_stop (segment, GST_FORMAT_TIME,
+ segment->start + (GST_SECOND * duration));
+
g_mutex_unlock (src->dvd_lock);
gst_pad_push_event (GST_BASE_SRC_PAD (src), still_event);
g_mutex_lock (src->dvd_lock);
@@ -2040,8 +2069,10 @@ rsn_dvdsrc_activate_nav_block (resinDvdSrc * src, GstBuffer * nav_buf)
/* highlight might change, let's check */
rsn_dvdsrc_update_highlight (src);
- if (src->highlight_event)
+ if (src->highlight_event && src->in_still_state) {
+ GST_LOG_OBJECT (src, "Signalling still condition due to highlight change");
g_cond_broadcast (src->still_cond);
+ }
}
static void
diff --git a/ext/resindvd/resindvdsrc.h b/ext/resindvd/resindvdsrc.h
index 0d883744..d30140ea 100644
--- a/ext/resindvd/resindvdsrc.h
+++ b/ext/resindvd/resindvdsrc.h
@@ -90,6 +90,9 @@ struct _resinDvdSrc
gboolean was_mouse_over;
+ /* Remaining time to wait in a timed still: */
+ GstClockTime still_time_remaining;
+
GstBuffer *alloc_buf;
GstBuffer *next_buf;
/* TRUE if the next_buf is a nav block that needs enqueueing */