[Mplayer-cvslog] CVS: main/libvo vo_dxr3.c,1.112,1.113
David Holm CVS
mswitch at mplayerhq.hu
Wed Nov 27 00:32:47 CET 2002
Update of /cvsroot/mplayer/main/libvo
In directory mail:/var/tmp.root/cvs-serv32014/libvo
Modified Files:
vo_dxr3.c
Log Message:
10l found by Zoltan
Index: vo_dxr3.c
===================================================================
RCS file: /cvsroot/mplayer/main/libvo/vo_dxr3.c,v
retrieving revision 1.112
retrieving revision 1.113
diff -u -r1.112 -r1.113
--- vo_dxr3.c 26 Nov 2002 23:23:17 -0000 1.112
+++ vo_dxr3.c 26 Nov 2002 23:32:43 -0000 1.113
@@ -6,11 +6,11 @@
*/
/* ChangeLog added 2002-01-10
- * 2002-01-03:
+ * 2002-11-03:
* Cleaned up syncing code and renamed setup variables so
* they can be accessed from the GUI.
*
- * 2002-01-02:
+ * 2002-11-02:
* Added native overlay support, activate with :overlay
* you have to run dxr3view to modify settings (or manually
* edit the files in ~/.overlay.
@@ -95,7 +95,11 @@
* find any inconcistencies.
*/
+#ifdef __FreeBSD__
+#include <em8300.h>
+#else
#include <linux/em8300.h>
+#endif
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -243,8 +247,28 @@
#endif
+/* Internal variables used in syncing */
+static int last_pts, frame_last_pts = -1;
+static int64_t pts64;
+static int64_t frame_pts64;
+#define RESYNC_WINDOW_SIZE 50
+static int resync_window = 0;
+#define SKIP_TOLERANCE 200
+static int skip_count = 0;
+
+
/* Functions for working with the em8300's internal clock */
-/* End of internal clock functions */
+struct {
+ int64_t offset;
+ uint32_t last_pts;
+} scr_s;
+
+static void scr_reset();
+static void scr_start(int64_t vpts);
+static int64_t scr_get_time();
+static void scr_adjust(int64_t vpts);
+
+
static uint32_t control(uint32_t request, void *data, ...)
{
@@ -279,37 +303,38 @@
#endif
case VOCTRL_RESUME:
if (dxr3_newsync) {
- ioctl(fd_control, EM8300_IOCTL_SCR_GET, &ioval);
- pts_offset = vo_pts - (ioval << 1);
- if (pts_offset < 0) {
+ pts_offset = vo_pts - scr_get_time();
+ if (pts_offset < 0) {
pts_offset = 0;
}
}
-
+
if (dxr3_prebuf) {
- ioval = EM8300_PLAYMODE_PLAY;
+ /*frame_last_pts = -1;
+ last_pts = vo_pts;
+ scr_adjust(pts64);*/
+ /*ioval = EM8300_PLAYMODE_PLAY;
if (ioctl(fd_control, EM8300_IOCTL_SET_PLAYMODE, &ioval) < 0) {
printf("VO: [dxr3] Unable to set playmode!\n");
- }
+ }*/
}
return VO_TRUE;
case VOCTRL_PAUSE:
if (dxr3_prebuf) {
+ /* Pausing will also stop the internal clock, avoid it
ioval = EM8300_PLAYMODE_PAUSED;
if (ioctl(fd_control, EM8300_IOCTL_SET_PLAYMODE, &ioval) < 0) {
printf("VO: [dxr3] Unable to set playmode!\n");
- }
+ }*/
}
return VO_TRUE;
case VOCTRL_RESET:
- if (dxr3_prebuf) {
- close(fd_video);
- fd_video = open(fdv_name, O_WRONLY);
- close(fd_spu);
- fd_spu = open(fds_name, O_WRONLY);
- fsync(fd_video);
- fsync(fd_spu);
- }
+ close(fd_video);
+ fd_video = open(fdv_name, O_WRONLY);
+ close(fd_spu);
+ fd_spu = open(fds_name, O_WRONLY);
+ fsync(fd_video);
+ fsync(fd_spu);
return VO_TRUE;
case VOCTRL_QUERY_FORMAT:
{
@@ -319,8 +344,8 @@
return 0;
flag = VFCAP_CSP_SUPPORTED | VFCAP_CSP_SUPPORTED_BY_HW | VFCAP_SPU;
- if (dxr3_prebuf)
- flag |= VFCAP_TIMER;
+ /*if (dxr3_prebuf)
+ flag |= VFCAP_TIMER;*/
return flag;
}
case VOCTRL_SET_EQUALIZER:
@@ -393,7 +418,7 @@
static uint32_t config(uint32_t width, uint32_t height, uint32_t d_width, uint32_t d_height, uint32_t fullscreen, char *title, uint32_t format)
{
- int tmp1, tmp2, size;
+ int tmp1, tmp2;
em8300_register_t reg;
extern float monitor_aspect;
@@ -409,11 +434,7 @@
}
/* Set the playmode to play (just in case another app has set it to something else) */
-#ifdef EM8300_PLAYMODE_SYNC
- ioval = EM8300_PLAYMODE_SYNC;
-#else
ioval = EM8300_PLAYMODE_PLAY;
-#endif
if (ioctl(fd_control, EM8300_IOCTL_SET_PLAYMODE, &ioval) < 0) {
printf("VO: [dxr3] Unable to set playmode!\n");
}
@@ -422,7 +443,7 @@
#ifdef MVCOMMAND_SYNC
reg.microcode_register = 1;
reg.reg = 0;
- reg.val = MVCOMMAND_START;
+ reg.val = MVCOMMAND_SYNC;
ioctl(fd_control, EM8300_IOCTL_WRITEREG, ®);
#endif
@@ -524,11 +545,7 @@
unsigned long xswamask;
Colormap cmap;
XColor key_color;
- Window junkwindow;
- Screen *scr;
int depth, red_shift, red_prec, green_shift, green_prec, blue_shift, blue_prec, acq_color;
- em8300_overlay_screen_t ovlscr;
- em8300_attribute_t ovlattr;
vo_dx = (vo_screenwidth - d_width) / 2;
vo_dy = (vo_screenheight - d_height) / 2;
@@ -563,10 +580,10 @@
hint.base_height = hint.height = vo_dheight;
hint.flags = PPosition | PSize;
vo_window = XCreateWindow(mDisplay, mRootWin, hint.x, hint.y, hint.width, hint.height, 0, depth, CopyFromParent, vinfo.visual, xswamask, &xswa);
- vo_x11_classhint(mDisplay, vo_window, "Viewing Window");
+ vo_x11_classhint(mDisplay, vo_window, "DXR3 Overlay");
vo_hidecursor(mDisplay, vo_window);
vo_x11_selectinput_witherr(mDisplay, vo_window, StructureNotifyMask | KeyPressMask | PropertyChangeMask);
- XSetStandardProperties(mDisplay, vo_window, "DXR3 Overlay", "DXR3 Overlay", None, NULL, 0, &hint);
+ XSetStandardProperties(mDisplay, vo_window, title, title, None, NULL, 0, &hint);
XSetWMNormalHints(mDisplay, vo_window, &hint);
XMapWindow(mDisplay, vo_window);
XFlush(mDisplay);
@@ -598,7 +615,7 @@
acq_color = ((key_color.red / 256) << 16) | ((key_color.green / 256) << 8) | key_color.blue;
if (key_color.pixel != KEY_COLOR) {
- printf("VO: [dxr3] Unable to allocate exact keycolor, using closest match (%0x)\n", key_color.pixel);
+ printf("VO: [dxr3] Unable to allocate exact keycolor, using closest match (%0x)\n", (unsigned int) key_color.pixel);
}
/* Set keycolor and activate overlay */
@@ -610,6 +627,25 @@
}
#endif
+ /* Set up timers
+ * This must be the last thing we do otherwise the
+ * timers will be off when we start sending frames
+ * causing a resync the first thing we do, which
+ * hopefully isn't necessary.
+ */
+ last_pts = vo_pts;
+ scr_reset();
+ frame_pts64 = pts64 = vo_pts;
+ scr_start(pts64);
+
+ if (dxr3_newsync) {
+ ioval = scr_get_time();
+ pts_offset = vo_pts - ioval;
+ if (pts_offset < 0) {
+ pts_offset = 0;
+ }
+ }
+
return 0;
}
@@ -683,23 +719,117 @@
#endif
}
-
static uint32_t draw_frame(uint8_t * src[])
{
vo_mpegpes_t *p = (vo_mpegpes_t *) src[0];
-
+ unsigned int pts;
+ uint8_t *c = p->data;
+
#ifdef SPU_SUPPORT
+ /* This is just a subpic, don't mess with timestamps */
if (p->id == 0x20) {
write(fd_spu, p->data, p->size);
- } else
+ return 0;
+ }
#endif
- write(fd_video, p->data, p->size);
+
+ /* If seek occured, reset device */
+ if (vo_pts <= 0) {
+ printf("Something happened, reset\n");
+ control(VOCTRL_RESET, NULL);
+ frame_last_pts = -1;
+ scr_adjust(frame_pts64);
+ }
+
+ /* Update frame timestamp */
+ if (frame_last_pts < 0) {
+ frame_last_pts = p->timestamp;
+ }
+ frame_pts64 += p->timestamp - frame_last_pts;
+
+ if (dxr3_prebuf) {
+ int64_t delay = frame_pts64 - scr_get_time();
+
+ if ((delay > 0) && (delay < 90000)) {
+ /* Frame is in sync with the em8300 */
+ uint32_t vpts32 = frame_pts64;
+
+ if (resync_window == 0) {
+ /* Video has been synced, lock the
+ * stream by activating the em8300
+ * syncer.
+ */
+ em8300_register_t reg;
+ printf("Video synced, lock stream\n");
+ reg.microcode_register = 1;
+ reg.reg = 0;
+ reg.val = MVCOMMAND_SYNC;
+ if (ioctl(fd_control, EM8300_IOCTL_WRITEREG, ®) < 0) {
+ printf("VO: [dxr3] Unable to lock stream!\n");
+ }
+ resync_window = -RESYNC_WINDOW_SIZE;
+ }
+
+ if (resync_window != 0 && resync_window > -RESYNC_WINDOW_SIZE) {
+ resync_window--;
+ }
+
+ if (ioctl(fd_video, EM8300_IOCTL_VIDEO_SETPTS, &vpts32) < 0) {
+ printf("VO: [dxr3] Unable to set video pts!\n");
+ }
+ /* Do some cpu throttling to avoid killing the cpu */
+ //usleep((delay / 0.09) / 2);
+ } else if (delay < 0) {
+ /* We are behind, count frames and start resync
+ * if this goes on for too long.
+ */
+ skip_count++;
+ if (skip_count > SKIP_TOLERANCE) {
+ scr_adjust(frame_pts64);
+ skip_count = 0;
+ resync_window = 0;
+ }
+
+ if (resync_window == 0) {
+ /* Sync was lost, unlock the stream
+ * and start recalibration
+ */
+ em8300_register_t reg;
+ printf("Sync lost, unlock stream\n");
+ reg.microcode_register = 1;
+ reg.reg = 0;
+ reg.val = MVCOMMAND_START;
+ if (ioctl(fd_control, EM8300_IOCTL_WRITEREG, ®) < 0) {
+ printf("VO: [dxr3] Unable to release stream!\n");
+ }
+ resync_window = RESYNC_WINDOW_SIZE;
+ }
+ if ((resync_window) != 0 && (resync_window < RESYNC_WINDOW_SIZE)) {
+ resync_window++;
+ }
+ } else if (delay >= 90000) {
+ printf("VO: [dxr3] Warning, pts is %.02f seconds ahead of time!\n", delay / 90000.0);
+ }
+ }
+
+ if (write(fd_video, p->data, p->size) < p->size) {
+ printf("VO: [dxr3] Lost some bytes\n");
+ }
+
+ frame_last_pts = p->timestamp;
+
return 0;
}
static void flip_page(void)
{
#ifdef HAVE_X11
+ /* Update current timestamp */
+ if (vo_pts <= 0) {
+ last_pts = vo_pts;
+ }
+ pts64 += vo_pts - last_pts;
+
if (dxr3_overlay) {
int event = vo_x11_check_events(mDisplay);
if (event & VO_EVENT_RESIZE) {
@@ -720,29 +850,22 @@
#endif
if (dxr3_newsync) {
- ioctl(fd_control, EM8300_IOCTL_SCR_GET, &ioval);
- ioval <<= 1;
+ ioval = scr_get_time();
if (vo_pts == 0) {
ioval = 0;
- ioctl(fd_control, EM8300_IOCTL_SCR_SET, &ioval);
+ scr_adjust(pts64);
pts_offset = 0;
} else if ((vo_pts - pts_offset) < (ioval - 7200) || (vo_pts - pts_offset) > (ioval + 7200)) {
- ioval = (vo_pts + pts_offset) >> 1;
- ioctl(fd_control, EM8300_IOCTL_SCR_SET, &ioval);
- ioctl(fd_control, EM8300_IOCTL_SCR_GET, &ioval);
- pts_offset = vo_pts - (ioval << 1);
- if (pts_offset < 0) {
- pts_offset = 0;
- }
+ ioval = vo_pts + pts_offset;
+ scr_adjust(ioval);
}
ioval = vo_pts + pts_offset;
ioctl(fd_video, EM8300_IOCTL_SPU_SETPTS, &ioval);
ioctl(fd_video, EM8300_IOCTL_VIDEO_SETPTS, &ioval);
prev_pts = vo_pts;
- } else if (dxr3_prebuf) {
- ioctl(fd_spu, EM8300_IOCTL_SPU_SETPTS, &vo_pts);
- ioctl(fd_video, EM8300_IOCTL_VIDEO_SETPTS, &vo_pts);
}
+
+ last_pts = vo_pts;
}
static uint32_t draw_slice(uint8_t *srcimg[], int stride[], int w, int h, int x0, int y0)
@@ -918,16 +1041,84 @@
}
#endif
- if (dxr3_newsync) {
- ioctl(fd_control, EM8300_IOCTL_SCR_GET, &ioval);
- pts_offset = vo_pts - (ioval << 1);
- if (pts_offset < 0) {
- pts_offset = 0;
- }
+ return 0;
+}
+
+
+/* em8300 clock handler */
+static void scr_reset()
+{
+ scr_s.last_pts = 0;
+ scr_s.offset = 0;
+}
+
+static void scr_start(int64_t vpts)
+{
+ uint32_t vpts32 = vpts >> 1;
+
+ scr_s.last_pts = vpts32;
+ scr_s.offset = vpts - ((int64_t) vpts32 << 1);
+
+ if (ioctl(fd_control, EM8300_IOCTL_SCR_SET, &vpts32) < 0) {
+ printf("VO: [dxr3] Unable to set scr!\n");
+ }
+
+ vpts32 = 0x900;
+ if (ioctl(fd_control, EM8300_IOCTL_SCR_SETSPEED, &vpts32) < 0) {
+ printf("VO: [dxr3] Unable to set em8300 clockspeed!\n");
}
+}
- return 0;
+static int64_t scr_get_time()
+{
+ uint32_t pts;
+ int64_t current;
+
+ if (ioctl(fd_control, EM8300_IOCTL_SCR_GET, &pts) < 0) {
+ printf("VO: [dxr3] Unable to get scr!\n");
+ }
+
+ if (scr_s.last_pts > 0xf0000000 && pts < 0x10000000) {
+ scr_s.offset += (int64_t) 1 << 33;
+ }
+
+ if (pts == 0) {
+ printf("VO: [dxr3] Warning, returned pts is 0!\n");
+ }
+
+ scr_s.last_pts = pts;
+ current = ((int64_t) pts << 1) + scr_s.offset;
+
+ return current;
+}
+
+static void scr_adjust(int64_t vpts)
+{
+ uint32_t current_pts32;
+ int32_t offset32;
+
+ if (ioctl(fd_control, EM8300_IOCTL_SCR_GET, ¤t_pts32) < 0) {
+ printf("VO: [dxr3] Unable to get scr!\n");
+ }
+
+ scr_s.last_pts = current_pts32;
+ scr_s.offset = vpts - ((int64_t) current_pts32 << 1);
+ offset32 = scr_s.offset / 4;
+
+ if (offset32 < (-7200 / 4) || offset32 > (7200 / 4)) {
+ uint32_t vpts32 = vpts >> 1;
+
+ if (ioctl(fd_control, EM8300_IOCTL_SCR_SET, &vpts32) < 0) {
+ printf("VO: [dxr3] Unable to set scr!\n");
+ }
+
+ scr_s.last_pts = vpts32;
+ scr_s.offset = vpts - ((int64_t) vpts32 << 1);
+ }
}
+/* End of em8300 clock handler */
+
+
/* Begin overlay.c */
static int update_parameters(overlay_t *o)
More information about the MPlayer-cvslog
mailing list