diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/dxr3/Makefile.am | 15 | ||||
-rw-r--r-- | src/dxr3/dxr3_video_out.h | 47 | ||||
-rw-r--r-- | src/dxr3/dxr3_vo_encoder.c | 950 | ||||
-rw-r--r-- | src/dxr3/dxr3_vo_encoder.h | 89 | ||||
-rw-r--r-- | src/dxr3/dxr3_vo_standard.c | 43 |
5 files changed, 602 insertions, 542 deletions
diff --git a/src/dxr3/Makefile.am b/src/dxr3/Makefile.am index 163846a4f..d9f73e932 100644 --- a/src/dxr3/Makefile.am +++ b/src/dxr3/Makefile.am @@ -6,15 +6,18 @@ LIBTOOL = $(SHELL) $(top_builddir)/libtool-nofpic libdir = $(XINE_PLUGINDIR) -# replace -lfame by -lrte below and define USE_MP1E 1 in dxr3_vo_decoder.h to -# use librte! Works with API of librte-0.4. - if HAVE_DXR3 -if HAVE_FAME +if HAVE_ENCODER dxr3enc_module = xineplug_vo_out_dxr3enc.la endif dxr3_modules = xineplug_decode_dxr3.la xineplug_vo_out_dxr3.la endif +if HAVE_LIBFAME +link_fame=-lfame +endif +if HAVE_LIBRTE +link_rte=-lrte +endif lib_LTLIBRARIES = $(dxr3_modules) $(dxr3enc_module) @@ -26,9 +29,9 @@ xineplug_vo_out_dxr3_la_LDFLAGS = -avoid-version -module $(X_LIBS) xineplug_vo_out_dxr3enc_la_SOURCES = dxr3_vo_encoder.c dxr3_vo_core.c xineplug_vo_out_dxr3enc_la_LDFLAGS = \ - -avoid-version -module -lfame $(X_LIBS) + -avoid-version -module $(link_fame) $(link_rte) $(X_LIBS) -include_HEADERS = dxr3_video_out.h dxr3_vo_encoder.h +include_HEADERS = dxr3_video_out.h debug: @$(MAKE) CFLAGS="$(DEBUG_CFLAGS) $(LINUX_INCLUDE)" diff --git a/src/dxr3/dxr3_video_out.h b/src/dxr3/dxr3_video_out.h index 9a956e2f3..bf9174fe8 100644 --- a/src/dxr3/dxr3_video_out.h +++ b/src/dxr3/dxr3_video_out.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_video_out.h,v 1.8 2001/11/29 07:17:07 mlampard Exp $ + * $Id: dxr3_video_out.h,v 1.9 2001/12/11 02:26:59 hrm Exp $ * */ @@ -80,6 +80,9 @@ typedef struct { struct coeff colcal_lower[3]; } dxr3_overlay_t; +typedef enum { ENC_FAME, ENC_RTE } encoder_type; +typedef struct encoder_data_s encoder_data_t; + typedef struct dxr3_driver_s { vo_driver_t vo_driver; config_values_t *config; @@ -87,14 +90,21 @@ typedef struct dxr3_driver_s { int fd_video; int aspectratio; int tv_mode; + int enhanced_mode; /* enhanced play mode */ em8300_bcs_t bcs; - + const char *devname; + /* for encoder plugin */ - uint8_t *out[3]; /* aligned buffer for YV12 data, copied from frames */ - uint8_t *buf[3]; /* unaligned YV12 buffer */ - int oheight; /* height after adding black bars to correct a.r. */ - int video_iheight; /* input height (before adding black bars) */ - int video_height; /* output height (after adding bars) */ + encoder_data_t *enc; /* encoder data */ + double fps; /* frames per second */ + int format; /* color format */ + const char *file_out; + /* height after adding black bars to correct a.r. */ + int oheight; + /* input height (before adding black bars) */ + int video_iheight; + /* output height (after adding bars) */ + int video_height; /* for overlay */ dxr3_overlay_t overlay; @@ -116,25 +126,30 @@ typedef struct dxr3_driver_s { char *user_data; - void (*request_dest_size) (char *userdata, int video_width, int video_height, int *dest_x, + void (*request_dest_size) (char *userdata, int video_width, + int video_height, 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]; /* allocated for YV12 or YUY2 buffers */ - uint8_t *real_base[3]; /* same buffers alligned on 16 bytes */ + int width, height,oheight; + uint8_t *mem; /* allocated for YV12 or YUY2 buffers */ + uint8_t *real_base[3]; /* yuv/yuy2 buffers in mem aligned on 16 */ int format; dxr3_driver_t *vo_instance; /* points to self, for use in dxr3_frame_copy */ int copy_calls; /* counts calls to dxr3_frame_copy function */ -#if USE_MPEG_BUFFER unsigned char *mpeg; /* encoded mpeg data */ unsigned int mpeg_size; /* length of data */ -#endif -}dxr3_frame_t; - -static char *devname; +} dxr3_frame_t; + +struct encoder_data_s { + encoder_type type; + int (*on_update_format)(dxr3_driver_t *); + int (*on_frame_copy)(dxr3_driver_t *, dxr3_frame_t *, uint8_t **src); + int (*on_display_frame)(dxr3_driver_t *, dxr3_frame_t *); + int (*on_close)(dxr3_driver_t *); +}; /* func definitions */ /* Overlay functions */ diff --git a/src/dxr3/dxr3_vo_encoder.c b/src/dxr3/dxr3_vo_encoder.c index 37db0f1c7..368c03e88 100644 --- a/src/dxr3/dxr3_vo_encoder.c +++ b/src/dxr3/dxr3_vo_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: dxr3_vo_encoder.c,v 1.12 2001/12/02 21:14:51 hrm Exp $ + * $Id: dxr3_vo_encoder.c,v 1.13 2001/12/11 02:26:59 hrm Exp $ * * mpeg1 encoding video out plugin for the dxr3. * @@ -131,41 +131,85 @@ * API is still under development so don't expect newer versions to work * right away), define USE_MP1E 1 in the header below and change -lfame * to -lrte in Makefile.am + * + ****** Update 11/12/2001 by Harm + * + * Much much needed clean up. + * Dropped ffmpeg support for the moment. Moved almost all libfame and + * librte stuff in separate sections, defined general encoder API + * in encoder_data_t. + * */ -/* encoder specific config/setup stuff * - * must be before dxr3_video_out.h */ -#include "dxr3_vo_encoder.h" +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#ifdef HAVE_LIBRTE +# define _GNU_SOURCE +# include <unistd.h> +# include <rte.h> +#endif +#ifdef HAVE_LIBFAME +# include <fame.h> +#endif -/* dxr3 vo globals */ #include "dxr3_video_out.h" +/* buffer size for encoded mpeg1 stream; will hold one intra frame + * at 640x480 typical sizes are <50 kB. 512 kB should be plenty */ +#define DEFAULT_BUFFER_SIZE 512*1024 + +#ifdef HAVE_LIBFAME +typedef struct { + encoder_data_t encoder_data; + fame_context_t *fc; /* needed for fame calls */ + fame_parameters_t fp; + fame_yuv_t yuv; + /* temporary buffer for mpeg data */ + char *buffer; + /* temporary buffer for YUY2->YV12 conversion */ + uint8_t *out[3]; /* aligned buffer for YV12 data */ + uint8_t *buf; /* unaligned YV12 buffer */ +} fame_data_t; + +int dxr3enc_fame_init(dxr3_driver_t *); +#endif + +#ifdef HAVE_LIBRTE +typedef struct { + encoder_data_t encoder_data; + rte_context* context; /* handle for encoding */ + void* rte_ptr; /* buffer maintened by librte */ + double rte_time; /* frame time (s) */ + double rte_time_step; /* time per frame (s) */ + double rte_bitrate; /* mpeg out bitrate, default 2.3e6 bits/s */ +} rte_data_t; + +int dxr3enc_rte_init(dxr3_driver_t *); +#endif + + +#define MV_COMMAND 0 + static uint32_t dxr3_get_capabilities (vo_driver_t *this_gen) { - /* Since we have no vo format, we return dummy values here */ return VO_CAP_YV12 | VO_CAP_YUY2 | VO_CAP_SATURATION | VO_CAP_BRIGHTNESS | VO_CAP_CONTRAST; } -/* This are dummy functions to fill in the frame object */ - static void dummy_frame_field (vo_frame_t *vo_img, int which_field) { - fprintf(stderr, "dxr3_vo: dummy_frame_field called!\n"); + /* dummy function */ } static void dxr3_frame_dispose (vo_frame_t *frame_gen) { 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]); -#if USE_MPEG_BUFFER - free(frame->mpeg); -#endif + if (frame->mem) + free (frame->mem); + if (frame->mpeg) + free(frame->mpeg); free(frame); } @@ -173,7 +217,6 @@ static void dxr3_frame_copy(vo_frame_t *frame_gen, uint8_t **src); static vo_frame_t *dxr3_alloc_frame (vo_driver_t *this_gen) { - /* dxr3_driver_t *this = (dxr3_driver_t *) this_gen; */ dxr3_frame_t *frame; frame = (dxr3_frame_t *) malloc (sizeof (dxr3_frame_t)); @@ -183,9 +226,7 @@ static vo_frame_t *dxr3_alloc_frame (vo_driver_t *this_gen) frame->vo_frame.field = dummy_frame_field; frame->vo_frame.dispose = dxr3_frame_dispose; -#if USE_MPEG_BUFFER frame->mpeg = (unsigned char *) malloc (DEFAULT_BUFFER_SIZE); -#endif return (vo_frame_t*) frame; } @@ -196,10 +237,9 @@ static void dxr3_update_frame_format (vo_driver_t *this_gen, int ratio_code, int format, int flags) { dxr3_driver_t *this = (dxr3_driver_t *) this_gen; - int aspect; + int aspect,i; dxr3_frame_t *frame = (dxr3_frame_t *) frame_gen; int image_size, oheight, top_bar; - float fps; /* reset the copy calls counter (number of calls to dxr3_frame_copy) */ frame->copy_calls = 0; @@ -208,6 +248,8 @@ static void dxr3_update_frame_format (vo_driver_t *this_gen, aspect = this->aspectratio; oheight = this->oheight; + frame->mpeg_size = 0; + /* check aspect ratio, see if we need to add black borders */ if ((this->video_width != width) || (this->video_iheight != height) || (this->video_aspect != ratio_code)) { @@ -239,68 +281,55 @@ static void dxr3_update_frame_format (vo_driver_t *this_gen, if (oheight - height > 0) printf("dxr3enc: adding %d black lines to get %s a.r.\n", oheight-height, aspect == ASPECT_FULL ? "4:3" : "16:9"); - - /* if YUY2 and dimensions changed, we need to re-allocate the - * internal YV12 buffer */ - if (format == IMGFMT_YUY2) { - if (this->buf[0]) free(this->buf[0]); - if (this->buf[1]) free(this->buf[1]); - if (this->buf[2]) free(this->buf[2]); - - image_size = width * oheight; - - this->out[0] = malloc_aligned(16, image_size, (void*)&this->buf[0]); - this->out[1] = malloc_aligned(16, image_size/4, (void*)&this->buf[1]); - this->out[2] = malloc_aligned(16, image_size/4, (void*)&this->buf[2]); - - /* fill with black (yuv 16,128,128) */ - memset(this->out[0], 16, image_size); - memset(this->out[1], 128, image_size/4); - memset(this->out[2], 128, image_size/4); - - printf("dxr3enc: Using YUY2->YV12 conversion\n"); - } + this->video_width = width; + this->video_iheight = height; + this->video_height = oheight; + this->video_aspect = ratio_code; + this->fps = 90000.0/frame->vo_frame.duration; + this->format = format; + + if (this->enc && this->enc->on_update_format) + this->enc->on_update_format(this); } + /* if dimensions changed, we need to re-allocate frame memory */ if ((frame->width != width) || (frame->height != height)) { - 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; + if (frame->mem) { + free (frame->mem); + frame->mem = NULL; } + /* make top black bar multiple of 16, + * so old and new macroblocks overlap */ + top_bar = ((oheight - height) / 32) * 16; if (format == IMGFMT_YUY2) { - image_size = width * height; /* does not include black bars */ + image_size = width * oheight; /* includes black bars */ /* planar format, only base[0] */ - frame->vo_frame.base[0] = malloc_aligned(16, image_size*2, (void**)&frame->mem[0]); + frame->real_base[0] = malloc_aligned(16, image_size*2, (void**)&frame->mem); + frame->real_base[1] = frame->real_base[2] = 0; + + /* fix offset, so the decoder does not see the top black bar */ + frame->vo_frame.base[0] = frame->real_base[0] + width * 2 * top_bar; frame->vo_frame.base[1] = frame->vo_frame.base[2] = 0; - frame->real_base[0] = frame->real_base[1] = frame->real_base[2] = 0; - /* we do the black bar stuff while converting to YV12 */ + + /* fill with black (yuy2 16,128,16,128,...) */ + memset(frame->real_base[0], 128, 2*image_size); /* U and V */ + for (i=0; i<2*image_size; i+=2) + *(frame->vo_frame.base[0]+i) = 16; /* Y */ } else { /* IMGFMT_YV12 */ image_size = width * oheight; /* includes black bars */ - frame->real_base[0] = malloc_aligned(16,image_size, - (void**) &frame->mem[0]); - frame->real_base[1] = malloc_aligned(16,image_size/4, - (void**) &frame->mem[1]); - frame->real_base[2] = malloc_aligned(16,image_size/4, - (void**) &frame->mem[2]); + frame->real_base[0] = malloc_aligned(16, image_size * 3/2, + (void**) &frame->mem); + frame->real_base[1] = frame->real_base[0] + image_size; + frame->real_base[2] = frame->real_base[1] + image_size/4; + /* fill with black (yuv 16,128,128) */ memset(frame->real_base[0], 16, image_size); memset(frame->real_base[1], 128, image_size/4); memset(frame->real_base[2], 128, image_size/4); - /* make top black bar multiple of 16, - * so old and new macroblocks overlap */ - top_bar = ((oheight - height) / 16) * 8; /* fix offsets, so the decoder does not see the top black bar */ frame->vo_frame.base[0] = frame->real_base[0] + width * top_bar; frame->vo_frame.base[1] = frame->real_base[1] + width * top_bar/4; @@ -310,343 +339,55 @@ static void dxr3_update_frame_format (vo_driver_t *this_gen, frame->width = width; frame->height = height; + frame->oheight = oheight; frame->format = format; - this->video_width = width; - this->video_iheight = height; - this->video_height = oheight; - this->video_aspect = ratio_code; - - /* init encoder if needed */ -#if USE_LIBFAME - if (!fc) - { - if (!(fc = fame_open ())) - puts ("Couldn't start the FAME library"); - - buffer = (unsigned char *) malloc (DEFAULT_BUFFER_SIZE); - fp.quality=this->config->register_range(this->config,"dxr3enc.quality",90, 10,100, "Dxr3enc: mpeg encoding quality",NULL,NULL,NULL); - /* the really interesting bit is the quantizer scale. The formula - * below is copied from libfame's sources (could be changed in the - * future) */ - printf("dxr3enc: quality %d -> quant scale = %d\n", fp.quality, - 1 + (30*(100-fp.quality)+50)/100); - fp.width = width; - fp.height = oheight; - fp.profile = "mpeg1"; - fp.coding = "I"; - fp.verbose = 0; /* we don't need any more info.. thanks :) */ - - /* start guessing the framerate */ - fps = 90000.0/frame->vo_frame.duration; - if (fabs(fps - 25) < 0.01) { /* PAL */ - printf("dxr3enc: setting mpeg output framerate to PAL (25 Hz)\n"); - fp.frame_rate_num = 25; fp.frame_rate_den = 1; - } - else if (fabs(fps - 24) < 0.01) { /* FILM */ - printf("dxr3enc: setting mpeg output framerate to FILM (24 Hz))\n"); - fp.frame_rate_num = 24; fp.frame_rate_den = 1; - } - else if (fabs(fps - 23.976) < 0.01) { /* NTSC-FILM */ - printf("dxr3enc: setting mpeg output framerate to NTSC-FILM (23.976 Hz))\n"); - fp.frame_rate_num = 24000; fp.frame_rate_den = 1001; - } - else if (fabs(fps - 29.97) < 0.01) { /* NTSC */ - printf("dxr3enc: setting mpeg output framerate to NTSC (29.97 Hz)\n"); - fp.frame_rate_num = 30000; fp.frame_rate_den = 1001; - } - else { /* try 1/fps, if not legal, libfame will go to PAL */ - fp.frame_rate_num = (int)(fps + 0.5); fp.frame_rate_den = 1; - printf("dxr3enc: trying to set mpeg output framerate to %d Hz\n", - fp.frame_rate_num); - } - fame_init (fc, &fp, buffer, DEFAULT_BUFFER_SIZE); - } -#endif -#if USE_FFMPEG - if (!avc) - { - avc = malloc(sizeof(AVCodecContext)); - memset(avc, 0, sizeof(AVCodecContext)); - buffer = (unsigned char *) malloc (DEFAULT_BUFFER_SIZE); - - avc->bit_rate = 0; /* using fixed quantizer */ - avc->width = width; - avc->height = oheight; - avc->gop_size = 0; /* only intra */ - avc->pix_fmt = PIX_FMT_YUV420P; - avc->flags = CODEC_FLAG_QSCALE; /* fix qscale = quality */ - avc->quality = 2; /* 1-31 highest-lowest quality */ - /* start guessing the framerate */ - fps = 90000.0/frame->vo_frame.duration; - avc->frame_rate = (int)(fps*FRAME_RATE_BASE + 0.5); - - if (avcodec_open(avc, avcodec)) { - printf("dxr3enc: error opening avcodec. Aborting...\n"); - exit(1); /* can't think of a cleaner way at this point */ - } - } -#endif -#if USE_MP1E - if (context == 0) { - enum rte_mux_mode mux_mode = RTE_VIDEO; - /* rte_codec *codec; */ - enum rte_frame_rate frame_rate; - enum rte_pixformat pixformat; - char tmpstr[128]; - - if (format != IMGFMT_YV12) { - /* not supported yet; I need to fix the black bar stuff for YUYV - buffers first... can't use the internal yuyv->yuv420 translation - if sending data from display_frame... */ - printf("dxr3enc: format not supported yet with mp1e encoder.\n"); - exit(1); - } - - if (! rte_init() ) { - printf("dxr3enc: failed to init librte; exiting...\n"); - exit(1); - } - context = rte_context_new (width, oheight, "mp1e", NULL); - rte_set_verbosity(context, 2); - /* rte_codec_set seems to create a program stream ... */ - /*codec = rte_codec_set(context, RTE_STREAM_VIDEO, 0, "mpeg1-video");*/ - rte_set_mode(context, mux_mode); - - /* start guessing the framerate */ - fps = 90000.0/frame->vo_frame.duration; - if (fabs(fps - 23.976) < 0.01) { /* NTSC-FILM */ - printf("dxr3enc: setting mpeg output framerate to NTSC-FILM (23.976 Hz))\n"); - frame_rate = RTE_RATE_1; - } - else if (fabs(fps - 24) < 0.01) { /* FILM */ - printf("dxr3enc: setting mpeg output framerate to FILM (24 Hz))\n"); - frame_rate = RTE_RATE_2; - } - else if (fabs(fps - 25) < 0.01) { /* PAL */ - printf("dxr3enc: setting mpeg output framerate to PAL (25 Hz)\n"); - frame_rate = RTE_RATE_3; - } - else if (fabs(fps - 29.97) < 0.01) { /* NTSC */ - printf("dxr3enc: setting mpeg output framerate to NTSC (29.97 Hz)\n"); - frame_rate = RTE_RATE_4; - } - else { /* go to PAL */ - frame_rate = RTE_RATE_3; - printf("dxr3enc: can't do %g Hz, using PAL\n", fps); - } - pixformat = (format == IMGFMT_YV12 ? RTE_YUV420 : RTE_YUYV); - rte_bitrate=this->config->register_range(this->config,"dxr3enc.bitrate",5000, 500,10000, "Dxr3enc: rte mpeg output bitrate (kbit/s)",NULL,NULL,NULL); - rte_bitrate *= 1000; - if (!rte_set_video_parameters(context, pixformat, - context->width, context->height, frame_rate, rte_bitrate, "I")) { - printf("dxr3enc: set_video_parameters failed: %s\n", - context->error); - rte_context_destroy(context); - exit(1); - } - /* paranoid; make sure we don't do motion searching */ - rte_set_motion(context, 0, 0); - rte_set_input(context, RTE_VIDEO, RTE_PUSH, FALSE, NULL, NULL, NULL); - snprintf (tmpstr, sizeof(tmpstr), "%s_mv", devname); - rte_set_output(context, NULL, NULL, tmpstr); - if (!rte_init_context(context)) { - printf("dxr3enc: cannot init the context: %s\n", - context->error); - rte_context_delete(context); - exit(1); - } - /* do the sync'ing and start encoding */ - if (!rte_start_encoding(context)) { - printf("dxr3enc: cannot start encoding: %s\n", - context->error); - rte_context_delete(context); - exit(1); - } - rte_ptr = rte_push_video_data(context, NULL, 0); - if (! rte_ptr) { - printf("dxr3enc: failed to get encoder buffer pointer.\n"); - exit(1); - } - rte_time = 0.0; - rte_time_step = frame->vo_frame.duration/90000.; - } -#endif if(this->aspectratio!=aspect) dxr3_set_property (this_gen,VO_PROP_ASPECT_RATIO, aspect); -#if USE_MPEG_BUFFER - /* safeguard */ - frame->mpeg_size = 0; -#endif } static void dxr3_frame_copy(vo_frame_t *frame_gen, uint8_t **src) { - int size, i, j, hoffset, w2; - dxr3_frame_t *frame = (dxr3_frame_t *) frame_gen; - dxr3_driver_t *this = frame->vo_instance; - uint8_t *y, *u, *v, *yuy2; - - if (frame_gen->bad_frame) - return; - - if (frame->copy_calls == frame->height/16) { - /* shouldn't happen */ - printf("dxr3enc: Internal error. Too many calls to dxr3_frame_copy (%d)\n", - frame->copy_calls); - return; - } - - if (frame_gen->format == IMGFMT_YV12) { - y = frame->real_base[0]; - u = frame->real_base[1]; - v = frame->real_base[2]; - } - else { /* must be YUY2 */ - if (! (this->out[0] && this->out[1] && this->out[2]) ) { - printf("dxr3enc: Internal error. Internal YV12 buffer not created.\n"); - return; - } - /* need conversion */ - hoffset = (this->oheight - frame->height)/2; - y = this->out[0] + frame->width*(hoffset + frame->copy_calls*16); - u = this->out[1] + frame->width/2*(hoffset/2 + frame->copy_calls*8); - v = this->out[2] + frame->width/2*(hoffset/2 + frame->copy_calls*8); - yuy2 = src[0]; - w2 = frame->width/2; - /* we get 16 lines each time */ - for (i=0; i<16; i+=2) { - for (j=0; j<w2; j++) { - /* packed YUV 422 is: Y[i] U[i] Y[i+1] V[i] */ - *(y++) = *(yuy2++); - *(u++) = *(yuy2++); - *(y++) = *(yuy2++); - *(v++) = *(yuy2++); - } - /* down sampling */ - for (j=0; j<w2; j++) { - /* skip every second line for U and V */ - *(y++) = *(yuy2++); - yuy2++; - *(y++) = *(yuy2++); - yuy2++; - } - } - /* reset for encoder */ - y = this->out[0]; - u = this->out[1]; - v = this->out[2]; - } - - frame->copy_calls++; - - /* frame complete yet? */ - if (frame->copy_calls == frame->height/16) { -#if USE_LIBFAME - yuv.y=y; - yuv.u=u; - yuv.v=v; - size = fame_encode_frame(fc, &yuv, NULL); - /* not sure whether libfame does bounds checking, but if we're - * this close to the limit there's bound to be trouble */ - if (size >= DEFAULT_BUFFER_SIZE) { - printf("dxr3enc: warning, mpeg buffer too small!\n"); - size = DEFAULT_BUFFER_SIZE; - } -# if USE_MPEG_BUFFER - /* copy mpeg data to frame */ - xine_fast_memcpy(frame->mpeg, buffer, size); - frame->mpeg_size = size; -# endif -#endif -#if USE_FFMPEG - avp.data[0] = y; - avp.data[1] = u; - avp.data[2] = v; - avp.linesize[0] = frame->width; - avp.linesize[1] = avp.linesize[2] = frame->width/2; -# if USE_MPEG_BUFFER - size = avcodec_encode_video(avc, frame->mpeg, DEFAULT_BUFFER_SIZE, &avp); - frame->mpeg_size = size; -# else - size = avcodec_encode_video(avc, buffer, DEFAULT_BUFFER_SIZE, &avp); -# endif -#endif -#if USE_MP1E - rte_time += rte_time_step; -#endif -#if (!USE_MPEG_BUFFER) && (!USE_MP1E) - /* write to device now */ - if (write(this->fd_video, buffer, size) < 0) - perror("dxr3enc: writing to video device"); -#endif - } + dxr3_frame_t *frame = (dxr3_frame_t *) frame_gen; + dxr3_driver_t *this = frame->vo_instance; + if (this->enc && this->enc->on_frame_copy) + this->enc->on_frame_copy(this, frame, src); } -#define MV_COMMAND 0 - static void dxr3_display_frame (vo_driver_t *this_gen, vo_frame_t *frame_gen) { - char tmpstr[256]; - int size; dxr3_driver_t *this = (dxr3_driver_t*)this_gen; dxr3_frame_t *frame = (dxr3_frame_t*)frame_gen; -#if USE_MAGIC_REGISTER - em8300_register_t regs; - regs.microcode_register=1; /* Yes, this is a MC Reg */ - regs.reg = MV_COMMAND; - regs.val=6; /* Mike's mystery number :-) */ - ioctl(this->fd_control, EM8300_IOCTL_WRITEREG, ®s); -#endif -#if USE_MP1E - size = frame->width * this->oheight; - /* we should make real_base contiguous */ - xine_fast_memcpy(rte_ptr, frame->real_base[0], size); - xine_fast_memcpy(rte_ptr+size, frame->real_base[1], size/4); - xine_fast_memcpy(rte_ptr+size*5/4, frame->real_base[2], size/4); - rte_ptr = rte_push_video_data(context, rte_ptr, rte_time); -#endif -#if USE_MPEG_BUFFER - if (this->fd_video < 0) { - snprintf (tmpstr, sizeof(tmpstr), "%s_mv", devname); - this->fd_video = open(tmpstr, O_WRONLY); - } - if (write(this->fd_video, frame->mpeg, frame->mpeg_size) < 0) - perror("dxr3enc: writing to video device"); -#endif - frame_gen->displayed (frame_gen); + if (this->enc) + this->enc->on_display_frame(this, frame); + + /* plugin is responsible for calling vo_frame->displayed(frame) ! */ } static void dxr3_overlay_blend (vo_driver_t *this_gen, vo_frame_t *frame_gen, vo_overlay_t *overlay) { - /* dxr3_driver_t *this = (dxr3_driver_t *) this_gen; */ - /*fprintf(stderr, "dxr3_vo: dummy function dxr3_overlay_blend called!\n");*/ + /* dummy function */ } void dxr3_exit (vo_driver_t *this_gen) { dxr3_driver_t *this = (dxr3_driver_t *) this_gen; + if (this->enc && this->enc->on_close) + this->enc->on_close(this); if(this->overlay_enabled) - dxr3_overlay_set_mode(&this->overlay, EM8300_OVERLAY_MODE_OFF ); - close(this->fd_control); -#if USE_MP1E - if (context) { - rte_stop(context); - rte_context_delete(context); - context = 0; - } -#endif + dxr3_overlay_set_mode(&this->overlay, EM8300_OVERLAY_MODE_OFF); } vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) { dxr3_driver_t *this; char tmpstr[100]; - char *file_out; + const char *encoder; + char *available_encoders,*default_encoder; /* * allocate plugin struct @@ -673,20 +414,21 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) this->vo_driver.exit = dxr3_exit; this->config=config; + this->enhanced_mode = config->register_bool(config,"dxr3enc.alt_play_mode", 1, "Dxr3enc: use alternate Play mode","Enabling this option will utilise a slightly different play mode",NULL,NULL); /* open control device */ - devname = config->register_string (config, LOOKUP_DEV, DEFAULT_DEV,NULL,NULL,NULL,NULL); + this->devname = config->register_string (config, LOOKUP_DEV, DEFAULT_DEV,NULL,NULL,NULL,NULL); - printf("dxr3enc: Entering video init, devname=%s.\n",devname); - if ((this->fd_control = open(devname, O_WRONLY)) < 0) { + printf("dxr3enc: Entering video init, devname=%s.\n",this->devname); + if ((this->fd_control = open(this->devname, O_WRONLY)) < 0) { printf("dxr3enc: Failed to open control device %s (%s)\n", - devname, strerror(errno)); + this->devname, strerror(errno)); return 0; } /* output mpeg to file instead of dxr3? */ - file_out = config->register_string(config, "dxr3enc.outputfile", "<none>", "Dxr3enc: output file for debugging",NULL,NULL,NULL); + this->file_out = config->register_string(config, "dxr3enc.outputfile", "<none>", "Dxr3enc: output file for debugging",NULL,NULL,NULL); - if (file_out && strcmp(file_out, "<none>")) { - this->fd_video = open(file_out, O_WRONLY | O_CREAT); + if (this->file_out && strcmp(this->file_out, "<none>")) { + this->fd_video = open(this->file_out, O_WRONLY | O_CREAT); if (this->fd_video < 0) { perror("dxr3enc: failed to open output file"); return 0; @@ -694,19 +436,53 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) } else { /* open video device */ - snprintf (tmpstr, sizeof(tmpstr), "%s_mv", devname); + snprintf (tmpstr, sizeof(tmpstr), "%s_mv", this->devname); if ((this->fd_video = open (tmpstr, O_WRONLY | O_SYNC )) < 0) { printf("dxr3enc: failed to open video device %s (%s)\n", tmpstr, strerror(errno)); return 0; } -#if USE_MPEG_BUFFER || USE_MP1E - /* we have to close now and open the first time we get - * to display_frame. weird... */ + /* close now and and let the encoders reopen if they want */ close(this->fd_video); this->fd_video = -1; + } + + /* which encoder to use? Whadda we got? */ + default_encoder = 0; + /* memory leak... but config doesn't copy our help string :-( */ + available_encoders = malloc(256); + strcpy(available_encoders, "Mpeg1 encoder. Options: "); +#ifdef HAVE_LIBFAME + default_encoder = "fame"; + strcat(available_encoders, "\"fame\" (very fast, good quality) "); +#endif +#ifdef HAVE_LIBRTE + default_encoder = "rte"; + strcat(available_encoders, "\"rte\" (fast, high quality) "); +#endif + printf("dxr3enc: %s\n", available_encoders); + if (! default_encoder) { /* silly person; no encoder compiled in! */ + printf("dxr3enc: no mpeg1 encoder compiled in.\n"); + return 0; + } + encoder = config->register_string(config, "dxr3enc.encoder", + default_encoder, available_encoders, NULL, NULL, NULL); + this->enc = 0; +#ifdef HAVE_LIBRTE + if (! strcmp(encoder, "rte")) + if ( dxr3enc_rte_init(this) ) + return 0; #endif +#ifdef HAVE_LIBFAME + if (! strcmp(encoder, "fame")) + if ( dxr3enc_fame_init(this) ) + return 0; +#endif + if (! this->enc) { + printf("dxr3enc: encoder \"%s\" not supported.\n", encoder); + return 0; } + gather_screen_vars(this, visual_gen); /* default values */ @@ -720,26 +496,6 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) dxr3_overlay_buggy_preinit(&this->overlay, this->fd_control); } -#if USE_LIBFAME - /* fame context */ - fc = 0; -#endif -#if USE_FFMPEG - avc = 0; - avcodec_init(); - /* this register_all() is not really needed, but it gives us a good - * way to sniff out bad libavcodecs */ - avcodec_register_all(); - avcodec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO); - if (! avcodec) { - /* tell tale sign of bad libavcodec */ - printf("dxr3enc: can't find mpeg1 encoder! libavcodec is rotten!\n"); - return 0; - } -#endif -#if USE_MP1E - context = 0; -#endif return &this->vo_driver; } @@ -756,3 +512,393 @@ vo_info_t *get_video_out_plugin_info() return &vo_info_dxr3; } +#ifdef HAVE_LIBRTE + +static void mp1e_callback(rte_context *context, void *data, ssize_t size, + void* user_data) +{ + dxr3_driver_t *this = (dxr3_driver_t*)user_data; + em8300_register_t regs; + char tmpstr[128]; + + if (this->enhanced_mode) + { + regs.microcode_register=1; /* Yes, this is a MC Reg */ + regs.reg = MV_COMMAND; + regs.val=6; /* Mike's mystery number :-) */ + ioctl(this->fd_control, EM8300_IOCTL_WRITEREG, ®s); + } + if (this->fd_video < 0) { + snprintf (tmpstr, sizeof(tmpstr), "%s_mv", this->devname); + this->fd_video = open(tmpstr, O_WRONLY); + } + if (write(this->fd_video, data, size) < 0) + perror("dxr3enc: writing to video device"); +} + +static int rte_on_update_format(dxr3_driver_t *drv) +{ + rte_data_t *this = (rte_data_t*)drv->enc; + rte_context* context; + enum rte_mux_mode mux_mode = RTE_VIDEO; + /* rte_codec *codec; */ + enum rte_frame_rate frame_rate; + enum rte_pixformat pixformat; + int width, height; + double fps; + char tmpstr[128]; + + width = drv->video_width; + height = drv->video_height; + + if (this->context != 0) /* already done */ + return 0; + + this->context = rte_context_new (width, height, "mp1e", drv); + if (! this->context) { + printf("failed to get rte context.\n"); + return 1; + } + context = this->context; /* shortcut */ + rte_set_verbosity(context, 2); + /* rte_codec_set seems to create a program stream ... */ + /*codec = rte_codec_set(context, RTE_STREAM_VIDEO, 0, "mpeg1-video");*/ + rte_set_mode(context, mux_mode); + + /* start guessing the framerate */ + fps = drv->fps; + if (fabs(fps - 23.976) < 0.01) { /* NTSC-FILM */ + printf("dxr3enc: setting mpeg output framerate to NTSC-FILM (23.976 Hz))\n"); + frame_rate = RTE_RATE_1; + } + else if (fabs(fps - 24) < 0.01) { /* FILM */ + printf("dxr3enc: setting mpeg output framerate to FILM (24 Hz))\n"); + frame_rate = RTE_RATE_2; + } + else if (fabs(fps - 25) < 0.01) { /* PAL */ + printf("dxr3enc: setting mpeg output framerate to PAL (25 Hz)\n"); + frame_rate = RTE_RATE_3; + } + else if (fabs(fps - 29.97) < 0.01) { /* NTSC */ + printf("dxr3enc: setting mpeg output framerate to NTSC (29.97 Hz)\n"); + frame_rate = RTE_RATE_4; + } + else { /* go to PAL */ + frame_rate = RTE_RATE_3; + printf("dxr3enc: can't do %g Hz, using PAL\n", fps); + } + pixformat = (drv->format == IMGFMT_YV12 ? RTE_YUV420 : RTE_YUYV); + this->rte_bitrate=drv->config->register_range(drv->config,"dxr3enc.rte_bitrate",10000, 1000,20000, "Dxr3enc: rte mpeg output bitrate (kbit/s)",NULL,NULL,NULL); + this->rte_bitrate *= 1000; + if (!rte_set_video_parameters(context, pixformat, + context->width, context->height, frame_rate, + this->rte_bitrate, "I")) { + printf("dxr3enc: set_video_parameters failed: %s\n", + context->error); + rte_context_destroy(context); + context = 0; + return 1; + } + + /* paranoid; make sure we don't do motion searching */ + rte_set_motion(context, 0, 0); + rte_set_input(context, RTE_VIDEO, RTE_PUSH, FALSE, NULL, NULL, NULL); + snprintf (tmpstr, sizeof(tmpstr), "%s_mv", drv->devname); + //rte_set_output(context, NULL, NULL, tmpstr); + rte_set_output(context, mp1e_callback, NULL, NULL); + if (!rte_init_context(context)) { + printf("dxr3enc: cannot init the context: %s\n", + context->error); + rte_context_delete(context); + context = 0; + return 1; + } + /* do the sync'ing and start encoding */ + if (!rte_start_encoding(context)) { + printf("dxr3enc: cannot start encoding: %s\n", + context->error); + rte_context_delete(context); + context = 0; + return 1; + } + this->rte_ptr = rte_push_video_data(context, NULL, 0); + if (! this->rte_ptr) { + printf("dxr3enc: failed to get encoder buffer pointer.\n"); + return 1; + } + this->rte_time = 0.0; + this->rte_time_step = 1.0/fps; + + return 0; +} + +static int rte_on_display_frame( dxr3_driver_t* drv, dxr3_frame_t* frame ) +{ + int size; + rte_data_t* this = (rte_data_t*)drv->enc; + size = frame->width * frame->oheight; + if (frame->format == IMGFMT_YV12) + xine_fast_memcpy(this->rte_ptr, frame->real_base[0], size*3/2); + else + xine_fast_memcpy(this->rte_ptr, frame->real_base[0], size*2); + this->rte_time += this->rte_time_step; + this->rte_ptr = rte_push_video_data(this->context, this->rte_ptr, + this->rte_time); + frame->vo_frame.displayed(&frame->vo_frame); + return 0; +} + +static int rte_on_close( dxr3_driver_t *drv ) +{ + rte_data_t *this = (rte_data_t*)drv->enc; + if (this->context) { + rte_stop(this->context); + rte_context_delete(this->context); + this->context = 0; + } + free(this); + drv->enc = 0; + return 0; +} + +int dxr3enc_rte_init( dxr3_driver_t *drv ) +{ + rte_data_t* this; + if (! rte_init() ) { + printf("dxr3enc: failed to init librte\n"); + return 1; + } + this = malloc(sizeof(rte_data_t)); + if (!this) + return 1; + memset(this, 0, sizeof(rte_data_t)); + this->encoder_data.type = ENC_RTE; + this->context = 0; + this->encoder_data.on_update_format = rte_on_update_format; + this->encoder_data.on_frame_copy = 0; + this->encoder_data.on_display_frame = rte_on_display_frame; + this->encoder_data.on_close = rte_on_close; + drv->enc = (encoder_data_t*)this; + return 0; +} + +#endif + +#ifdef HAVE_LIBFAME + +static fame_parameters_t dummy_init_fp = FAME_PARAMETERS_INITIALIZER; + +static int fame_on_update_format(dxr3_driver_t *drv) +{ + fame_data_t *this = (fame_data_t*)drv->enc; + double fps; + + /* if YUY2 and dimensions changed, we need to re-allocate the + * internal YV12 buffer */ + if (this->buf) free(this->buf); + this->buf = 0; + this->out[0] = this->out[1] = this->out[2] = 0; + if (drv->format == IMGFMT_YUY2) { + int image_size = drv->video_width * drv->video_height; + + this->out[0] = malloc_aligned(16, image_size * 3/2, + (void*)&this->buf); + this->out[1] = this->out[0] + image_size; + this->out[2] = this->out[1] + image_size/4; + + /* fill with black (yuv 16,128,128) */ + memset(this->out[0], 16, image_size); + memset(this->out[1], 128, image_size/4); + memset(this->out[2], 128, image_size/4); + + printf("dxr3enc: Using YUY2->YV12 conversion\n"); + } + + if (!this->fc) + this->fc = fame_open(); + if (!this->fc) { + printf("Couldn't start the FAME library\n"); + return 1; + } + + if (!this->buffer) + this->buffer = (unsigned char *) malloc (DEFAULT_BUFFER_SIZE); + if (!this->buffer) { + printf("Couldn't allocate temp buffer for mpeg data\n"); + return 1; + } + + this->fp = dummy_init_fp; + this->fp.quality=drv->config->register_range(drv->config,"dxr3enc.fame_quality",90, 10,100, "Dxr3enc: fame mpeg encoding quality",NULL,NULL,NULL); + /* the really interesting bit is the quantizer scale. The formula + * below is copied from libfame's sources (could be changed in the + * future) */ + printf("dxr3enc: quality %d -> quant scale = %d\n", this->fp.quality, + 1 + (30*(100-this->fp.quality)+50)/100); + this->fp.width = drv->video_width; + this->fp.height = drv->video_height; + this->fp.profile = "mpeg1"; + this->fp.coding = "I"; + this->fp.verbose = 1; /* we don't need any more info.. thanks :) */ + + /* start guessing the framerate */ + fps = drv->fps; + if (fabs(fps - 25) < 0.01) { /* PAL */ + printf("dxr3enc: setting mpeg output framerate to PAL (25 Hz)\n"); + this->fp.frame_rate_num = 25; this->fp.frame_rate_den = 1; + } + else if (fabs(fps - 24) < 0.01) { /* FILM */ + printf("dxr3enc: setting mpeg output framerate to FILM (24 Hz))\n"); + this->fp.frame_rate_num = 24; this->fp.frame_rate_den = 1; + } + else if (fabs(fps - 23.976) < 0.01) { /* NTSC-FILM */ + printf("dxr3enc: setting mpeg output framerate to NTSC-FILM (23.976 Hz))\n"); + this->fp.frame_rate_num = 24000; this->fp.frame_rate_den = 1001; + } + else if (fabs(fps - 29.97) < 0.01) { /* NTSC */ + printf("dxr3enc: setting mpeg output framerate to NTSC (29.97 Hz)\n"); + this->fp.frame_rate_num = 30000; this->fp.frame_rate_den = 1001; + } + else { /* try 1/fps, if not legal, libfame will go to PAL */ + this->fp.frame_rate_num = (int)(fps + 0.5); this->fp.frame_rate_den = 1; + printf("dxr3enc: trying to set mpeg output framerate to %d Hz\n", + this->fp.frame_rate_num); + } + fame_init (this->fc, &this->fp, this->buffer, DEFAULT_BUFFER_SIZE); + + return 0; +} + +static int fame_on_frame_copy(dxr3_driver_t *drv, dxr3_frame_t *frame, + uint8_t **src) +{ + int size, i, j, hoffset, w2; + uint8_t *y, *u, *v, *yuy2; + fame_data_t *this = (fame_data_t*)drv->enc; + + if (frame->vo_frame.bad_frame) + return 0; + + if (frame->copy_calls == frame->height/16) { + /* shouldn't happen */ + printf("dxr3enc: Internal error. Too many calls to dxr3_frame_copy (%d)\n", + frame->copy_calls); + return 1; + } + + if (frame->vo_frame.format == IMGFMT_YUY2) { + /* need YUY2->YV12 conversion */ + if (! (this->out[0] && this->out[1] && this->out[2]) ) { + printf("dxr3enc: Internal error. Internal YV12 buffer not created.\n"); + return 1; + } + /* need conversion */ + hoffset = ((frame->oheight - frame->height)/32)*16; + y = this->out[0] + frame->width*(hoffset + frame->copy_calls*16); + u = this->out[1] + frame->width/2*(hoffset/2 + frame->copy_calls*8); + v = this->out[2] + frame->width/2*(hoffset/2 + frame->copy_calls*8); + yuy2 = src[0]; + w2 = frame->width/2; + /* we get 16 lines each time */ + for (i=0; i<16; i+=2) { + for (j=0; j<w2; j++) { + /* packed YUV 422 is: Y[i] U[i] Y[i+1] V[i] */ + *(y++) = *(yuy2++); + *(u++) = *(yuy2++); + *(y++) = *(yuy2++); + *(v++) = *(yuy2++); + } + /* down sampling */ + for (j=0; j<w2; j++) { + /* skip every second line for U and V */ + *(y++) = *(yuy2++); + yuy2++; + *(y++) = *(yuy2++); + yuy2++; + } + } + /* reset for encoder */ + y = this->out[0]; + u = this->out[1]; + v = this->out[2]; + } + else { /* YV12 */ + y = frame->real_base[0]; + u = frame->real_base[1]; + v = frame->real_base[2]; + } + + frame->copy_calls++; + + /* frame complete yet? */ + if (frame->copy_calls != frame->height/16) + return 0; + /* frame is complete: encode */ + this->yuv.y=y; + this->yuv.u=u; + this->yuv.v=v; + size = fame_encode_frame(this->fc, &this->yuv, NULL); + if (size >= DEFAULT_BUFFER_SIZE) { + printf("dxr3enc: warning, mpeg buffer too small!\n"); + size = DEFAULT_BUFFER_SIZE; + } + /* copy mpeg data to frame */ + xine_fast_memcpy(frame->mpeg, this->buffer, size); + frame->mpeg_size = size; + return 0; +} + + +static int fame_on_display_frame( dxr3_driver_t* drv, dxr3_frame_t* frame) +{ + char tmpstr[128]; + em8300_register_t regs; + if (drv->enhanced_mode) + { + regs.microcode_register=1; /* Yes, this is a MC Reg */ + regs.reg = MV_COMMAND; + regs.val=6; /* Mike's mystery number :-) */ + ioctl(drv->fd_control, EM8300_IOCTL_WRITEREG, ®s); + } + + if (drv->fd_video < 0) { + snprintf (tmpstr, sizeof(tmpstr), "%s_mv", drv->devname); + drv->fd_video = open(tmpstr, O_WRONLY); + } + if (write(drv->fd_video, frame->mpeg, frame->mpeg_size) < 0) + perror("dxr3enc: writing to video device"); + frame->vo_frame.displayed(&frame->vo_frame); + return 0; +} + +static int fame_on_close( dxr3_driver_t *drv ) +{ + fame_data_t *this = (fame_data_t*)drv->enc; + if (this->fc) { + fame_close(this->fc); + } + free(this); + drv->enc = 0; + return 0; +} + +int dxr3enc_fame_init( dxr3_driver_t *drv ) +{ + fame_data_t* this; + this = malloc(sizeof(fame_data_t)); + if (! this) + return 1; + memset(this, 0, sizeof(fame_data_t)); + this->encoder_data.type = ENC_FAME; + /* fame context */ + this->fc = 0; + this->encoder_data.on_update_format = fame_on_update_format; + this->encoder_data.on_frame_copy = fame_on_frame_copy; + this->encoder_data.on_display_frame = fame_on_display_frame; + this->encoder_data.on_close = fame_on_close; + drv->enc = (encoder_data_t*)this; + return 0; +} + +#endif + diff --git a/src/dxr3/dxr3_vo_encoder.h b/src/dxr3/dxr3_vo_encoder.h deleted file mode 100644 index 6635f2c2f..000000000 --- a/src/dxr3/dxr3_vo_encoder.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2000-2001 the xine project - * - * This file is part of xine, a unix video player. - * - * xine is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * xine is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * 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_vo_encoder.h,v 1.10 2001/12/02 21:14:51 hrm Exp $ - * - */ - -/************************************************************************* - * Dxr3 Encoding Plugin Configuration Options * - *************************************************************************/ - -/* 1: enable to buffer the mpeg1 stream; - * 0: write to mpeg device immediately; - * with 1 sync is better, but playback still not smooth (but see below) - * (not supported with mp1e; will disable automatically) */ -#define USE_MPEG_BUFFER 1 - -/* 1: write 6 to MV_COMMAND register. This seems to fix playback problems! - * 0: don't write to register */ -#define USE_MAGIC_REGISTER 1 - -/* select one mpeg encoder out of the three below */ -#define USE_LIBFAME 1 - -#define USE_FFMPEG 0 - -#define USE_MP1E 0 - -/************************************************************************* - * Dxr3 Encoding private stuff below - You shouldn't need to change this * - *************************************************************************/ - -/* buffer size for encoded mpeg1 stream; will hold one intra frame - * at 640x480 typical sizes are <50 kB. 512 kB should be plenty */ -#define DEFAULT_BUFFER_SIZE 512*1024 - -#if (USE_LIBFAME && USE_FFMPEG) || (USE_LIBFAME && USE_MP1E) || (USE_LIBFFMPEG && USE_MP1E) -# error "Configure only one mpeg encoder" -#endif - -#if USE_LIBFAME - #include <fame.h> - - /* some global stuff for libfame, could use some cleanup :-) */ - fame_parameters_t fp = FAME_PARAMETERS_INITIALIZER; - fame_yuv_t yuv; - fame_context_t *fc; /* needed for fame calls */ -#endif - -#if USE_FFMPEG - /* use libffmpeg */ - #include <ffmpeg/avcodec.h> - AVCodecContext *avc; - AVPicture avp; - AVCodec *avcodec; -#endif - -#if USE_MP1E - #define _GNU_SOURCE - #include <unistd.h> - #include <rte.h> - rte_context* context; /* handle for encoding */ - void* rte_ptr; /* buffer maintened by librte */ - double rte_time; /* frame time (s) */ - double rte_time_step; /* time per frame (s) */ - double rte_bitrate; /* mpeg out bitrate, default 2.3e6 bits/s */ -# undef USE_MPEG_BUFFER -# define USE_MPEG_BUFFER 0 -#endif - -/* mpeg1 buffer, used by both encoders */ -unsigned char *buffer; - diff --git a/src/dxr3/dxr3_vo_standard.c b/src/dxr3/dxr3_vo_standard.c index 9263cd71a..a466f04d2 100644 --- a/src/dxr3/dxr3_vo_standard.c +++ b/src/dxr3/dxr3_vo_standard.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_vo_standard.c,v 1.7 2001/11/25 20:21:25 hrm Exp $ + * $Id: dxr3_vo_standard.c,v 1.8 2001/12/11 02:26:59 hrm Exp $ * ******************************************************************* * Dummy video out plugin for the dxr3. Is responsible for setting * @@ -65,12 +65,8 @@ static void dummy_frame_dispose (vo_frame_t *frame_gen) { 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]); + if (frame->mem) + free (frame->mem); free(frame); } @@ -100,19 +96,10 @@ static void dxr3_update_frame_format (vo_driver_t *this_gen, 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) { + free (frame->mem); + frame->mem = 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; @@ -133,15 +120,13 @@ static void dxr3_update_frame_format (vo_driver_t *this_gen, 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]); + frame->vo_frame.base[0] = malloc_aligned(16,image_size*3/2, + (void**) &frame->mem); + frame->vo_frame.base[1] = frame->vo_frame.base[0] + image_size; + frame->vo_frame.base[2] = frame->vo_frame.base[1] + image_size/4; }else if (format == IMGFMT_YUY2) { frame->vo_frame.base[0] = malloc_aligned(16, image_size*2, - (void**)&frame->mem[0]); + (void**)&frame->mem); frame->vo_frame.base[1] = frame->vo_frame.base[2] = 0; } } @@ -202,11 +187,11 @@ vo_driver_t *init_video_out_plugin (config_values_t *config, void *visual_gen) this->config = config; /* open control device */ - devname = config->register_string (config, LOOKUP_DEV, DEFAULT_DEV, NULL,NULL,NULL,NULL); + this->devname = config->register_string (config, LOOKUP_DEV, DEFAULT_DEV, NULL,NULL,NULL,NULL); - if ((this->fd_control = open(devname, O_WRONLY)) < 0) { + if ((this->fd_control = open(this->devname, O_WRONLY)) < 0) { fprintf(stderr, "dxr3_vo: Failed to open control device %s (%s)\n", - devname, strerror(errno)); + this->devname, strerror(errno)); return 0; } |