# HG changeset patch # User arpi # Date 1018608038 0 # Node ID 8cd761968f356fcbc35b637b8de4f7e166d80712 # Parent 124bfc43c04457340ec65d94750aecffa43d51b0 BSD-BT848 TV update patch by Charles Henrich - tvi interface changes, grab_audio/video now returns timestamp! - tv demuxer gets 'ds' hint too - some verbose skip/dup counters to mencoder - tvi_bsdbt848.c updates - aviwrite/mencoder size types int->off_t diff -r 124bfc43c044 -r 8cd761968f35 cfg-common.h --- a/cfg-common.h Fri Apr 12 10:17:24 2002 +0000 +++ b/cfg-common.h Fri Apr 12 10:40:38 2002 +0000 @@ -107,7 +107,11 @@ #ifdef USE_TV struct config tvopts_conf[]={ {"on", &tv_param_on, CONF_TYPE_FLAG, 0, 0, 1, NULL}, +#ifdef HAVE_TV_BSDBT848 + {"immediatemode", &tv_param_immediate, CONF_TYPE_FLAG, 0, 0, 0, NULL}, +#endif {"noaudio", &tv_param_noaudio, CONF_TYPE_FLAG, 0, 0, 1, NULL}, + {"audiorate", &tv_param_audiorate, CONF_TYPE_INT, 0, 0, 0, NULL}, {"driver", &tv_param_driver, CONF_TYPE_STRING, 0, 0, 0, NULL}, {"device", &tv_param_device, CONF_TYPE_STRING, 0, 0, 0, NULL}, {"freq", &tv_param_freq, CONF_TYPE_STRING, 0, 0, 0, NULL}, diff -r 124bfc43c044 -r 8cd761968f35 configure --- a/configure Fri Apr 12 10:17:24 2002 +0000 +++ b/configure Fri Apr 12 10:40:38 2002 +0000 @@ -3228,6 +3228,21 @@ fi fi +echocheck "ftello()" +# if we dont have ftello map it to ftell +cat > $TMPC << EOF +#include +int main (void) { ftello(stdin); return 0; } +EOF +_ftello=no +cc_check && _ftello=yes +if test "$_ftello" = yes ; then + _def_ftello='#define HAVE_FTELLO 1' +else + _def_ftello='#undef HAVE_FTELLO' +fi +echores "$_ftello" + # Determine OS dependent libs if cygwin ; then _confcygwin='TARGET_CYGWIN = yes' @@ -3507,6 +3522,13 @@ /* Define this if your system has the header file for the OSS sound interface */ $_def_sys_soundcard +/* Define this if your system uses ftello() for off_t seeking */ + +$_def_ftello +#ifndef HAVE_FTELLO +# define ftello(a) ftell(a) +#endif + /* Define this if your system has the "malloc.h" header file */ $_def_malloc diff -r 124bfc43c044 -r 8cd761968f35 libmpdemux/aviwrite.c --- a/libmpdemux/aviwrite.c Fri Apr 12 10:17:24 2002 +0000 +++ b/libmpdemux/aviwrite.c Fri Apr 12 10:40:38 2002 +0000 @@ -2,6 +2,7 @@ #include #include #include +#include #include "config.h" diff -r 124bfc43c044 -r 8cd761968f35 libmpdemux/aviwrite.h --- a/libmpdemux/aviwrite.h Fri Apr 12 10:17:24 2002 +0000 +++ b/libmpdemux/aviwrite.h Fri Apr 12 10:40:38 2002 +0000 @@ -10,7 +10,7 @@ int id; // stream no unsigned int ckid; // chunk id (00dc 01wb etc) double timer; - unsigned int size; + off_t size; // buffering: unsigned char *buffer; unsigned int buffer_size; diff -r 124bfc43c044 -r 8cd761968f35 libmpdemux/demuxer.c --- a/libmpdemux/demuxer.c Fri Apr 12 10:17:24 2002 +0000 +++ b/libmpdemux/demuxer.c Fri Apr 12 10:40:38 2002 +0000 @@ -214,7 +214,7 @@ extern tvi_handle_t *tv_handler; extern int tv_param_on; -extern int demux_tv_fill_buffer(demuxer_t *demux, tvi_handle_t *tvh); +extern int demux_tv_fill_buffer(demuxer_t *demux, demux_stream_t *ds, tvi_handle_t *tvh); extern int demux_open_tv(demuxer_t *demuxer, tvi_handle_t *tvh); #endif int demux_y4m_fill_buffer(demuxer_t *demux); @@ -242,7 +242,7 @@ case DEMUXER_TYPE_REAL: return demux_real_fill_buffer(demux); case DEMUXER_TYPE_NUV: return demux_nuv_fill_buffer(demux); #ifdef USE_TV - case DEMUXER_TYPE_TV: return demux_tv_fill_buffer(demux, tv_handler); + case DEMUXER_TYPE_TV: return demux_tv_fill_buffer(demux, ds, tv_handler); #endif case DEMUXER_TYPE_Y4M: return demux_y4m_fill_buffer(demux); case DEMUXER_TYPE_AUDIO: return demux_audio_fill_buffer(ds); diff -r 124bfc43c044 -r 8cd761968f35 libmpdemux/tv.c --- a/libmpdemux/tv.c Fri Apr 12 10:17:24 2002 +0000 +++ b/libmpdemux/tv.c Fri Apr 12 10:40:38 2002 +0000 @@ -6,7 +6,7 @@ API idea based on libvo2 Feb 19, 2002: Significant rewrites by Charles R. Henrich (henrich@msu.edu) - try to fix audio support, and bktr *BSD support. + to add support for audio, and bktr *BSD support. */ @@ -37,7 +37,11 @@ #include "frequencies.h" /* some default values */ +int tv_param_audiorate = 44100; int tv_param_noaudio = 0; +#ifdef HAVE_TV_BSDBT848 +int tv_param_immediate = 0; +#endif char *tv_param_freq = NULL; char *tv_param_channel = NULL; char *tv_param_norm = "pal"; @@ -58,57 +62,39 @@ */ /* fill demux->video and demux->audio */ -int demux_tv_fill_buffer(demuxer_t *demux, tvi_handle_t *tvh) +int demux_tv_fill_buffer(demuxer_t *demux, demux_stream_t *ds, tvi_handle_t *tvh) { demux_packet_t* dp; sh_video_t *sh_video = demux->video->sh; u_int len; - u_int cframe; int aframeswaiting; - len = cframe = -1; + len = 0; /* ================== ADD AUDIO PACKET =================== */ - if (tv_param_noaudio == 0 && + if (ds==demux->audio && tv_param_noaudio == 0 && tvh->functions->control(tvh->priv, TVI_CONTROL_IS_AUDIO, 0) == TVI_CONTROL_TRUE) { len = tvh->functions->get_audio_framesize(tvh->priv); - do { - dp=new_demux_packet(len); - aframeswaiting=tvh->functions->grab_audio_frame(tvh->priv, - dp->buffer,len); - dp->pts=tvh->seq/sh_video->fps; - dp->pos=tvh->seq*len; - ds_add_packet(demux->audio,dp); - - tvh->seq++; - - } while (aframeswaiting > 0); + dp=new_demux_packet(len); + dp->pts=tvh->functions->grab_audio_frame(tvh->priv, dp->buffer,len); + ds_add_packet(demux->audio,dp); } /* ================== ADD VIDEO PACKET =================== */ - if (tvh->functions->control(tvh->priv, + if (ds==demux->video && tvh->functions->control(tvh->priv, TVI_CONTROL_IS_VIDEO, 0) == TVI_CONTROL_TRUE) { - len = tvh->functions->get_video_framesize(tvh->priv); - - dp=new_demux_packet(len); - - cframe=tvh->functions->grab_video_frame(tvh->priv, dp->buffer, - len); - - if(tv_param_noaudio == 1) tvh->seq = cframe; - - dp->pos=tvh->seq*len; - dp->pts=tvh->seq/sh_video->fps; - - ds_add_packet(demux->video,dp); - } + len = tvh->functions->get_video_framesize(tvh->priv); + dp=new_demux_packet(len); + dp->pts=tvh->functions->grab_video_frame(tvh->priv, dp->buffer, len); + ds_add_packet(demux->video,dp); + } return 1; } @@ -190,7 +176,7 @@ if (funcs->control(tvh->priv, TVI_CONTROL_IS_TUNER, 0) != TVI_CONTROL_TRUE) { mp_msg(MSGT_TV, MSGL_WARN, "Selected input hasn't got a tuner!\n"); - goto start_device; + goto done; } /* select channel list */ @@ -214,7 +200,7 @@ if (tv_param_freq && tv_param_channel) { mp_msg(MSGT_TV, MSGL_WARN, "You can't set frequency and channel simultanly!\n"); - goto start_device; + goto done; } /* we need to set frequency */ @@ -251,9 +237,9 @@ } } -start_device: +done: /* also start device! */ - return(funcs->start(tvh->priv)); + return 1; } int demux_open_tv(demuxer_t *demuxer, tvi_handle_t *tvh) @@ -286,6 +272,15 @@ printf("fps: %f, frametime: %f\n", sh_video->fps, sh_video->frametime); +#ifdef HAVE_TV_BSDBT848 + /* If playback only mode, go to immediate mode, fail silently */ + if(tv_param_immediate == 1) + { + funcs->control(tvh->priv, TVI_CONTROL_IMMEDIATE, 0); + tv_param_noaudio = 1; + } +#endif + /* set width */ funcs->control(tvh->priv, TVI_CONTROL_VID_GET_WIDTH, &sh_video->disp_w); @@ -308,6 +303,10 @@ int sh_audio_format; /* yeah, audio is present */ + + funcs->control(tvh->priv, TVI_CONTROL_AUD_SET_SAMPLERATE, + &tv_param_audiorate); + if (funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_FORMAT, &audio_format) != TVI_CONTROL_TRUE) goto no_audio; @@ -334,7 +333,6 @@ } sh_audio = new_sh_audio(demuxer, 0); - sh_audio->wf = (WAVEFORMATEX *)malloc(sizeof(WAVEFORMATEX)); funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_SAMPLERATE, &sh_audio->samplerate); @@ -347,33 +345,21 @@ sh_audio->sample_format = audio_format; sh_audio->i_bps = sh_audio->o_bps = - sh_audio->samplerate * sh_audio->samplesize/8 * + sh_audio->samplerate * sh_audio->samplesize * sh_audio->channels; + // emulate WF for win32 codecs: + sh_audio->wf = (WAVEFORMATEX *)malloc(sizeof(WAVEFORMATEX)); sh_audio->wf->wFormatTag = sh_audio->format; sh_audio->wf->nChannels = sh_audio->channels; - switch(audio_format) - { - case AFMT_U8: - case AFMT_S8: - sh_audio->wf->wBitsPerSample = 8; - break; - case AFMT_U16_LE: - case AFMT_U16_BE: - case AFMT_S16_LE: - case AFMT_S16_BE: - sh_audio->wf->wBitsPerSample = 16; - break; - case AFMT_S32_LE: - case AFMT_S32_BE: - sh_audio->wf->wBitsPerSample = 32; - break; - } + sh_audio->wf->wBitsPerSample = sh_audio->samplesize * 8; sh_audio->wf->nSamplesPerSec = sh_audio->samplerate; - sh_audio->wf->nBlockAlign = sh_audio->wf->nAvgBytesPerSec; - sh_audio->wf->nAvgBytesPerSec = sh_audio->wf->nChannels * - sh_audio->samplesize/8 * - sh_audio->samplerate; + sh_audio->wf->nBlockAlign = sh_audio->samplesize * sh_audio->channels; + sh_audio->wf->nAvgBytesPerSec = sh_audio->i_bps; + + mp_msg(MSGT_DECVIDEO, MSGL_V, " TV audio: %d channels, %d bits, %d Hz\n", + sh_audio->wf->nChannels, sh_audio->wf->wBitsPerSample, + sh_audio->wf->nSamplesPerSec); demuxer->audio->sh = sh_audio; sh_audio->ds = demuxer->audio; @@ -381,7 +367,7 @@ } no_audio: - return(1); + return(funcs->start(tvh->priv)); } /* ================== STREAM_TV ===================== */ diff -r 124bfc43c044 -r 8cd761968f35 libmpdemux/tv.h --- a/libmpdemux/tv.h Fri Apr 12 10:17:24 2002 +0000 +++ b/libmpdemux/tv.h Fri Apr 12 10:40:38 2002 +0000 @@ -21,6 +21,8 @@ extern char *tv_param_outfmt; extern float tv_param_fps; extern int tv_param_noaudio; +extern int tv_param_immediate; +extern int tv_param_audiorate; typedef struct tvi_info_s { @@ -36,9 +38,12 @@ int (*uninit)(); int (*control)(); int (*start)(); - int (*grab_video_frame)(); + double (*grab_video_frame)(); +#ifdef HAVE_TV_BSDBT848 + double (*grabimmediate_video_frame)(); +#endif int (*get_video_framesize)(); - int (*grab_audio_frame)(); + double (*grab_audio_frame)(); int (*get_audio_framesize)(); } tvi_functions_t; @@ -67,6 +72,9 @@ #define TVI_CONTROL_IS_AUDIO 0x1 #define TVI_CONTROL_IS_VIDEO 0x2 #define TVI_CONTROL_IS_TUNER 0x3 +#ifdef HAVE_TV_BSDBT848 +#define TVI_CONTROL_IMMEDIATE 0x4 +#endif /* VIDEO controls */ #define TVI_CONTROL_VID_GET_FPS 0x101 @@ -107,6 +115,7 @@ #define TVI_CONTROL_AUD_GET_SAMPLERATE 0x302 #define TVI_CONTROL_AUD_GET_SAMPLESIZE 0x303 #define TVI_CONTROL_AUD_GET_CHANNELS 0x304 +#define TVI_CONTROL_AUD_SET_SAMPLERATE 0x305 /* SPECIFIC controls */ #define TVI_CONTROL_SPC_GET_INPUT 0x401 /* set input channel (tv,s-video,composite..) */ diff -r 124bfc43c044 -r 8cd761968f35 libmpdemux/tvi_bsdbt848.c --- a/libmpdemux/tvi_bsdbt848.c Fri Apr 12 10:17:24 2002 +0000 +++ b/libmpdemux/tvi_bsdbt848.c Fri Apr 12 10:40:38 2002 +0000 @@ -1,27 +1,32 @@ /* - (C)2002 Charles R. Henrich (henrich@msu.edu) - *BSD (hopefully, requires working driver!) BrookTree capture support. + (C)2002 Charles R. Henrich (henrich@msu.edu) + *BSD (hopefully, requires working driver!) BrookTree capture support. - Still in (active) development! + Still in (active) development! - v1.0 Feb 19 2002 First Release, need to add support for changing - audio parameters. + v1.1 Mar 13 2002 Fully functional, need to move ring buffer to + the kernel driver. + v1.0 Feb 19 2002 First Release, need to add support for changing + audio parameters. */ #include "config.h" #if defined(USE_TV) && defined(HAVE_TV_BSDBT848) +#define RINGSIZE 8 +#define FRAGSIZE 4096 /* (2^12 see SETFRAGSIZE below) */ + #define TRUE (1==1) #define FALSE (1==0) #define PAL_WIDTH 768 #define PAL_HEIGHT 576 -#define PAL_FPS 25 +#define PAL_FPS 25 #define NTSC_WIDTH 640 #define NTSC_HEIGHT 480 -#define NTSC_FPS 30 +#define NTSC_FPS 30 #include #include @@ -29,11 +34,14 @@ #include #include #include +#include +#include #include #include #include #include + #ifdef HAVE_SYS_SOUNDCARD_H #include #else @@ -45,52 +53,71 @@ /* information about this file */ static tvi_info_t info = { - "Brooktree848 Support", - "bt848", - "Charles Henrich", - "in development" + "Brooktree848 Support", + "bsdbt848", + "Charles Henrich", + "in development" }; +typedef struct { + int dirty; + double timestamp; + char *buf; +} RBFRAME; + /* private data's */ typedef struct { /* Audio */ - char *dspdev; - int dspready; - int dspfd; - int dspsamplesize; - int dspstereo; - int dspspeed; - int dspfmt; - int dspframesize; + char *dspdev; + int dspready; + int dspfd; + int dspsamplesize; + int dspstereo; + int dspspeed; + int dspfmt; + int dspframesize; + int dsprate; + long long dspbytesread; /* Video */ - char *btdev; - int videoready; - int btfd; - int source; - int maxfps; - int fps; - int iformat; - int maxheight; - int maxwidth; - struct meteor_geomet geom; - struct meteor_capframe capframe; - int buffersize; - unsigned char *buffer; - int currentframe; + char *btdev; + int videoready; + int btfd; + int source; + int maxfps; + int fps; + int iformat; + int maxheight; + int maxwidth; + struct meteor_geomet geom; + struct meteor_capframe capframe; + +/* Frame Buffer */ + + int framebufsize; + float timestamp; + int curpaintframe; + int curbufframe; + unsigned char *livebuf; + RBFRAME framebuf[RINGSIZE]; /* Inputs */ - int input; + int input; /* Tuner */ - char *tunerdev; - int tunerfd; - int tunerready; - u_long tunerfreq; - struct bktr_chnlset cset; + char *tunerdev; + int tunerfd; + int tunerready; + u_long tunerfreq; + struct bktr_chnlset cset; + +/* Other */ + + int immediatemode; + double starttime; } priv_t; @@ -98,10 +125,30 @@ static priv_t *G_private=NULL; +static int getinput(int innumber); static void processframe(int signal) { -G_private->currentframe++; +struct timeval curtime; + +if(G_private->immediatemode == TRUE) return; + +gettimeofday(&curtime, NULL); + +if(G_private->framebuf[G_private->curpaintframe].dirty == TRUE) + { + memcpy(G_private->framebuf[G_private->curpaintframe].buf, + G_private->livebuf, G_private->framebufsize); + + G_private->framebuf[G_private->curpaintframe].dirty = FALSE; + + G_private->framebuf[G_private->curpaintframe].timestamp = + curtime.tv_sec + curtime.tv_usec*.000001; + + G_private->curpaintframe++; + + if(G_private->curpaintframe >= RINGSIZE) G_private->curpaintframe = 0; + } return; } @@ -109,269 +156,295 @@ /* handler creator - entry point ! */ tvi_handle_t *tvi_init_bsdbt848(char *device) { - return(new_handle()); + return(new_handle()); } static int control(priv_t *priv, int cmd, void *arg) { - switch(cmd) - { + switch(cmd) + { /* Tuner Controls */ - case TVI_CONTROL_IS_TUNER: - if(priv->tunerready == FALSE) return TVI_CONTROL_FALSE; - return(TVI_CONTROL_TRUE); + case TVI_CONTROL_IS_TUNER: + if(priv->tunerready == FALSE) return TVI_CONTROL_FALSE; + return(TVI_CONTROL_TRUE); - case TVI_CONTROL_TUN_GET_FREQ: - { - if(ioctl(priv->tunerfd, TVTUNER_GETFREQ, &priv->tunerfreq) < 0) - { - perror("GETFREQ:ioctl"); - return(TVI_CONTROL_FALSE); - } + case TVI_CONTROL_TUN_GET_FREQ: + { + if(ioctl(priv->tunerfd, TVTUNER_GETFREQ, &priv->tunerfreq) < 0) + { + perror("GETFREQ:ioctl"); + return(TVI_CONTROL_FALSE); + } - (int)*(void **)arg = priv->tunerfreq; - return(TVI_CONTROL_TRUE); - } - - case TVI_CONTROL_TUN_SET_FREQ: - { - priv->tunerfreq = (int)*(void **)arg; + (int)*(void **)arg = priv->tunerfreq; + return(TVI_CONTROL_TRUE); + } + + case TVI_CONTROL_TUN_SET_FREQ: + { + priv->tunerfreq = (int)*(void **)arg; - if(ioctl(priv->tunerfd, TVTUNER_SETFREQ, &priv->tunerfreq) < 0) - { - perror("SETFREQ:ioctl"); - return(0); - } + if(ioctl(priv->tunerfd, TVTUNER_SETFREQ, &priv->tunerfreq) < 0) + { + perror("SETFREQ:ioctl"); + return(0); + } - return(TVI_CONTROL_TRUE); - } + return(TVI_CONTROL_TRUE); + } - case TVI_CONTROL_TUN_GET_TUNER: - case TVI_CONTROL_TUN_SET_TUNER: + case TVI_CONTROL_TUN_GET_TUNER: + case TVI_CONTROL_TUN_SET_TUNER: /* Inputs */ case TVI_CONTROL_SPC_GET_INPUT: - { - if(ioctl(priv->btfd, METEORGINPUT, &priv->input) < 0) - { - perror("GINPUT:ioctl"); - return(TVI_CONTROL_FALSE); - } + { + if(ioctl(priv->btfd, METEORGINPUT, &priv->input) < 0) + { + perror("GINPUT:ioctl"); + return(TVI_CONTROL_FALSE); + } - (int)*(void **)arg = priv->input; - return(TVI_CONTROL_TRUE); - } - + (int)*(void **)arg = priv->input; + return(TVI_CONTROL_TRUE); + } + case TVI_CONTROL_SPC_SET_INPUT: - { - priv->input = getinput((int)*(void **)arg); + { + priv->input = getinput((int)*(void **)arg); - if(ioctl(priv->btfd, METEORSINPUT, &priv->input) < 0) - { - perror("tunerfreq:ioctl"); - return(0); - } + if(ioctl(priv->btfd, METEORSINPUT, &priv->input) < 0) + { + perror("tunerfreq:ioctl"); + return(0); + } - return(TVI_CONTROL_TRUE); - } + return(TVI_CONTROL_TRUE); + } /* Audio Controls */ - case TVI_CONTROL_IS_AUDIO: - if(priv->dspready == FALSE) return TVI_CONTROL_FALSE; - return(TVI_CONTROL_TRUE); + case TVI_CONTROL_IS_AUDIO: + if(priv->dspready == FALSE) return TVI_CONTROL_FALSE; + return(TVI_CONTROL_TRUE); + + case TVI_CONTROL_AUD_GET_FORMAT: + { + (int)*(void **)arg = AFMT_S16_LE; + return(TVI_CONTROL_TRUE); + } + case TVI_CONTROL_AUD_GET_CHANNELS: + { + (int)*(void **)arg = 2; + return(TVI_CONTROL_TRUE); + } + case TVI_CONTROL_AUD_SET_SAMPLERATE: + { + int dspspeed = (int)*(void **)arg; - case TVI_CONTROL_AUD_GET_FORMAT: - { - (int)*(void **)arg = AFMT_S16_LE; - return(TVI_CONTROL_TRUE); - } - case TVI_CONTROL_AUD_GET_CHANNELS: - { - (int)*(void **)arg = 2; - return(TVI_CONTROL_TRUE); - } - case TVI_CONTROL_AUD_GET_SAMPLERATE: - { - (int)*(void **)arg = 44100; - return(TVI_CONTROL_TRUE); - } - case TVI_CONTROL_AUD_GET_SAMPLESIZE: - { - (int)*(void **)arg = priv->dspsamplesize; - return(TVI_CONTROL_TRUE); - } + if(ioctl(priv->dspfd, SNDCTL_DSP_SPEED, &dspspeed) == -1) + { + perror("invalidaudiorate"); + return(TVI_CONTROL_FALSE); + } + + priv->dspspeed = dspspeed; + + priv->dspframesize = priv->dspspeed*priv->dspsamplesize/8/ + priv->fps * (priv->dspstereo+1); + priv->dsprate = priv->dspspeed * priv->dspsamplesize/8* + (priv->dspstereo+1); + + return(TVI_CONTROL_TRUE); + } + case TVI_CONTROL_AUD_GET_SAMPLERATE: + { + (int)*(void **)arg = priv->dspspeed; + return(TVI_CONTROL_TRUE); + } + case TVI_CONTROL_AUD_GET_SAMPLESIZE: + { + (int)*(void **)arg = priv->dspsamplesize/8; + return(TVI_CONTROL_TRUE); + } /* Video Controls */ - case TVI_CONTROL_IS_VIDEO: - if(priv->videoready == FALSE) return TVI_CONTROL_FALSE; - return(TVI_CONTROL_TRUE); + case TVI_CONTROL_IS_VIDEO: + if(priv->videoready == FALSE) return TVI_CONTROL_FALSE; + return(TVI_CONTROL_TRUE); - case TVI_CONTROL_TUN_SET_NORM: - { - int req_mode = (int)*(void **)arg; + case TVI_CONTROL_TUN_SET_NORM: + { + int req_mode = (int)*(void **)arg; - priv->iformat = METEOR_FMT_AUTOMODE; + priv->iformat = METEOR_FMT_AUTOMODE; - if(req_mode == TV_NORM_PAL) - { - priv->iformat = METEOR_FMT_PAL; - priv->maxheight = PAL_HEIGHT; - priv->maxwidth = PAL_WIDTH; - priv->maxfps = PAL_FPS; - priv->fps = PAL_FPS; - - if(priv->fps > priv->maxfps) priv->fps = priv->maxfps; + if(req_mode == TV_NORM_PAL) + { + priv->iformat = METEOR_FMT_PAL; + priv->maxheight = PAL_HEIGHT; + priv->maxwidth = PAL_WIDTH; + priv->maxfps = PAL_FPS; + priv->fps = PAL_FPS; - if(priv->geom.rows > priv->maxheight) - { - priv->geom.rows = priv->maxheight; - } + if(priv->fps > priv->maxfps) priv->fps = priv->maxfps; - if(priv->geom.columns > priv->maxwidth) - { - priv->geom.columns = priv->maxwidth; - } - } + if(priv->geom.rows > priv->maxheight) + { + priv->geom.rows = priv->maxheight; + } - if(req_mode == TV_NORM_NTSC) - { - priv->iformat = METEOR_FMT_NTSC; - priv->maxheight = NTSC_HEIGHT; - priv->maxwidth = NTSC_WIDTH; - priv->maxfps = NTSC_FPS; - priv->fps = NTSC_FPS; + if(priv->geom.columns > priv->maxwidth) + { + priv->geom.columns = priv->maxwidth; + } + } - priv->dspframesize = priv->dspspeed*priv->dspsamplesize/8/ - priv->fps * (priv->dspstereo+1); - - if(priv->fps > priv->maxfps) priv->fps = priv->maxfps; - - if(priv->geom.rows > priv->maxheight) - { - priv->geom.rows = priv->maxheight; - } + if(req_mode == TV_NORM_NTSC) + { + priv->iformat = METEOR_FMT_NTSC; + priv->maxheight = NTSC_HEIGHT; + priv->maxwidth = NTSC_WIDTH; + priv->maxfps = NTSC_FPS; + priv->fps = NTSC_FPS; - if(priv->geom.columns > priv->maxwidth) - { - priv->geom.columns = priv->maxwidth; - } - } + priv->dspframesize = priv->dspspeed*priv->dspsamplesize/8/ + priv->fps * (priv->dspstereo+1); + priv->dsprate = priv->dspspeed * priv->dspsamplesize/8 * + (priv->dspstereo+1); - if(req_mode == TV_NORM_SECAM) priv->iformat = METEOR_FMT_SECAM; + if(priv->fps > priv->maxfps) priv->fps = priv->maxfps; - if(ioctl(priv->btfd, METEORSFMT, &priv->iformat) < 0) - { - perror("format:ioctl"); - return(TVI_CONTROL_FALSE); - } - - if(ioctl(priv->btfd, METEORSETGEO, &priv->geom) < 0) - { - perror("geo:ioctl"); - return(0); - } + if(priv->geom.rows > priv->maxheight) + { + priv->geom.rows = priv->maxheight; + } + + if(priv->geom.columns > priv->maxwidth) + { + priv->geom.columns = priv->maxwidth; + } + } + + if(req_mode == TV_NORM_SECAM) priv->iformat = METEOR_FMT_SECAM; - if(ioctl(priv->btfd, METEORSFPS, &priv->fps) < 0) - { - perror("fps:ioctl"); - return(0); - } + if(ioctl(priv->btfd, METEORSFMT, &priv->iformat) < 0) + { + perror("format:ioctl"); + return(TVI_CONTROL_FALSE); + } + + if(ioctl(priv->btfd, METEORSETGEO, &priv->geom) < 0) + { + perror("geo:ioctl"); + return(0); + } - return(TVI_CONTROL_TRUE); - } - - case TVI_CONTROL_VID_GET_FORMAT: - (int)*(void **)arg = IMGFMT_UYVY; - return(TVI_CONTROL_TRUE); - - case TVI_CONTROL_VID_SET_FORMAT: - { - int req_fmt = (int)*(void **)arg; + if(ioctl(priv->btfd, METEORSFPS, &priv->fps) < 0) + { + perror("fps:ioctl"); + return(0); + } - if(req_fmt != IMGFMT_UYVY) return(TVI_CONTROL_FALSE); + return(TVI_CONTROL_TRUE); + } + + case TVI_CONTROL_VID_GET_FORMAT: + (int)*(void **)arg = IMGFMT_UYVY; + return(TVI_CONTROL_TRUE); - return(TVI_CONTROL_TRUE); - } - case TVI_CONTROL_VID_SET_WIDTH: - priv->geom.columns = (int)*(void **)arg; + case TVI_CONTROL_VID_SET_FORMAT: + { + int req_fmt = (int)*(void **)arg; - if(priv->geom.columns > priv->maxwidth) - { - priv->geom.columns = priv->maxwidth; - } + if(req_fmt != IMGFMT_UYVY) return(TVI_CONTROL_FALSE); - if(ioctl(priv->btfd, METEORSETGEO, &priv->geom) < 0) - { - perror("width:ioctl"); - return(0); - } + return(TVI_CONTROL_TRUE); + } + case TVI_CONTROL_VID_SET_WIDTH: + priv->geom.columns = (int)*(void **)arg; + + if(priv->geom.columns > priv->maxwidth) + { + priv->geom.columns = priv->maxwidth; + } - return(TVI_CONTROL_TRUE); + if(ioctl(priv->btfd, METEORSETGEO, &priv->geom) < 0) + { + perror("width:ioctl"); + return(0); + } - case TVI_CONTROL_VID_GET_WIDTH: - (int)*(void **)arg = priv->geom.columns; - return(TVI_CONTROL_TRUE); + return(TVI_CONTROL_TRUE); - case TVI_CONTROL_VID_SET_HEIGHT: - priv->geom.rows = (int)*(void **)arg; + case TVI_CONTROL_VID_GET_WIDTH: + (int)*(void **)arg = priv->geom.columns; + return(TVI_CONTROL_TRUE); - if(priv->geom.rows > priv->maxheight) - { - priv->geom.rows = priv->maxheight; - } + case TVI_CONTROL_VID_SET_HEIGHT: + priv->geom.rows = (int)*(void **)arg; + + if(priv->geom.rows > priv->maxheight) + { + priv->geom.rows = priv->maxheight; + } - if(priv->geom.rows <= priv->maxheight / 2) - { - priv->geom.oformat |= METEOR_GEO_EVEN_ONLY; - } + if(priv->geom.rows <= priv->maxheight / 2) + { + priv->geom.oformat |= METEOR_GEO_EVEN_ONLY; + } - if(ioctl(priv->btfd, METEORSETGEO, &priv->geom) < 0) - { - perror("height:ioctl"); - return(0); - } + if(ioctl(priv->btfd, METEORSETGEO, &priv->geom) < 0) + { + perror("height:ioctl"); + return(0); + } - return(TVI_CONTROL_TRUE); + return(TVI_CONTROL_TRUE); - case TVI_CONTROL_VID_GET_HEIGHT: - (int)*(void **)arg = priv->geom.rows; - return(TVI_CONTROL_TRUE); + case TVI_CONTROL_VID_GET_HEIGHT: + (int)*(void **)arg = priv->geom.rows; + return(TVI_CONTROL_TRUE); - case TVI_CONTROL_VID_GET_FPS: - (int)*(void **)arg = (int)priv->fps; - return(TVI_CONTROL_TRUE); + case TVI_CONTROL_VID_GET_FPS: + (int)*(void **)arg = (int)priv->fps; + return(TVI_CONTROL_TRUE); /* - case TVI_CONTROL_VID_SET_FPS: - priv->fps = (int)*(void **)arg; + case TVI_CONTROL_VID_SET_FPS: + priv->fps = (int)*(void **)arg; - if(priv->fps > priv->maxfps) priv->fps = priv->maxfps; + if(priv->fps > priv->maxfps) priv->fps = priv->maxfps; - if(ioctl(priv->btfd, METEORSFPS, &priv->fps) < 0) - { - perror("fps:ioctl"); - return(0); - } + if(ioctl(priv->btfd, METEORSFPS, &priv->fps) < 0) + { + perror("fps:ioctl"); + return(0); + } - return(TVI_CONTROL_TRUE); + return(TVI_CONTROL_TRUE); */ - case TVI_CONTROL_VID_CHK_WIDTH: - case TVI_CONTROL_VID_CHK_HEIGHT: - return(TVI_CONTROL_TRUE); + case TVI_CONTROL_VID_CHK_WIDTH: + case TVI_CONTROL_VID_CHK_HEIGHT: + return(TVI_CONTROL_TRUE); - } - return(TVI_CONTROL_UNKNOWN); + case TVI_CONTROL_IMMEDIATE: + priv->immediatemode = TRUE; + return(TVI_CONTROL_TRUE); + } + + return(TVI_CONTROL_UNKNOWN); } static int init(priv_t *priv) { int marg; +int count; G_private = priv; /* Oooh, sick */ @@ -379,6 +452,7 @@ priv->videoready = TRUE; priv->btdev = strdup("/dev/bktr0"); +priv->immediatemode = FALSE; priv->iformat = METEOR_FMT_PAL; priv->maxheight = PAL_HEIGHT; priv->maxwidth = PAL_WIDTH; @@ -386,7 +460,9 @@ priv->source = METEOR_INPUT_DEV0; priv->fps = priv->maxfps; -priv->currentframe=0; +priv->starttime=0; +priv->curpaintframe=0; +priv->curbufframe=0; priv->geom.columns = priv->maxwidth; priv->geom.rows = priv->maxheight; @@ -396,49 +472,63 @@ priv->btfd = open(priv->btdev, O_RDONLY); if(priv->btfd < 0) - { - perror("bktr open"); - priv->videoready = FALSE; - } + { + perror("bktr open"); + priv->videoready = FALSE; + } if(priv->videoready == TRUE && ioctl(priv->btfd, METEORSFMT, &priv->iformat) < 0) - { - perror("FMT:ioctl"); - } + { + perror("FMT:ioctl"); + } if(priv->videoready == TRUE && ioctl(priv->btfd, METEORSINPUT, &priv->source) < 0) - { - perror("SINPUT:ioctl"); - } + { + perror("SINPUT:ioctl"); + } if(priv->videoready == TRUE && ioctl(priv->btfd, METEORSFPS, &priv->fps) < 0) - { - perror("SFPS:ioctl"); - } + { + perror("SFPS:ioctl"); + } if(priv->videoready == TRUE && ioctl(priv->btfd, METEORSETGEO, &priv->geom) < 0) - { - perror("SGEO:ioctl"); - } + { + perror("SGEO:ioctl"); + } if(priv->videoready == TRUE) - { - priv->buffersize = (priv->geom.columns * priv->geom.rows * 2); + { + priv->framebufsize = (priv->geom.columns * priv->geom.rows * 2); + + priv->livebuf = (u_char *)mmap((caddr_t)0, priv->framebufsize, PROT_READ, + MAP_SHARED, priv->btfd, (off_t)0); - priv->buffer = (u_char *)mmap((caddr_t)0, priv->buffersize, PROT_READ, - MAP_SHARED, priv->btfd, (off_t)0); + if(priv->livebuf == (u_char *) MAP_FAILED) + { + perror("mmap"); + priv->videoready = FALSE; + } - if(priv->buffer == (u_char *) MAP_FAILED) - { - perror("mmap"); - priv->videoready = FALSE; - } + for(count=0;countframebuf[count].buf = malloc(priv->framebufsize); - } + if(priv->framebuf[count].buf == NULL) + { + perror("framebufmalloc"); + priv->videoready = FALSE; + break; + } + + priv->framebuf[count].dirty = TRUE; + priv->framebuf[count].timestamp = 0; + } + } /* Tuner Configuration */ @@ -448,10 +538,10 @@ priv->tunerfd = open(priv->tunerdev, O_RDONLY); if(priv->tunerfd < 0) - { - perror("tune open"); - priv->tunerready = FALSE; - } + { + perror("tune open"); + priv->tunerready = FALSE; + } /* Audio Configuration */ @@ -461,33 +551,35 @@ priv->dspstereo = 1; priv->dspspeed = 44100; priv->dspfmt = AFMT_S16_LE; +priv->dspbytesread = 0; +priv->dsprate = priv->dspspeed * priv->dspsamplesize/8*(priv->dspstereo+1); priv->dspframesize = priv->dspspeed*priv->dspsamplesize/8/priv->fps * - (priv->dspstereo+1); + (priv->dspstereo+1); -if((priv->dspfd = open ("/dev/dsp", O_RDWR, 0)) < 0) - { - perror("/dev/dsp open"); - priv->dspready = FALSE; - } +if((priv->dspfd = open ("/dev/dsp", O_RDONLY, 0)) < 0) + { + perror("/dev/dsp open"); + priv->dspready = FALSE; + } -marg = (256 << 16) | 13; +marg = (256 << 16) | 12; if (ioctl(priv->dspfd, SNDCTL_DSP_SETFRAGMENT, &marg ) < 0 ) - { - perror("setfrag"); - priv->dspready = FALSE; - } + { + perror("setfrag"); + priv->dspready = FALSE; + } if((priv->dspready == TRUE) && - (ioctl(priv->dspfd, SNDCTL_DSP_SAMPLESIZE, &priv->dspsamplesize) == -1) || + ((ioctl(priv->dspfd, SNDCTL_DSP_SAMPLESIZE, &priv->dspsamplesize) == -1) || (ioctl(priv->dspfd, SNDCTL_DSP_STEREO, &priv->dspstereo) == -1) || (ioctl(priv->dspfd, SNDCTL_DSP_SPEED, &priv->dspspeed) == -1) || - (ioctl(priv->dspfd, SNDCTL_DSP_SETFMT, &priv->dspfmt) == -1)) - { - perror ("configuration of /dev/dsp failed"); - close(priv->dspfd); - priv->dspready = FALSE; - } + (ioctl(priv->dspfd, SNDCTL_DSP_SETFMT, &priv->dspfmt) == -1))) + { + perror ("configuration of /dev/dsp failed"); + close(priv->dspfd); + priv->dspready = FALSE; + } return(1); } @@ -495,8 +587,11 @@ /* that's the real start, we'got the format parameters (checked with control) */ static int start(priv_t *priv) { +int tmp; +struct timeval curtime; int marg; +fprintf(stderr,"START\n"); if(priv->videoready == FALSE) return(0); signal(SIGUSR1, processframe); @@ -505,18 +600,24 @@ marg = SIGUSR1; if(ioctl(priv->btfd, METEORSSIGNAL, &marg) < 0) - { - perror("METEORSSIGNAL failed"); - return(0); - } + { + perror("METEORSSIGNAL failed"); + return(0); + } + +read(priv->dspfd, &tmp, 2); + +gettimeofday(&curtime, NULL); + +priv->starttime = curtime.tv_sec + (curtime.tv_usec *.000001); marg = METEOR_CAP_CONTINOUS; if(ioctl(priv->btfd, METEORCAPTUR, &marg) < 0) - { - perror("METEORCAPTUR failed"); - return(0); - } + { + perror("METEORCAPTUR failed"); + return(0); + } return(1); } @@ -530,18 +631,18 @@ marg = METEOR_SIG_MODE_MASK; if(ioctl( priv->btfd, METEORSSIGNAL, &marg) < 0 ) - { - perror("METEORSSIGNAL"); - return(0); - } + { + perror("METEORSSIGNAL"); + return(0); + } marg = METEOR_CAP_STOP_CONT; if(ioctl(priv->btfd, METEORCAPTUR, &marg) < 0 ) - { - perror("METEORCAPTUR STOP"); - return(0); - } + { + perror("METEORCAPTUR STOP"); + return(0); + } close(priv->btfd); close(priv->dspfd); @@ -555,8 +656,9 @@ } -static int grab_video_frame(priv_t *priv, char *buffer, int len) +static double grabimmediate_video_frame(priv_t *priv, char *buffer, int len) { +struct timeval curtime; sigset_t sa_mask; if(priv->videoready == FALSE) return(0); @@ -569,9 +671,43 @@ sigsuspend(&sa_mask); alarm(0); -memcpy(buffer, priv->buffer, len); +memcpy(buffer, priv->livebuf, len); + +/* PTS = 0, show the frame NOW, this routine is only used in playback mode + without audio capture .. */ + +return(0); +} + +static double grab_video_frame(priv_t *priv, char *buffer, int len) +{ +struct timeval curtime; +double timestamp=0; +sigset_t sa_mask; + +if(priv->videoready == FALSE) return(0); -return(priv->currentframe); +if(priv->immediatemode == TRUE) + { + return grabimmediate_video_frame(priv, buffer, len); + } + +while(priv->framebuf[priv->curbufframe].dirty == TRUE) + { + alarm(1); + sigemptyset(&sa_mask); + sigsuspend(&sa_mask); + alarm(0); + } + +memcpy(buffer, priv->framebuf[priv->curbufframe].buf, len); +timestamp = priv->framebuf[priv->curbufframe].timestamp; +priv->framebuf[priv->curbufframe].dirty = TRUE; + +priv->curbufframe++; +if(priv->curbufframe >= RINGSIZE) priv->curbufframe = 0; + +return(timestamp-priv->starttime); } static int get_video_framesize(priv_t *priv) @@ -579,58 +715,88 @@ return(priv->geom.columns*priv->geom.rows*16/8); } -static int grab_audio_frame(priv_t *priv, char *buffer, int len) +static double grab_audio_frame(priv_t *priv, char *buffer, int len) { -struct audio_buf_info abi; +struct timeval curtime; +double curpts; +double timeskew; +int bytesavail; int bytesread; int ret; if(priv->dspready == FALSE) return 0; +gettimeofday(&curtime, NULL); + /* Get exactly one frame of audio, which forces video sync to audio.. */ bytesread=read(priv->dspfd, buffer, len); while(bytesread < len) - { - ret=read(priv->dspfd, &buffer[bytesread], len-bytesread); + { + ret=read(priv->dspfd, &buffer[bytesread], len-bytesread); - if(ret == -1) - { - perror("Audio read failed!"); - return 0; - } + if(ret == -1) + { + perror("Audio read failed!"); + return 0; + } + + bytesread+=ret; + } + +priv->dspbytesread += bytesread; + +curpts = curtime.tv_sec + curtime.tv_usec * .000001; - bytesread+=ret; - } +timeskew = priv->dspbytesread * 1.0 / priv->dsprate - (curpts-priv->starttime); -if(ioctl(priv->dspfd, SNDCTL_DSP_GETISPACE, &abi) < 0) - { - perror("abi:ioctl"); - return(TVI_CONTROL_FALSE); - } +if(timeskew > .125/priv->fps) + { + priv->starttime -= timeskew; + } +else + { + if(timeskew < -.125/priv->fps) + { + priv->starttime -= timeskew; + } + } -return(abi.bytes/len); +return(priv->dspbytesread * 1.0 / priv->dsprate); } static int get_audio_framesize(priv_t *priv) { +int bytesavail; + if(priv->dspready == FALSE) return 0; -return(priv->dspframesize); +if(ioctl(priv->dspfd, FIONREAD, &bytesavail) < 0) + { + perror("FIONREAD"); + return(TVI_CONTROL_FALSE); + } + +/* When mencoder wants audio data, it wants data.. + it wont go do anything else until it gets it :( */ + +if(bytesavail == 0) return FRAGSIZE; + +return(bytesavail); } static int getinput(int innumber) { switch(innumber) - { - case 0: return METEOR_INPUT_DEV0; /* RCA */ - case 1: return METEOR_INPUT_DEV1; /* Tuner */ - case 2: return METEOR_INPUT_DEV2; /* In 1 */ - case 3: return METEOR_INPUT_DEV3; /* In 2 */ - case 4: return METEOR_INPUT_DEV_RGB; /* RGB */ - case 5: return METEOR_INPUT_DEV_SVIDEO; /* SVid */ - } + { + case 0: return METEOR_INPUT_DEV0; /* RCA */ + case 1: return METEOR_INPUT_DEV1; /* Tuner */ + case 2: return METEOR_INPUT_DEV2; /* In 1 */ + case 3: return METEOR_INPUT_DEV3; /* In 2 */ + case 4: return METEOR_INPUT_DEV_RGB; /* RGB */ + case 5: return METEOR_INPUT_DEV_SVIDEO; /* SVid */ + } return 0; } diff -r 124bfc43c044 -r 8cd761968f35 libmpdemux/tvi_def.h --- a/libmpdemux/tvi_def.h Fri Apr 12 10:17:24 2002 +0000 +++ b/libmpdemux/tvi_def.h Fri Apr 12 10:40:38 2002 +0000 @@ -4,9 +4,12 @@ static int uninit(priv_t *priv); static int control(priv_t *priv, int cmd, void *arg); static int start(priv_t *priv); -static int grab_video_frame(priv_t *priv, char *buffer, int len); +static double grab_video_frame(priv_t *priv, char *buffer, int len); +#ifdef HAVE_TV_BSDBT848 +static double grabimmediate_video_frame(priv_t *priv, char *buffer, int len); +#endif static int get_video_framesize(priv_t *priv); -static int grab_audio_frame(priv_t *priv, char *buffer, int len); +static double grab_audio_frame(priv_t *priv, char *buffer, int len); static int get_audio_framesize(priv_t *priv); static tvi_functions_t functions = @@ -16,6 +19,9 @@ control, start, grab_video_frame, +#ifdef HAVE_TV_BSDBT848 + grabimmediate_video_frame, +#endif get_video_framesize, grab_audio_frame, get_audio_framesize diff -r 124bfc43c044 -r 8cd761968f35 libmpdemux/tvi_dummy.c --- a/libmpdemux/tvi_dummy.c Fri Apr 12 10:17:24 2002 +0000 +++ b/libmpdemux/tvi_dummy.c Fri Apr 12 10:40:38 2002 +0000 @@ -86,7 +86,15 @@ return(TVI_CONTROL_UNKNOWN); } -static int grab_video_frame(priv_t *priv, char *buffer, int len) +#ifdef HAVE_TV_BSDBT848 +static double grabimmediate_video_frame(priv_t *priv, char *buffer, int len) +{ + memset(buffer, 0xCC, len); + return(1); +} +#endif + +static double grab_video_frame(priv_t *priv, char *buffer, int len) { memset(buffer, 0x42, len); return(1); @@ -98,7 +106,7 @@ return(priv->width*priv->height*12/8); } -static int grab_audio_frame(priv_t *priv, char *buffer, int len) +static double grab_audio_frame(priv_t *priv, char *buffer, int len) { memset(buffer, 0x42, len); return(1); diff -r 124bfc43c044 -r 8cd761968f35 libmpdemux/tvi_v4l.c --- a/libmpdemux/tvi_v4l.c Fri Apr 12 10:17:24 2002 +0000 +++ b/libmpdemux/tvi_v4l.c Fri Apr 12 10:40:38 2002 +0000 @@ -63,7 +63,6 @@ struct video_mmap *buf; int nbuf; int queue; - int currentframe; /* audio */ int audio_id; @@ -807,13 +806,11 @@ return(TVI_CONTROL_UNKNOWN); } -static int grab_video_frame(priv_t *priv, char *buffer, int len) +static double grab_video_frame(priv_t *priv, char *buffer, int len) { int frame = priv->queue % priv->nbuf; int nextframe = (priv->queue+1) % priv->nbuf; - priv->currentframe++; - mp_dbg(MSGT_TV, MSGL_DBG2, "grab_video_frame(priv=%p, buffer=%p, len=%d)\n", priv, buffer, len); @@ -841,7 +838,7 @@ /* copy the actual frame */ memcpy(buffer, priv->mmap+priv->mbuf.offsets[frame], len); - return(priv->currentframe); + return(0); } static int get_video_framesize(priv_t *priv) @@ -849,7 +846,7 @@ return(priv->bytesperline * priv->height); } -static int grab_audio_frame(priv_t *priv, char *buffer, int len) +static double grab_audio_frame(priv_t *priv, char *buffer, int len) { int in_len = 0; // int max_tries = 128; @@ -874,7 +871,7 @@ } // printf("tries: %d\n", 128-max_tries); - return(in_len); + return 0; //(in_len); // FIXME! } static int get_audio_framesize(priv_t *priv) diff -r 124bfc43c044 -r 8cd761968f35 libmpdemux/video.c --- a/libmpdemux/video.c Fri Apr 12 10:17:24 2002 +0000 +++ b/libmpdemux/video.c Fri Apr 12 10:40:38 2002 +0000 @@ -291,6 +291,10 @@ sh_video->fps=1.0f/d; } } else + if(demuxer->file_format==DEMUXER_TYPE_TV && !force_fps){ + // TV has variable video frame rate, fixed audio... + frame_time=d_video->pts-pts1; + } else if(demuxer->file_format==DEMUXER_TYPE_MOV && !force_fps){ // .MOV files has no fixed FPS - just frame durations! frame_time=d_video->pts-pts1; diff -r 124bfc43c044 -r 8cd761968f35 mencoder.c --- a/mencoder.c Fri Apr 12 10:17:24 2002 +0000 +++ b/mencoder.c Fri Apr 12 10:40:38 2002 +0000 @@ -15,6 +15,7 @@ #include #include #include +#include #include "config.h" #include "mp_msg.h" @@ -212,6 +213,7 @@ } } + //--------------------------------------------------------------------------- void *vo_spudec=NULL; @@ -278,9 +280,17 @@ int file_format=DEMUXER_TYPE_UNKNOWN; int i; +uint32_t ptimer_start; +uint32_t audiorate=0; +uint32_t videorate=0; +uint32_t audiosamples=1; +uint32_t videosamples=1; +uint32_t skippedframes=0; +uint32_t duplicatedframes=0; + aviwrite_stream_t* mux_a=NULL; aviwrite_stream_t* mux_v=NULL; -int muxer_f_size=0; +off_t muxer_f_size=0; #ifdef HAVE_MP3LAME lame_global_flags *lame; @@ -714,6 +724,13 @@ demux_seek(demuxer, d, 1); } +if(tv_param_on == 1) + { + fprintf(stderr,"Forcing audio preload to 0, max pts correction to 0\n"); + audio_preload = 0.0; + default_max_pts_correction = 0; + } + while(!eof){ float frame_time=0; @@ -724,7 +741,7 @@ int in_size; int skip_flag=0; // 1=skip -1=duplicate - if((end_at_type == END_AT_SIZE && end_at <= ftell(muxer_f)) || + if((end_at_type == END_AT_SIZE && end_at <= ftello(muxer_f)) || (end_at_type == END_AT_TIME && end_at < sh_video->timer)) break; @@ -737,6 +754,9 @@ // get audio: while(mux_a->timer-audio_preloadtimer){ int len=0; + + ptimer_start = GetTimerMS(); + if(mux_a->h.dwSampleSize){ // CBR - copy 0.5 sec of audio switch(mux_a->codec){ @@ -796,14 +816,19 @@ mux_a->buffer_len-=len; memcpy(mux_a->buffer,mux_a->buffer+len,mux_a->buffer_len); } + + + audiosamples++; + audiorate+= (GetTimerMS() - ptimer_start); } } // get video frame! + in_size=video_read_frame(sh_video,&frame_time,&start,force_fps); if(in_size<0){ eof=1; break; } sh_video->timer+=frame_time; ++decoded_frameno; - + v_timer_corr-=frame_time-(float)mux_v->h.dwScale/mux_v->h.dwRate; if(demuxer2){ // 3-pass encoding, read control file (frameno.avi) @@ -816,7 +841,7 @@ if(len==4) next_frameno=start[0]; } if(eof) break; - if(skip_flag) printf("!!!!!!!!!!!!\n"); + // if(skip_flag) printf("!!!!!!!!!!!!\n"); skip_flag=next_frameno-decoded_frameno; // find next frame: while(next_frameno<=decoded_frameno){ @@ -868,6 +893,8 @@ } #endif +ptimer_start = GetTimerMS(); + switch(mux_v->codec){ case VCODEC_COPY: mux_v->buffer=start; @@ -884,17 +911,22 @@ if(!blit_frame) aviwrite_write_chunk(muxer,mux_v,muxer_f,0,0); // empty. } +videosamples++; +videorate+=(GetTimerMS() - ptimer_start); + if(skip_flag<0){ // duplicate frame - printf("\nduplicate %d frame(s)!!! \n",-skip_flag); + if(!tv_param_on && !verbose) printf("\nduplicate %d frame(s)!!! \n",-skip_flag); while(skip_flag<0){ + duplicatedframes++; aviwrite_write_chunk(muxer,mux_v,muxer_f,0,0); ++skip_flag; } } else if(skip_flag>0){ // skip frame - printf("\nskip frame!!! \n"); + if(!tv_param_on && !verbose) printf("\nskip frame!!! \n"); + skippedframes++; --skip_flag; } @@ -961,6 +993,19 @@ (int)demuxer->filepos, (int)demuxer->movi_end); #else + if(verbose) { + mp_msg(MSGT_AVSYNC,MSGL_STATUS,"Pos:%6.1fs %6df (%2d%%) %3dfps Trem:%4dmin %3dmb A-V:%5.3f [%d:%d] A/Vms %d/%d D/S %d/%d \r", + mux_v->timer, decoded_frameno, (int)(p*100), + (t>1) ? (int)(decoded_frameno/t) : 0, + (p>0.001) ? (int)((t/p-t)/60) : 0, + (p>0.001) ? (int)(ftello(muxer_f)/p/1024/1024) : 0, + v_pts_corr, + (mux_v->timer>1) ? (int)(mux_v->size/mux_v->timer/125) : 0, + (mux_a && mux_a->timer>1) ? (int)(mux_a->size/mux_a->timer/125) : 0, + audiorate/audiosamples, videorate/videosamples, + duplicatedframes, skippedframes + ); + } else mp_msg(MSGT_AVSYNC,MSGL_STATUS,"Pos:%6.1fs %6df (%2d%%) %3dfps Trem:%4dmin %3dmb A-V:%5.3f [%d:%d]\r", mux_v->timer, decoded_frameno, (int)(p*100), (t>1) ? (int)(decoded_frameno/t) : 0, @@ -972,7 +1017,6 @@ ); #endif } - fflush(stdout); @@ -992,7 +1036,7 @@ printf("\nWriting AVI index...\n"); aviwrite_write_index(muxer,muxer_f); -muxer_f_size=ftell(muxer_f); +muxer_f_size=ftello(muxer_f); printf("Fixup AVI header...\n"); fseek(muxer_f,0,SEEK_SET); aviwrite_write_header(muxer,muxer_f); // update header @@ -1005,10 +1049,10 @@ } printf("\nVideo stream: %8.3f kbit/s (%d bps) size: %d bytes %5.3f secs %d frames\n", - (float)(mux_v->size/mux_v->timer*8.0f/1000.0f), (int)(mux_v->size/mux_v->timer), mux_v->size, (float)mux_v->timer, decoded_frameno); + (float)(mux_v->size/mux_v->timer*8.0f/1000.0f), (int)(mux_v->size/mux_v->timer), (int)mux_v->size, (float)mux_v->timer, decoded_frameno); if(sh_audio) printf("\nAudio stream: %8.3f kbit/s (%d bps) size: %d bytes %5.3f secs\n", - (float)(mux_a->size/mux_a->timer*8.0f/1000.0f), (int)(mux_a->size/mux_a->timer), mux_a->size, (float)mux_a->timer); + (float)(mux_a->size/mux_a->timer*8.0f/1000.0f), (int)(mux_a->size/mux_a->timer), (int)mux_a->size, (float)mux_a->timer); if(stream) free_stream(stream); // kill cache thread diff -r 124bfc43c044 -r 8cd761968f35 mplayer.c --- a/mplayer.c Fri Apr 12 10:17:24 2002 +0000 +++ b/mplayer.c Fri Apr 12 10:40:38 2002 +0000 @@ -546,6 +546,10 @@ #endif +#ifdef HAVE_TV_BSDBT848 + tv_param_immediate = 1; +#endif + if ( argv[0] ) if(!strcmp(argv[0],"gmplayer") || (strrchr(argv[0],'/') && !strcmp(strrchr(argv[0],'/'),"/gmplayer") ) )