summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Lampard <mlampard@users.sourceforge.net>2001-10-28 11:14:39 +0000
committerMike Lampard <mlampard@users.sourceforge.net>2001-10-28 11:14:39 +0000
commitc60b50b3c3208741cfbd6e689f683757633da5fb (patch)
tree11f9bc7eb9784fedf1448105e19cc34f906bd4a3 /src
parenta28c896a61f11557d9065def54a90ca3eba1ea37 (diff)
downloadxine-lib-c60b50b3c3208741cfbd6e689f683757633da5fb.tar.gz
xine-lib-c60b50b3c3208741cfbd6e689f683757633da5fb.tar.bz2
in order for av sync to be correct with still menus, we need to act like a
real plugin.. Partial I-Frame FFWD implemented also... CVS patchset: 899 CVS date: 2001/10/28 11:14:39
Diffstat (limited to 'src')
-rw-r--r--src/dxr3/dxr3_decoder.c117
-rw-r--r--src/dxr3/video_out_dxr3.c105
2 files changed, 183 insertions, 39 deletions
diff --git a/src/dxr3/dxr3_decoder.c b/src/dxr3/dxr3_decoder.c
index 16abf4841..054eeb28c 100644
--- a/src/dxr3/dxr3_decoder.c
+++ b/src/dxr3/dxr3_decoder.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: dxr3_decoder.c,v 1.22 2001/10/27 17:33:28 mlampard Exp $
+ * $Id: dxr3_decoder.c,v 1.23 2001/10/28 11:14:39 mlampard Exp $
*
* dxr3 video and spu decoder plugin. Accepts the video and spu data
* from XINE and sends it directly to the corresponding dxr3 devices.
@@ -47,10 +47,17 @@
#define DEFAULT_DEV "/dev/em8300"
static char *devname;
+#define MV_COMMAND 0
+#define MV_STATUS 1
+#ifndef MVCOMMAND_SCAN
+ #define MVCOMMAND_SCAN 4
+#endif
+
typedef struct dxr3_decoder_s {
video_decoder_t video_decoder;
vo_instance_t *video_out;
-
+
+ int fd_control;
int fd_video;
int last_pts;
scr_plugin_t *scr;
@@ -58,6 +65,7 @@ typedef struct dxr3_decoder_s {
int width;
int height;
int aspect;
+ int duration;
} dxr3_decoder_t;
static int dxr3_tested = 0;
@@ -86,6 +94,15 @@ static void dxr3_presence_test()
dxr3_ok = 1;
}
+static int dxr3_mvcommand(int fd_control, int command) {
+ em8300_register_t regs;
+ regs.microcode_register=1; /* Yes, this is a MC Reg */
+ regs.reg = MV_COMMAND;
+ regs.val=command;
+
+ return (ioctl(fd_control, EM8300_IOCTL_WRITEREG, &regs));
+}
+
typedef struct dxr3scr_s {
scr_plugin_t scr;
int fd_control;
@@ -97,32 +114,49 @@ static int dxr3scr_get_priority (scr_plugin_t *scr) {
return self->priority;
}
+int scanning_mode=0;
static int dxr3scr_set_speed (scr_plugin_t *scr, int speed) {
dxr3scr_t *self = (dxr3scr_t*) scr;
uint32_t em_speed;
-
+ int playmode;
+
switch(speed){
case SPEED_PAUSE:
em_speed = 0;
+ playmode=MVCOMMAND_PAUSE;
break;
case SPEED_SLOW_4:
em_speed = 0x900/4;
+ playmode=MVCOMMAND_START;
break;
case SPEED_SLOW_2:
em_speed = 0x900/2;
+ playmode=MVCOMMAND_START;
break;
case SPEED_NORMAL:
em_speed = 0x900;
+ playmode=MVCOMMAND_START;
break;
case SPEED_FAST_2:
em_speed = 0x900*2;
+ playmode=MVCOMMAND_SCAN;
break;
case SPEED_FAST_4:
em_speed = 0x900*4;
+ playmode=MVCOMMAND_SCAN;
break;
default:
em_speed = 0;
+ playmode = MVCOMMAND_PAUSE;
}
+ if(em_speed>0x900)
+ scanning_mode=1;
+ else
+ scanning_mode=0;
+
+ if(dxr3_mvcommand(self->fd_control,playmode))
+ fprintf(stderr, "dxr3scr: failed to playmode (%s)\n", strerror(errno));
+
if (ioctl(self->fd_control, EM8300_IOCTL_SCR_SETSPEED, &em_speed))
fprintf(stderr, "dxr3scr: failed to set speed (%s)\n", strerror(errno));
@@ -135,6 +169,7 @@ static void dxr3scr_adjust (scr_plugin_t *scr, uint32_t vpts) {
if (ioctl(self->fd_control, EM8300_IOCTL_SCR_SET, &vpts))
fprintf(stderr, "dxr3scr: adjust failed (%s)\n", strerror(errno));
+
}
static void dxr3scr_start (scr_plugin_t *scr, uint32_t start_vpts) {
@@ -204,6 +239,12 @@ static void dxr3_init (video_decoder_t *this_gen, vo_instance_t *video_out)
return;
}
+ if ((this->fd_control = open (devname, O_WRONLY)) < 0) {
+ fprintf(stderr, "dxr3: Failed to open control device %s (%s)\n",
+ devname, strerror(errno));
+ return;
+ }
+
video_out->open(video_out);
this->video_out = video_out;
@@ -227,6 +268,9 @@ static void find_aspect(dxr3_decoder_t *this, uint8_t * buffer)
int old_w = this->width;
int old_a = this->aspect;
+ /* framerate code... needed for metronom */
+ int framecode = buffer[HEADER_OFFSET+3] & 15;
+
/* grab video resolution and aspect ratio from the stream */
this->height = (buffer[HEADER_OFFSET+0] << 16) |
(buffer[HEADER_OFFSET+1] << 8) |
@@ -235,12 +279,33 @@ static void find_aspect(dxr3_decoder_t *this, uint8_t * buffer)
this->height = ((this->height & 0xfff) + 15) & ~15;
this->aspect = buffer[HEADER_OFFSET+3] >> 4;
+ switch (framecode){
+ case 2:
+ this->duration=90000/24;
+ break;
+ case 3:
+ this->duration=90000/25;
+ break;
+ case 5:
+ this->duration=90000/30;
+ break;
+ case 6:
+ this->duration=90000/50;
+ break;
+ case 8:
+ this->duration=90000/60;
+ break;
+ default:
+ this->duration=90000/25; /* PAL 25fps */
+ break;
+ }
+
/* and ship the data if different ... appeasing any other vo plugins
that are active ... */
if (old_h!=this->height || old_w!=this->width || old_a!=this->aspect)
this->video_out->get_frame(this->video_out,
this->width,this->height,this->aspect,
- IMGFMT_YV12, 1, 6667); /* dxr3_decoder = 6667 */
+ IMGFMT_YV12, this->duration, 6667); /* dxr3_decoder = 6667 */
}
}
@@ -249,28 +314,44 @@ static void dxr3_decode_data (video_decoder_t *this_gen, buf_element_t *buf)
dxr3_decoder_t *this = (dxr3_decoder_t *) this_gen;
ssize_t written;
- /* Increment vpts for videofill packets to keep in sync with audio...
- fixes issues with the Matrix etc... */
- if(buf->type == BUF_VIDEO_FILL) {
- int vpts;
- static int videofill_count=0;
- /* pthread_mutex_lock (&this->video_decoder.metronom->lock); */
- videofill_count += this->video_decoder.metronom->pts_per_frame +
- this->video_decoder.metronom->video_pts_delta;
- /* pthread_mutex_unlock (&this->video_decoder.metronom->lock);*/
- vpts = this->video_decoder.metronom->got_video_frame(
- this->video_decoder.metronom, videofill_count);
- return;
- }
/* The dxr3 does not need the preview-data */
if (buf->decoder_info[0] == 0) return;
+ /* Act like other plugins... keeps metronom in check :) */
+ if(buf->type == BUF_VIDEO_FILL) {
+ vo_frame_t *img;
+ img = this->video_out->get_frame (this->video_out,
+ this->width,
+ this->height,
+ this->aspect,
+ IMGFMT_YV12,
+ this->duration,
+ VO_BOTH_FIELDS);
+
+ img->draw(img);
+ img->free(img);
+ return;
+ }
+
+ if(scanning_mode){
+ vo_frame_t *img;
+ img = this->video_out->get_frame (this->video_out,
+ this->width,
+ this->height,
+ this->aspect,
+ IMGFMT_YV12,
+ this->duration,
+ VO_BOTH_FIELDS);
+
+ img->draw(img);
+ img->free(img);
+ }
+
if (buf->PTS) {
int vpts;
vpts = this->video_decoder.metronom->got_video_frame(
this->video_decoder.metronom, buf->PTS);
-
if (this->last_pts < vpts)
{
this->last_pts = vpts;
diff --git a/src/dxr3/video_out_dxr3.c b/src/dxr3/video_out_dxr3.c
index 38560a7dd..d8deb8f3f 100644
--- a/src/dxr3/video_out_dxr3.c
+++ b/src/dxr3/video_out_dxr3.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_dxr3.c,v 1.15 2001/10/24 15:53:23 mlampard Exp $
+ * $Id: video_out_dxr3.c,v 1.16 2001/10/28 11:14:39 mlampard Exp $
*
* Dummy video out plugin for the dxr3. Is responsible for setting
* tv_mode, bcs values and the aspectratio.
@@ -77,6 +77,26 @@ typedef struct dxr3_driver_s {
int *dest_x, int *dest_y, int *dest_height, int *dest_width);
} dxr3_driver_t;
+typedef struct dxr3_frame_s {
+ vo_frame_t vo_frame;
+ int width, height;
+ uint8_t *mem[3];
+ int format;
+}dxr3_frame_t;
+
+static void *malloc_aligned (size_t alignment, size_t size, void **mem) {
+ char *aligned;
+
+ aligned = malloc (size+alignment);
+ *mem = aligned;
+
+ while ((int) aligned % alignment)
+ aligned++;
+
+ return aligned;
+}
+
+
static int dxr3_set_property (vo_driver_t *this_gen, int property, int value);
static void dxr3_overlay_adapt_area(dxr3_driver_t *this,
@@ -178,31 +198,63 @@ static void dummy_frame_field (vo_frame_t *vo_img, int which_field)
fprintf(stderr, "dxr3_vo: dummy_frame_field called!\n");
}
-static void dummy_frame_dispose (vo_frame_t *frame)
+static void dummy_frame_dispose (vo_frame_t *frame_gen)
{
- free(frame);
+ dxr3_frame_t *frame = (dxr3_frame_t *) frame_gen;
+
+ if (frame->mem[0])
+ free (frame->mem[0]);
+ if (frame->mem[1])
+ free (frame->mem[1]);
+ if (frame->mem[2])
+ free (frame->mem[2]);
+ free(frame);
}
static vo_frame_t *dxr3_alloc_frame (vo_driver_t *this_gen)
{
- vo_frame_t *frame;
-
- frame = (vo_frame_t *) malloc (sizeof (vo_frame_t));
- memset (frame, 0, sizeof(vo_frame_t));
-
- frame->copy = dummy_frame_copy;
- frame->field = dummy_frame_field;
- frame->dispose = dummy_frame_dispose;
-
- return frame;
+ dxr3_frame_t *frame;
+
+ frame = (dxr3_frame_t *) malloc (sizeof (dxr3_frame_t));
+ memset (frame, 0, sizeof(dxr3_frame_t));
+
+ frame->vo_frame.copy = dummy_frame_copy;
+ frame->vo_frame.field = dummy_frame_field;
+ frame->vo_frame.dispose = dummy_frame_dispose;
+
+ return (vo_frame_t*) frame;
}
+
static void dxr3_update_frame_format (vo_driver_t *this_gen,
- vo_frame_t *frame,
+ vo_frame_t *frame_gen,
uint32_t width, uint32_t height,
int ratio_code, int format, int flags)
{
dxr3_driver_t *this = (dxr3_driver_t *) this_gen;
+ dxr3_frame_t *frame = (dxr3_frame_t *) frame_gen;
+ int image_size;
+
+ if ((frame->width != width) || (frame->height != height)
+ || (frame->format != format)) {
+
+ if (frame->mem[0]) {
+ free (frame->mem[0]);
+ frame->mem[0] = NULL;
+ }
+ if (frame->mem[1]) {
+ free (frame->mem[1]);
+ frame->mem[1] = NULL;
+ }
+ if (frame->mem[2]) {
+ free (frame->mem[2]);
+ frame->mem[2] = NULL;
+ }
+
+ frame->width = width;
+ frame->height = height;
+ frame->format = format;
+
if(flags == 6667){ /* dxr3 flag anyone? :) */
int aspect;
this->video_width = width;
@@ -216,18 +268,29 @@ static void dxr3_update_frame_format (vo_driver_t *this_gen,
if(this->aspectratio!=aspect)
dxr3_set_property ((vo_driver_t*)this, VO_PROP_ASPECT_RATIO, aspect);
}
- else{
- /* inform the user that we don't do non-mpeg streams and exit nicely */
- fprintf(stderr,"\nDxr3 videoout plugin doesn't currently play non-mpeg streams\n");
- fprintf(stderr,"Please try xine with -VXv or -VShm for this stream. Exiting...\n");
- exit(1);
+
+ if (format == IMGFMT_YV12) {
+ image_size = width * height;
+ frame->vo_frame.base[0] = malloc_aligned(16,image_size,
+ (void**) &frame->mem[0]);
+ frame->vo_frame.base[1] = malloc_aligned(16,image_size/4,
+ (void**) &frame->mem[1]);
+ frame->vo_frame.base[2] = malloc_aligned(16,image_size/4,
+ (void**) &frame->mem[2]);
+ }else if (format == IMGFMT_YUY2) {
+ printf("DXR3_Overlay: this plugin doesn't support AVIs\n");
+ printf("DXR3_Overlay: Exiting......");
+ exit(1);
}
+ }
}
-static void dxr3_display_frame (vo_driver_t *this_gen, vo_frame_t *frame)
+static void dxr3_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen)
{
/* dxr3_driver_t *this = (dxr3_driver_t *) this_gen; */
- fprintf(stderr, "dxr3_vo: dummy function dxr3_display_frame called!\n");
+ dxr3_frame_t *frame = (dxr3_frame_t *) frame_gen;
+
+ frame->vo_frame.displayed (&frame->vo_frame);
}
static void dxr3_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen,