summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiguel Freitas <miguelfreitas@users.sourceforge.net>2003-07-12 20:31:49 +0000
committerMiguel Freitas <miguelfreitas@users.sourceforge.net>2003-07-12 20:31:49 +0000
commit953fa1914a55c6f711578983b0fb0344e3b10fc6 (patch)
treeb63ecd972ac18c2351c6a478314d0904a2ac8b0f
parent0ec2496491e9921554799839a8c74a3aa4a1968d (diff)
downloadxine-lib-953fa1914a55c6f711578983b0fb0344e3b10fc6.tar.gz
xine-lib-953fa1914a55c6f711578983b0fb0344e3b10fc6.tar.bz2
reports the number of skipped/discarded frames
http://sourceforge.net/mailarchive/forum.php?thread_id=2753813&forum_id=7131 CVS patchset: 5155 CVS date: 2003/07/12 20:31:49
-rw-r--r--include/xine.h.in19
-rw-r--r--src/xine-engine/video_out.c78
2 files changed, 89 insertions, 8 deletions
diff --git a/include/xine.h.in b/include/xine.h.in
index 1c5ae1650..d0743f756 100644
--- a/include/xine.h.in
+++ b/include/xine.h.in
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xine.h.in,v 1.89 2003/06/18 12:59:39 mroi Exp $
+ * $Id: xine.h.in,v 1.90 2003/07/12 20:31:49 miguelfreitas Exp $
*
* public xine-lib (libxine) interface and documentation
*
@@ -813,6 +813,8 @@ const char *xine_get_meta_info (xine_stream_t *stream, int info);
#define XINE_STREAM_INFO_MAX_AUDIO_CHANNEL 24
#define XINE_STREAM_INFO_MAX_SPU_CHANNEL 25
#define XINE_STREAM_INFO_AUDIO_MODE 26
+#define XINE_STREAM_INFO_SKIPPED_FRAMES 27 /* for 1000 frames delivered */
+#define XINE_STREAM_INFO_DISCARDED_FRAMES 28 /* for 1000 frames delivered */
/* xine_get_meta_info */
#define XINE_META_INFO_TITLE 0
@@ -1256,6 +1258,7 @@ void xine_config_reset (xine_t *self);
#define XINE_EVENT_MRL_REFERENCE 9 /* demuxer->frontend: MRL reference(s) for the real stream */
#define XINE_EVENT_UI_NUM_BUTTONS 10 /* number of buttons for interactive menus */
#define XINE_EVENT_SPU_BUTTON 11 /* the mouse pointer enter/leave a button */
+#define XINE_EVENT_DROPPED_FRAMES 12 /* number of dropped frames is too high */
/* input events coming from frontend */
#define XINE_EVENT_INPUT_MOUSE_BUTTON 101
@@ -1501,6 +1504,20 @@ typedef struct {
#endif
+/* event XINE_EVENT_DROPPED_FRAMES is generated if libxine detects a
+ * high number of dropped frames (above configured thresholds). it can
+ * be used by the front end to warn about performance problems.
+ */
+typedef struct {
+ /* these values are given for 1000 frames delivered */
+ /* (that is, divide by 10 to get percentages) */
+ int skipped_frames;
+ int skipped_threshold;
+ int discarded_frames;
+ int discarded_threshold;
+} xine_dropped_frames_t;
+
+
/*
* Defined message types for XINE_EVENT_UI_MESSAGE
* This is the mechanism to report async errors from engine.
diff --git a/src/xine-engine/video_out.c b/src/xine-engine/video_out.c
index be977e1f8..ef4f3079f 100644
--- a/src/xine-engine/video_out.c
+++ b/src/xine-engine/video_out.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: video_out.c,v 1.164 2003/06/22 17:10:41 mroi Exp $
+ * $Id: video_out.c,v 1.165 2003/07/12 20:31:49 miguelfreitas Exp $
*
* frame allocation / queuing / scheduling / output functions
*/
@@ -76,6 +76,12 @@ typedef struct {
int num_frames_skipped;
int num_frames_discarded;
+ /* threshold for sending XINE_EVENT_DROPPED_FRAMES */
+ int warn_skipped_threshold;
+ int warn_discarded_threshold;
+ int warn_threshold_exceeded;
+ int warn_threshold_event_sent;
+
/* pts value when decoder delivered last video frame */
int64_t last_delivery_pts;
@@ -432,12 +438,59 @@ static int vo_frame_draw (vo_frame_t *img, xine_stream_t *stream) {
* performance measurement
*/
- if ((this->num_frames_delivered % 200) == 0
- && (this->num_frames_skipped || this->num_frames_discarded)) {
- xine_log(this->xine, XINE_LOG_MSG,
- _("%d frames delivered, %d frames skipped, %d frames discarded\n"),
- this->num_frames_delivered,
- this->num_frames_skipped, this->num_frames_discarded);
+ if ((this->num_frames_delivered % 200) == 0) {
+ int send_event;
+
+ if( (100 * this->num_frames_skipped / this->num_frames_delivered) >
+ this->warn_skipped_threshold ||
+ (100 * this->num_frames_discarded / this->num_frames_delivered) >
+ this->warn_discarded_threshold )
+ this->warn_threshold_exceeded++;
+ else
+ this->warn_threshold_exceeded = 0;
+
+ /* make sure threshold has being consistently exceeded - 5 times in a row
+ * (that is, this is not just a small burst of dropped frames).
+ */
+ send_event = (this->warn_threshold_exceeded == 5 &&
+ !this->warn_threshold_event_sent);
+ this->warn_threshold_event_sent += send_event;
+
+ pthread_mutex_lock(&this->streams_lock);
+ for (stream = xine_list_first_content(this->streams); stream;
+ stream = xine_list_next_content(this->streams)) {
+ stream->stream_info[XINE_STREAM_INFO_SKIPPED_FRAMES] =
+ 1000 * this->num_frames_skipped / this->num_frames_delivered;
+ stream->stream_info[XINE_STREAM_INFO_DISCARDED_FRAMES] =
+ 1000 * this->num_frames_discarded / this->num_frames_delivered;
+
+ /* we send XINE_EVENT_DROPPED_FRAMES to frontend to warn that
+ * number of skipped or discarded frames is too high.
+ */
+ if( send_event ) {
+ xine_event_t event;
+ xine_dropped_frames_t data;
+
+ event.type = XINE_EVENT_DROPPED_FRAMES;
+ event.stream = stream;
+ event.data = &data;
+ event.data_length = sizeof(data);
+ data.skipped_frames = stream->stream_info[XINE_STREAM_INFO_SKIPPED_FRAMES];
+ data.skipped_threshold = this->warn_skipped_threshold * 10;
+ data.discarded_frames = stream->stream_info[XINE_STREAM_INFO_DISCARDED_FRAMES];
+ data.discarded_threshold = this->warn_discarded_threshold * 10;
+ xine_event_send(stream, &event);
+ }
+ }
+ pthread_mutex_unlock(&this->streams_lock);
+
+
+ if( this->num_frames_skipped || this->num_frames_discarded ) {
+ xine_log(this->xine, XINE_LOG_MSG,
+ _("%d frames delivered, %d frames skipped, %d frames discarded\n"),
+ this->num_frames_delivered,
+ this->num_frames_skipped, this->num_frames_discarded);
+ }
this->num_frames_delivered = 0;
this->num_frames_discarded = 0;
@@ -1117,6 +1170,7 @@ static void vo_open (xine_video_port_t *this_gen, xine_stream_t *stream) {
this->video_opened = 1;
this->discard_frames = 0;
this->last_delivery_pts = 0;
+ this->warn_threshold_event_sent = this->warn_threshold_exceeded = 0;
if (!this->overlay_enabled && stream->spu_channel_user > -2)
/* enable overlays if our new stream might want to show some */
this->overlay_enabled = 1;
@@ -1489,6 +1543,16 @@ xine_video_port_t *vo_new_port (xine_t *xine, vo_driver_t *driver,
img);
}
+ this->warn_skipped_threshold =
+ xine->config->register_num (xine->config, "video.warn_skipped_threshold", 10,
+ "send event to front end if percentage of skipped frames exceed this value",
+ NULL, 20, NULL, NULL);
+ this->warn_discarded_threshold =
+ xine->config->register_num (xine->config, "video.warn_discarded_threshold", 10,
+ "send event to front end if percentage of discarded frames exceed this value",
+ NULL, 20, NULL, NULL);
+
+
if (grabonly) {
this->video_loop_running = 0;