diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dxr3/Makefile.am | 3 | ||||
-rw-r--r-- | src/dxr3/dxr3_decode_video.c | 48 | ||||
-rw-r--r-- | src/dxr3/dxr3_mpeg_encoders.c | 12 | ||||
-rw-r--r-- | src/dxr3/dxr3_scr.c | 10 | ||||
-rw-r--r-- | src/dxr3/dxr3_scr.h | 4 | ||||
-rw-r--r-- | src/dxr3/video_out_dxr3.c | 81 | ||||
-rw-r--r-- | src/dxr3/video_out_dxr3.h | 11 | ||||
-rw-r--r-- | src/libffmpeg/xine_encoder.c | 11 |
8 files changed, 105 insertions, 75 deletions
diff --git a/src/dxr3/Makefile.am b/src/dxr3/Makefile.am index b5e219a2f..4fbe6b306 100644 --- a/src/dxr3/Makefile.am +++ b/src/dxr3/Makefile.am @@ -21,7 +21,7 @@ endif lib_LTLIBRARIES = $(dxr3_modules) -xineplug_decode_dxr3_video_la_SOURCES = dxr3_decode_video.c dxr3_scr.c +xineplug_decode_dxr3_video_la_SOURCES = dxr3_decode_video.c xineplug_decode_dxr3_video_la_LIBADD = $(XINE_LIB) xineplug_decode_dxr3_video_la_LDFLAGS = -avoid-version -module @@ -40,6 +40,7 @@ xineplug_vo_out_dxr3_la_SOURCES = \ alphablend.c \ dxr3_mpeg_encoders.c \ dxr3_spu_encoder.c \ + dxr3_scr.c \ video_out_dxr3.c xineplug_vo_out_dxr3_la_LIBADD = $(link_fame) $(link_rte) $(link_x_libs) $(XINE_LIB) diff --git a/src/dxr3/dxr3_decode_video.c b/src/dxr3/dxr3_decode_video.c index 143094054..ab2477cf2 100644 --- a/src/dxr3/dxr3_decode_video.c +++ b/src/dxr3/dxr3_decode_video.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_decode_video.c,v 1.40 2003/08/12 13:57:18 mroi Exp $ + * $Id: dxr3_decode_video.c,v 1.41 2003/09/11 10:01:03 mroi Exp $ */ /* dxr3 video decoder plugin. @@ -37,7 +37,6 @@ #include "xine_internal.h" #include "buffer.h" -#include "dxr3_scr.h" #include "video_out_dxr3.h" #include "dxr3.h" @@ -100,8 +99,7 @@ typedef struct dxr3_decoder_s { video_decoder_t video_decoder; dxr3_decoder_class_t *class; xine_stream_t *stream; - dxr3_scr_t *scr; - dxr3_driver_t *dxr3_vo; /* we need to talk to the dxr3 video out */ + dxr3_scr_t *scr; /* shortcut to the scr plugin in the dxr3 video out */ char devname[128]; char devnum[3]; @@ -195,7 +193,6 @@ static video_decoder_t *dxr3_open_plugin(video_decoder_class_t *class_gen, xine_ this->class = class; this->stream = stream; this->scr = NULL; - this->dxr3_vo = (dxr3_driver_t *)stream->video_driver; confstr = cfg->register_string(cfg, CONF_LOOKUP, CONF_DEFAULT, CONF_NAME, CONF_HELP, 0, NULL, NULL); strncpy(this->devname, confstr, 128); @@ -424,7 +421,7 @@ static void dxr3_decode_data(video_decoder_t *this_gen, buf_element_t *buf) if (this->skip_count) this->skip_count--; if (this->resync_window == 0 && this->scr && this->enhanced_mode && - !this->scr->scanning) { + !this->scr->scanning) { /* we are in sync, so we can lock the stream now */ #if LOG_VID printf("dxr3_decode_video: in sync, stream locked\n"); @@ -455,7 +452,7 @@ static void dxr3_decode_data(video_decoder_t *this_gen, buf_element_t *buf) if (this->scr && this->scr->scanning) this->resync_window = 0; if (this->resync_window == 0 && this->scr && this->enhanced_mode && - !this->scr->scanning) { + !this->scr->scanning) { /* switch off sync mode in the card to allow resyncing */ #if LOG_VID printf("dxr3_decode_video: out of sync, allowing stream resync\n"); @@ -485,36 +482,35 @@ static void dxr3_decode_data(video_decoder_t *this_gen, buf_element_t *buf) } if (buf->decoder_flags & BUF_FLAG_PREVIEW) return; - /* ensure video device is open + /* ensure video device is open * (we open it late because on occasion the dxr3 video out driver * wants to open it) + * also ensure the scr is running */ if (this->fd_video < 0) { + metronom_clock_t *clock = this->class->clock; char tmpstr[128]; + int64_t time; + + /* open the device for the decoder */ snprintf (tmpstr, sizeof(tmpstr), "%s_mv%s", this->devname, this->devnum); if ((this->fd_video = open(tmpstr, O_WRONLY | O_NONBLOCK)) < 0) { printf("dxr3_decode_video: Failed to open video device %s (%s)\n", tmpstr, strerror(errno)); return; } - } - - /* We may want to issue a SETPTS, so make sure the scr plugin - * is running and registered. Unfortuantely wa cannot do this - * earlier, because the dxr3's internal scr gets confused - * when started with a closed video device. Maybe this is a - * driver bug and gets fixed somewhen. FIXME: We might then - * want to move this code to dxr3_init. - */ - if (!this->scr) { - int64_t time; - - time = this->class->clock->get_current_time(this->class->clock); - this->scr = dxr3_scr_init(this->stream); + /* We may want to issue a SETPTS, so make sure the scr plugin + * is running and registered. Unfortuantely wa cannot do this + * earlier, because the dxr3's internal scr gets confused + * when started with a closed video device. Maybe this is a + * driver bug and gets fixed somewhen. FIXME: We might then + * want to do this entirely in the video out. + */ + this->scr = ((dxr3_driver_t *)this->stream->video_driver)->class->scr; + time = clock->get_current_time(clock); this->scr->scr_plugin.start(&this->scr->scr_plugin, time); - this->class->clock->register_scr( - this->class->clock, &this->scr->scr_plugin); + clock->register_scr(clock, &this->scr->scr_plugin); #if LOG_VID if (this->class->clock->scr_master == &this->scr->scr_plugin) printf("dxr3_decode_video: dxr3_scr plugin is master\n"); @@ -626,10 +622,8 @@ static void dxr3_dispose(video_decoder_t *this_gen) dxr3_decoder_t *this = (dxr3_decoder_t *)this_gen; metronom_clock_t *clock = this->class->clock; - if (this->scr) { + if (this->scr) clock->unregister_scr(clock, &this->scr->scr_plugin); - this->scr->scr_plugin.exit(&this->scr->scr_plugin); - } dxr3_mvcommand(this->fd_control, MVCOMMAND_FLUSHBUF); diff --git a/src/dxr3/dxr3_mpeg_encoders.c b/src/dxr3/dxr3_mpeg_encoders.c index 7f4279baa..1461bea7f 100644 --- a/src/dxr3/dxr3_mpeg_encoders.c +++ b/src/dxr3/dxr3_mpeg_encoders.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_mpeg_encoders.c,v 1.12 2003/05/31 18:33:28 miguelfreitas Exp $ + * $Id: dxr3_mpeg_encoders.c,v 1.13 2003/09/11 10:01:03 mroi Exp $ */ /* mpeg encoders for the dxr3 video out plugin. @@ -301,11 +301,6 @@ static void mp1e_callback(rte_context *context, void *data, ssize_t size, void * char tmpstr[128]; ssize_t written; - if (drv->fd_video == CLOSED_FOR_ENCODER) { - snprintf(tmpstr, sizeof(tmpstr), "%s_mv%s", drv->class->devname, drv->class->devnum); - drv->fd_video = open(tmpstr, O_WRONLY | O_NONBLOCK); - } - if (drv->fd_video < 0) return; written = write(drv->fd_video, data, size); if (written < 0) { printf("dxr3_mpeg_encoder: video device write failed (%s)\n", @@ -490,11 +485,6 @@ static int fame_on_display_frame(dxr3_driver_t *drv, dxr3_frame_t *frame) frame->vo_frame.free(&frame->vo_frame); - if (drv->fd_video == CLOSED_FOR_ENCODER) { - snprintf (tmpstr, sizeof(tmpstr), "%s_mv%s", drv->class->devname, drv->class->devnum); - drv->fd_video = open(tmpstr, O_WRONLY | O_NONBLOCK); - } - if (drv->fd_video < 0) return 0; written = write(drv->fd_video, this->buffer, size); if (written < 0) { printf("dxr3_mpeg_encoder: video device write failed (%s)\n", diff --git a/src/dxr3/dxr3_scr.c b/src/dxr3/dxr3_scr.c index b3706fa85..ffa289f1f 100644 --- a/src/dxr3/dxr3_scr.c +++ b/src/dxr3/dxr3_scr.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_scr.c,v 1.9 2003/02/26 20:35:32 mroi Exp $ + * $Id: dxr3_scr.c,v 1.10 2003/09/11 10:01:03 mroi Exp $ */ /* dxr3 scr plugin. @@ -55,14 +55,14 @@ static int dxr3_mvcommand(int fd_control, int command); static void dxr3_scr_update_priority(void *this_gen, xine_cfg_entry_t *entry); -dxr3_scr_t *dxr3_scr_init(xine_stream_t *stream) +dxr3_scr_t *dxr3_scr_init(xine_t *xine) { dxr3_scr_t *this; const char *confstr; this = (dxr3_scr_t *)malloc(sizeof(dxr3_scr_t)); - confstr = stream->xine->config->register_string(stream->xine->config, + confstr = xine->config->register_string(xine->config, CONF_LOOKUP, CONF_DEFAULT, CONF_NAME, CONF_HELP, 0, NULL, NULL); if ((this->fd_control = open(confstr, O_WRONLY)) < 0) { printf("dxr3_scr: Failed to open control device %s (%s)\n", @@ -79,8 +79,8 @@ dxr3_scr_t *dxr3_scr_init(xine_stream_t *stream) this->scr_plugin.set_speed = dxr3_scr_set_speed; this->scr_plugin.exit = dxr3_scr_exit; - this->priority = stream->xine->config->register_num( - stream->xine->config, "dxr3.scr_priority", 10, _("Dxr3: SCR plugin priority"), + this->priority = xine->config->register_num( + xine->config, "dxr3.scr_priority", 10, _("Dxr3: SCR plugin priority"), _("Scr priorities greater 5 make the dxr3 xine's master clock."), 20, dxr3_scr_update_priority, this); this->offset = 0; diff --git a/src/dxr3/dxr3_scr.h b/src/dxr3/dxr3_scr.h index c038feb90..ce7416627 100644 --- a/src/dxr3/dxr3_scr.h +++ b/src/dxr3/dxr3_scr.h @@ -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_scr.h,v 1.3 2002/10/26 14:35:05 mroi Exp $ + * $Id: dxr3_scr.h,v 1.4 2003/09/11 10:01:03 mroi Exp $ */ #include "xine_internal.h" @@ -37,4 +37,4 @@ typedef struct dxr3_scr_s { } dxr3_scr_t; /* plugin initialization function */ -dxr3_scr_t *dxr3_scr_init(xine_stream_t *stream); +dxr3_scr_t *dxr3_scr_init(xine_t *xine); diff --git a/src/dxr3/video_out_dxr3.c b/src/dxr3/video_out_dxr3.c index ae8446475..f9209d214 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.85 2003/08/12 13:54:21 mroi Exp $ + * $Id: video_out_dxr3.c,v 1.86 2003/09/11 10:01:03 mroi Exp $ */ /* mpeg1 encoding video out plugin for the dxr3. @@ -65,6 +65,9 @@ #define LOG_VID 0 #define LOG_OVR 0 +/* the amount of extra time we give the card for decoding */ +#define DECODE_PIPE_PREBUFFER 10000 + /* plugin class initialization functions */ static void *dxr3_x11_init_plugin(xine_t *xine, void *visual_gen); @@ -193,6 +196,8 @@ static dxr3_driver_class_t *dxr3_vo_init_plugin(xine_t *xine, void *visual_gen) this->instance = 0; + this->scr = dxr3_scr_init(xine); + return this; } @@ -208,6 +213,9 @@ static char *dxr3_vo_get_description(video_driver_class_t *class_gen) static void dxr3_vo_class_dispose(video_driver_class_t *class_gen) { + dxr3_driver_class_t *class = (dxr3_driver_class_t *)class_gen; + + class->scr->scr_plugin.exit(&class->scr->scr_plugin); free(class_gen); } @@ -250,6 +258,7 @@ static vo_driver_t *dxr3_vo_open_plugin(video_driver_class_t *class_gen, const v this->vo_driver.gui_data_exchange = dxr3_gui_data_exchange; this->vo_driver.dispose = dxr3_dispose; + pthread_mutex_init(&this->video_device_lock, NULL); pthread_mutex_init(&this->spu_device_lock, NULL); vo_scale_init(&this->scale, 0, 0, config); @@ -288,7 +297,7 @@ static vo_driver_t *dxr3_vo_open_plugin(video_driver_class_t *class_gen, const v } /* close now and and let the decoder/encoder reopen if they want */ close(this->fd_video); - this->fd_video = CLOSED_FOR_DECODER; + this->fd_video = -1; /* which encoder to use? Whadda we got? */ encoder = 0; @@ -492,17 +501,24 @@ static uint32_t dxr3_get_capabilities(vo_driver_t *this_gen) static vo_frame_t *dxr3_alloc_frame(vo_driver_t *this_gen) { dxr3_frame_t *frame; +#if 0 dxr3_driver_t *this = (dxr3_driver_t *)this_gen; +#endif frame = (dxr3_frame_t *)malloc(sizeof(dxr3_frame_t)); memset(frame, 0, sizeof(dxr3_frame_t)); pthread_mutex_init(&frame->vo_frame.mutex, NULL); +#if 1 + /* always call frame_copy since we do some little vpts tweaking there */ + frame->vo_frame.copy = dxr3_frame_copy; +#else if (this->enc && this->enc->on_frame_copy) frame->vo_frame.copy = dxr3_frame_copy; else - frame->vo_frame.copy = 0; + frame->vo_frame.copy = NULL; +#endif frame->vo_frame.field = dxr3_frame_field; frame->vo_frame.dispose = dxr3_frame_dispose; frame->vo_frame.driver = this_gen; @@ -515,6 +531,10 @@ static void dxr3_frame_copy(vo_frame_t *frame_gen, uint8_t **src) dxr3_frame_t *frame = (dxr3_frame_t *)frame_gen; dxr3_driver_t *this = (dxr3_driver_t *)frame_gen->driver; + /* vpts hack: we reduce the vpts to give the card some extra decoding time */ + if (frame_gen->format != XINE_IMGFMT_DXR3 && !frame_gen->copy_called) + frame_gen->vpts -= DECODE_PIPE_PREBUFFER; + frame_gen->copy_called = 1; if (frame_gen->format != XINE_IMGFMT_DXR3 && this->enc && this->enc->on_frame_copy) @@ -545,19 +565,20 @@ static void dxr3_update_frame_format(vo_driver_t *this_gen, vo_frame_t *frame_ge if (format == XINE_IMGFMT_DXR3) { /* talking to dxr3 decoder */ /* a bit of a hack. we must release the em8300_mv fd for * the dxr3 decoder plugin */ + pthread_mutex_lock(&this->video_device_lock); if (this->fd_video >= 0) { + metronom_clock_t *clock = this->class->xine->clock; + + clock->unregister_scr(clock, &this->class->scr->scr_plugin); close(this->fd_video); - this->fd_video = CLOSED_FOR_DECODER; + this->fd_video = -1; /* inform the encoder on next frame's arrival */ this->need_update = 1; } + pthread_mutex_unlock(&this->video_device_lock); /* for mpeg source, we don't have to do much. */ - this->video_width = width; - this->video_iheight = height; - this->video_oheight = height; - this->top_bar = 0; - this->video_ratio = ratio; + this->video_width = 0; frame->vo_frame.width = width; frame->vo_frame.height = height; @@ -587,13 +608,29 @@ static void dxr3_update_frame_format(vo_driver_t *this_gen, vo_frame_t *frame_ge frame->vo_frame.ratio = ratio; frame->pan_scan = 0; - frame->aspect = this->aspect; + frame->aspect = this->video_aspect; oheight = this->video_oheight; - if (this->fd_video == CLOSED_FOR_DECODER) { /* decoder should have released it */ - this->fd_video = CLOSED_FOR_ENCODER; /* allow encoder to reopen it */ + pthread_mutex_lock(&this->video_device_lock); + if (this->fd_video < 0) { /* decoder should have released it */ + metronom_clock_t *clock = this->class->xine->clock; + char tmpstr[128]; + int64_t time; + + /* open the device for the encoder */ + snprintf(tmpstr, sizeof(tmpstr), "%s_mv%s", this->class->devname, this->class->devnum); + if ((this->fd_video = open(tmpstr, O_WRONLY | O_NONBLOCK)) < 0) + printf("video_out_dxr3: Failed to open video device %s (%s)\n", + tmpstr, strerror(errno)); + + /* start the scr plugin */ + time = clock->get_current_time(clock); + this->class->scr->scr_plugin.start(&this->class->scr->scr_plugin, time); + clock->register_scr(clock, &this->class->scr->scr_plugin); + this->scale.force_redraw = 1; } + pthread_mutex_unlock(&this->video_device_lock); if ((this->video_width != width) || (this->video_iheight != height) || (fabs(this->video_ratio - ratio) > 0.01)) { @@ -619,10 +656,15 @@ static void dxr3_update_frame_format(vo_driver_t *this_gen, vo_frame_t *frame_ge printf("video_out_dxr3: adding %d black lines to get %s aspect ratio.\n", oheight - height, frame->aspect == XINE_VO_ASPECT_4_3 ? "4:3" : "16:9"); + /* make top black bar multiple of 16, + * so old and new macroblocks overlap */ + this->top_bar = ((oheight - height) / 32) * 16; + this->video_width = width; this->video_iheight = height; this->video_oheight = oheight; this->video_ratio = ratio; + this->video_aspect = frame->aspect; this->scale.force_redraw = 1; this->need_update = 1; @@ -641,9 +683,6 @@ static void dxr3_update_frame_format(vo_driver_t *this_gen, vo_frame_t *frame_ge frame->mem = NULL; } - /* make top black bar multiple of 16, - * so old and new macroblocks overlap */ - this->top_bar = ((oheight - height) / 32) * 16; if (format == XINE_IMGFMT_YUY2) { int i, image_size; @@ -870,20 +909,29 @@ static void dxr3_display_frame(vo_driver_t *this_gen, vo_frame_t *frame_gen) if (frame_gen->format != XINE_IMGFMT_DXR3 && this->enc && this->enc->on_display_frame) { - if (this->fd_video == CLOSED_FOR_DECODER) { + pthread_mutex_lock(&this->video_device_lock); + if (this->fd_video < 0) { /* no need to encode, when the device is already reserved for the decoder */ frame_gen->free(frame_gen); } else { + uint32_t vpts32 = (uint32_t)(frame_gen->vpts + DECODE_PIPE_PREBUFFER); + if (this->need_update) { /* we cannot do this earlier, because vo_frame.duration is only valid here */ if (this->enc && this->enc->on_update_format) this->enc->on_update_format(this, frame); this->need_update = 0; } + + /* inform the card on the timing */ + if (ioctl(this->fd_video, EM8300_IOCTL_VIDEO_SETPTS, &vpts32)) + printf("video_out_dxr3: set video pts failed (%s)\n", + strerror(errno)); /* for non-mpeg, the encoder plugin is responsible for calling * frame_gen->free(frame_gen) ! */ this->enc->on_display_frame(this, frame); } + pthread_mutex_unlock(&this->video_device_lock); } else { @@ -1133,6 +1181,7 @@ static void dxr3_dispose(vo_driver_t *this_gen) close(this->fd_spu); } pthread_mutex_unlock(&this->spu_device_lock); + pthread_mutex_destroy(&this->video_device_lock); pthread_mutex_destroy(&this->spu_device_lock); free(this); } diff --git a/src/dxr3/video_out_dxr3.h b/src/dxr3/video_out_dxr3.h index 6e78ab86b..09af98652 100644 --- a/src/dxr3/video_out_dxr3.h +++ b/src/dxr3/video_out_dxr3.h @@ -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.h,v 1.18 2003/08/05 15:07:42 mroi Exp $ + * $Id: video_out_dxr3.h,v 1.19 2003/09/11 10:01:04 mroi Exp $ */ #ifdef HAVE_CONFIG_H @@ -30,12 +30,9 @@ #include "xine_internal.h" #include "vo_scale.h" +#include "dxr3_scr.h" #include "dxr3.h" -/* values for fd_video indicating why it is closed */ -#define CLOSED_FOR_DECODER -1 -#define CLOSED_FOR_ENCODER -2 - /* the number of supported encoders */ #define SUPPORTED_ENCODER_COUNT 3 @@ -79,6 +76,8 @@ typedef struct dxr3_driver_class_s { char devname[128]; char devnum[3]; + + dxr3_scr_t *scr; /* to provide dxr3 clocking */ } dxr3_driver_class_t; typedef struct dxr3_driver_s { @@ -86,6 +85,7 @@ typedef struct dxr3_driver_s { dxr3_driver_class_t *class; int fd_control; + pthread_mutex_t video_device_lock; int fd_video; pthread_mutex_t spu_device_lock; int fd_spu; /* to access the relevant dxr3 devices */ @@ -111,6 +111,7 @@ typedef struct dxr3_driver_s { uint32_t video_oheight; /* output height (after adding black bars) */ uint32_t video_width; double video_ratio; + int video_aspect; int top_bar; /* the height of the upper black bar */ vo_scale_t scale; diff --git a/src/libffmpeg/xine_encoder.c b/src/libffmpeg/xine_encoder.c index a8b0e4c93..a993a6955 100644 --- a/src/libffmpeg/xine_encoder.c +++ b/src/libffmpeg/xine_encoder.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: xine_encoder.c,v 1.5 2003/07/09 18:25:45 mroi Exp $ + * $Id: xine_encoder.c,v 1.6 2003/09/11 10:01:02 mroi Exp $ */ /* mpeg encoders for the dxr3 video out plugin. */ @@ -274,13 +274,8 @@ static int lavc_on_display_frame(dxr3_driver_t *drv, dxr3_frame_t *frame) size = avcodec_encode_video(this->context, this->ffmpeg_buffer, DEFAULT_BUFFER_SIZE, this->picture); frame->vo_frame.free(&frame->vo_frame); - - if (drv->fd_video == CLOSED_FOR_ENCODER) { - snprintf (tmpstr, sizeof(tmpstr), "%s_mv%s", drv->class->devname, drv->class->devnum); - drv->fd_video = open(tmpstr, O_WRONLY | O_NONBLOCK); - } - if (drv->fd_video < 0) return 0; - written = write(drv->fd_video, this->ffmpeg_buffer, size); + + written = write(drv->fd_video, this->ffmpeg_buffer, size); if (written < 0) { printf("dxr3_mpeg_encoder: video device write failed (%s)\n", strerror(errno)); |