Mercurial > mplayer.hg
changeset 2790:98769cea155c
added tv subsystem
author | alex |
---|---|
date | Fri, 09 Nov 2001 23:46:06 +0000 |
parents | 7023bf2ff439 |
children | 8ef2ab5cd47f |
files | cfg-common.h cfg-mencoder.h cfg-mplayer.h libmpdemux/Makefile libmpdemux/demuxer.c libmpdemux/demuxer.h libmpdemux/open.c libmpdemux/stream.c libmpdemux/stream.h libmpdemux/tv.c libmpdemux/tv.h libmpdemux/tvi_def.h libmpdemux/tvi_dummy.c libmpdemux/tvi_v4l.c |
diffstat | 14 files changed, 752 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/cfg-common.h Fri Nov 09 22:20:59 2001 +0000 +++ b/cfg-common.h Fri Nov 09 23:46:06 2001 +0000 @@ -1,4 +1,4 @@ - +#ifdef MAIN_CONF /* this will be included in conf[] */ // ------------------------- stream options -------------------- #ifdef USE_STREAM_CACHE @@ -79,3 +79,28 @@ {"oldpp", "MPlayer was compiled without opendivx library", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0}, #endif +#ifdef USE_TV + {"tv", tvopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0}, +#endif + +#else + +#include "config.h" + +#ifdef USE_TV +#include "libmpdemux/tv.h" + +struct config tvopts_conf[]={ + {"on", &tv_param_on, CONF_TYPE_FLAG, 0, 0, 1}, + {"driver", &tv_param_driver, CONF_TYPE_STRING, 0, 0, 0}, + {"device", &tv_param_device, CONF_TYPE_STRING, 0, 0, 0}, + {"freq", &tv_param_freq, CONF_TYPE_FLOAT, CONF_RANGE, 0, 2500000}, + {"channel", &tv_param_channel, CONF_TYPE_STRING, 0, 0, 0}, + {"norm", &tv_param_norm, CONF_TYPE_STRING, 0, 0, 0}, + {"width", &tv_param_width, CONF_TYPE_INT, 0, 0, 4096}, + {"height", &tv_param_height, CONF_TYPE_INT, 0, 0, 4096}, + {NULL, NULL, 0, 0, 0, 0} +}; +#endif + +#endif
--- a/cfg-mencoder.h Fri Nov 09 22:20:59 2001 +0000 +++ b/cfg-mencoder.h Fri Nov 09 23:46:06 2001 +0000 @@ -2,6 +2,8 @@ * config for cfgparser */ +#include "cfg-common.h" + #ifdef USE_FAKE_MONO extern int fakemono; // defined in dec_audio.c #endif @@ -71,7 +73,9 @@ {"divx4opts", divx4opts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0}, {"lameopts", lameopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0}, +#define MAIN_CONF #include "cfg-common.h" +#undef MAIN_CONF // {"quiet", &quiet, CONF_TYPE_FLAG, 0, 0, 1}, {"verbose", &verbose, CONF_TYPE_INT, CONF_RANGE, 0, 100},
--- a/cfg-mplayer.h Fri Nov 09 22:20:59 2001 +0000 +++ b/cfg-mplayer.h Fri Nov 09 23:46:06 2001 +0000 @@ -2,6 +2,8 @@ * config for cfgparser */ +#include "cfg-common.h" + extern char *playlist_file; #ifdef HAVE_FBDEV @@ -214,7 +216,9 @@ {"skin", &skinName, CONF_TYPE_STRING, 0, 0, 0}, #endif +#define MAIN_CONF #include "cfg-common.h" +#undef MAIN_CONF {"quiet", &quiet, CONF_TYPE_FLAG, 0, 0, 1}, {"verbose", &verbose, CONF_TYPE_INT, CONF_RANGE, 0, 100},
--- a/libmpdemux/Makefile Fri Nov 09 22:20:59 2001 +0000 +++ b/libmpdemux/Makefile Fri Nov 09 23:46:06 2001 +0000 @@ -3,7 +3,7 @@ include ../config.mak -SRCS = mp3_hdr.c video.c mpeg_hdr.c cache2.c asfheader.c aviheader.c aviprint.c aviwrite.c demux_asf.c demux_avi.c demux_mov.c demux_mpg.c demux_viv.c demuxer.c dvdauth.c open.c parse_es.c stream.c +SRCS = mp3_hdr.c video.c mpeg_hdr.c cache2.c asfheader.c aviheader.c aviprint.c aviwrite.c demux_asf.c demux_avi.c demux_mov.c demux_mpg.c demux_viv.c demuxer.c dvdauth.c open.c parse_es.c stream.c tv.c tvi_dummy.c tvi_v4l.c ifeq ($(STREAMING),yes) SRCS += asf_streaming.c url.c http.c network.c endif
--- a/libmpdemux/demuxer.c Fri Nov 09 22:20:59 2001 +0000 +++ b/libmpdemux/demuxer.c Fri Nov 09 23:46:06 2001 +0000 @@ -157,6 +157,9 @@ int demux_asf_fill_buffer(demuxer_t *demux); int demux_mov_fill_buffer(demuxer_t *demux,demux_stream_t* ds); int demux_vivo_fill_buffer(demuxer_t *demux); +#ifdef USE_TV +int demux_tv_fill_buffer(demuxer_t *demux); +#endif int demux_fill_buffer(demuxer_t *demux,demux_stream_t *ds){ // Note: parameter 'ds' can be NULL! @@ -170,6 +173,9 @@ case DEMUXER_TYPE_ASF: return demux_asf_fill_buffer(demux); case DEMUXER_TYPE_MOV: return demux_mov_fill_buffer(demux,ds); case DEMUXER_TYPE_VIVO: return demux_vivo_fill_buffer(demux); +#ifdef USE_TV + case DEMUXER_TYPE_TV: return demux_tv_fill_buffer(demux); +#endif } return 0; } @@ -344,6 +350,10 @@ int mov_check_file(demuxer_t* demuxer); int mov_read_header(demuxer_t* demuxer); +#ifdef USE_TV +/* tv ! */ +extern int tv_param_on; +#endif demuxer_t* demux_open(stream_t *stream,int file_format,int audio_id,int video_id,int dvdsub_id){ @@ -359,6 +369,17 @@ //printf("demux_open(%p,%d,%d,%d,%d) \n",stream,file_format,audio_id,video_id,dvdsub_id); +#ifdef USE_TV +//=============== Try to open as TV-input: ================= +if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_TV){ + demuxer=new_demuxer(stream,DEMUXER_TYPE_TV,audio_id,video_id,dvdsub_id); + if(tv_param_on==1) + { + mp_msg(MSGT_DEMUXER,MSGL_INFO,"Detected TV! ;-)\n"); + file_format=DEMUXER_TYPE_TV; + } +} +#endif //=============== Try to open as AVI file: ================= if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_AVI){ demuxer=new_demuxer(stream,DEMUXER_TYPE_AVI,audio_id,video_id,dvdsub_id); @@ -427,6 +448,14 @@ mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_DetectedMPEGESfile); } } +//=============== Try to open as MOV file: ================= +if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_MOV){ + demuxer=new_demuxer(stream,DEMUXER_TYPE_MOV,audio_id,video_id,dvdsub_id); + if(mov_check_file(demuxer)){ + mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_DetectedQTMOVfile); + file_format=DEMUXER_TYPE_MOV; + } +} //=============== Try to open as VIVO file: ================= if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_VIVO){ demuxer=new_demuxer(stream,DEMUXER_TYPE_VIVO,audio_id,video_id,dvdsub_id); @@ -435,14 +464,6 @@ file_format=DEMUXER_TYPE_VIVO; } } -//=============== Try to open as MOV file: ================= -if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_MOV){ - demuxer=new_demuxer(stream,DEMUXER_TYPE_MOV,audio_id,video_id,dvdsub_id); - if(mov_check_file(demuxer)){ - mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_DetectedQTMOVfile); - file_format=DEMUXER_TYPE_MOV; - } -} //=============== Unknown, exiting... =========================== if(file_format==DEMUXER_TYPE_UNKNOWN){ mp_msg(MSGT_DEMUXER,MSGL_ERR,MSGTR_FormatNotRecognized); @@ -531,6 +552,12 @@ } break; } +#ifdef USE_TV + case DEMUXER_TYPE_TV: { + demux_open_tv(demuxer); + break; + } +#endif } // switch(file_format) pts_from_bps=0; // !!! return demuxer; @@ -550,6 +577,10 @@ if(!demuxer->seekable){ if(demuxer->file_format==DEMUXER_TYPE_AVI) mp_msg(MSGT_SEEK,MSGL_WARN,MSGTR_CantSeekRawAVI); +#ifdef USE_TV + else if (demuxer->file_format==DEMUXER_TYPE_TV) + mp_msg(MSGT_SEEK,MSGL_WARN,"TV input isn't seekable! (probarly seeking will be for changing channels ;)\n"); +#endif else mp_msg(MSGT_SEEK,MSGL_WARN,MSGTR_CantSeekFile); return 0;
--- a/libmpdemux/demuxer.h Fri Nov 09 22:20:59 2001 +0000 +++ b/libmpdemux/demuxer.h Fri Nov 09 23:46:06 2001 +0000 @@ -11,6 +11,7 @@ #define DEMUXER_TYPE_ASF 6 #define DEMUXER_TYPE_MOV 7 #define DEMUXER_TYPE_VIVO 8 +#define DEMUXER_TYPE_TV 9 #define DEMUXER_TIME_NONE 0 #define DEMUXER_TIME_PTS 1
--- a/libmpdemux/open.c Fri Nov 09 22:20:59 2001 +0000 +++ b/libmpdemux/open.c Fri Nov 09 23:46:06 2001 +0000 @@ -70,6 +70,11 @@ extern int vcd_get_track_end(int fd,int track); +#ifdef USE_TV +#include "tv.h" +extern tvi_handle_t *tv_handler; +#endif + // Open a new stream (stdin/file/vcd/url) stream_t* open_stream(char* filename,int vcd_track,int* file_format){ @@ -242,6 +247,19 @@ } #endif +#ifdef USE_TV +//============ Check for TV-input ==== + if (tv_param_on==1) + { + stream=new_stream(-1,STREAMTYPE_TV); + tv_handler = tv_begin(); + if (!tv_handler) + return(NULL); + tv_init(tv_handler); + return(stream); + } +#endif + //============ Open STDIN ============ if(!strcmp(filename,"-")){ // read from stdin
--- a/libmpdemux/stream.c Fri Nov 09 22:20:59 2001 +0000 +++ b/libmpdemux/stream.c Fri Nov 09 23:46:06 2001 +0000 @@ -53,6 +53,13 @@ break; } #endif +#ifdef USE_TV + case STREAMTYPE_TV: + { + len = 0; + break; + } +#endif default: len=0; } if(len<=0){ s->eof=1; s->buf_pos=s->buf_len=0; return 0; } @@ -126,6 +133,11 @@ if(stream_fill_buffer(s)<=0) break; // EOF } break; +#ifdef USE_TV + case STREAMTYPE_TV: + s->pos=newpos; /* no sense */ + break; +#endif } // putchar('.');fflush(stdout); //} else {
--- a/libmpdemux/stream.h Fri Nov 09 22:20:59 2001 +0000 +++ b/libmpdemux/stream.h Fri Nov 09 23:46:06 2001 +0000 @@ -8,6 +8,7 @@ #define STREAMTYPE_STREAM 2 // same as FILE but no seeking (for stdin) #define STREAMTYPE_DVD 3 #define STREAMTYPE_MEMORY 4 +#define STREAMTYPE_TV 5 #define VCD_SECTOR_SIZE 2352 #define VCD_SECTOR_OFFS 24
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmpdemux/tv.c Fri Nov 09 23:46:06 2001 +0000 @@ -0,0 +1,215 @@ +/* + TV subsystem for libMPDemux by Alex + + API idea based on libvo2's + + UNDER HEAVY DEVELOPEMENT, DO NOT USE! :) +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include "config.h" + +#ifdef USE_TV +#include "tv.h" +#include "mp_msg.h" +#include "help_mp.h" + +#include "stream.h" +#include "demuxer.h" +#include "stheader.h" + +/* global! */ +tvi_handle_t *tv_handler; + +/* some default values */ +float tv_param_freq = 0.0; +char *tv_param_channel = "0"; +char *tv_param_norm = "pal"; +int tv_param_on = 0; +char *tv_param_device = NULL; +char *tv_param_driver = "dummy"; +int tv_param_width = -1; +int tv_param_height = -1; + + +/* ================== DEMUX_TV ===================== */ +/* + Return value: + 0 = EOF(?) or no stream + 1 = successfully read a packet +*/ +/* fill demux->video and demux->audio */ +int demux_tv_fill_buffer(demuxer_t *demux) +{ + int seq; + demux_stream_t *ds_video = NULL; + demux_packet_t *dp_video = NULL; + demux_stream_t *ds_audio = NULL; + demux_packet_t *dp_audio = NULL; + int len_video, len_audio; + + demux->filepos = -1; + + /* ================== ADD VIDEO PACKET =================== */ + len_video = tv_handler->functions->get_video_framesize(tv_handler->priv); + ds_video = demux->video; + + if (!ds_video) + { + dp_video = new_demux_packet(len_video); + tv_handler->functions->grab_video_frame(tv_handler->priv, dp_video->buffer, len_video); + dp_video->pos = demux->filepos; + ds_video->asf_packet = dp_video; + ds_video->asf_seq = seq; + } + else if (ds_video->asf_packet) + { + if (ds_video->asf_seq != seq) + { + ds_add_packet(ds_video, ds_video->asf_packet); + ds_video->asf_packet = NULL; + } + else + { + dp_video = ds_video->asf_packet; + dp_video->buffer = realloc(dp_video->buffer, dp_video->len+len_video); + tv_handler->functions->grab_video_frame(tv_handler->priv, dp_video->buffer+dp_video->len, len_video); + mp_dbg(MSGT_DEMUX,MSGL_DBG4, "video data appended %d+%d\n", dp_video->len, len_video); + dp_video->len += len_video; + } + } + + + /* ================== ADD AUDIO PACKET =================== */ + len_audio = tv_handler->functions->get_audio_framesize(tv_handler->priv); + ds_audio = demux->audio; + + if (!ds_audio) + { + dp_audio = new_demux_packet(len_audio); + tv_handler->functions->grab_audio_frame(tv_handler->priv, dp_audio->buffer, len_audio); + dp_audio->pos = demux->filepos; + ds_audio->asf_packet = dp_audio; + ds_audio->asf_seq = seq; + } + else if (ds_audio->asf_packet) + { + if (ds_audio->asf_seq != seq) + { + ds_add_packet(ds_audio, ds_audio->asf_packet); + ds_audio->asf_packet = NULL; + } + else + { + dp_audio = ds_audio->asf_packet; + dp_audio->buffer = realloc(dp_audio->buffer, dp_audio->len+len_audio); + tv_handler->functions->grab_audio_frame(tv_handler->priv, dp_audio->buffer+dp_audio->len, len_audio); + mp_dbg(MSGT_DEMUX,MSGL_DBG4, "audio data appended %d+%d\n", dp_audio->len, len_audio); + dp_audio->len += len_audio; + } + } + + return 1; +} + +int demux_open_tv(demuxer_t *demuxer) +{ + sh_video_t *sh_video; + tvi_handle_t *tvh = tv_handler; + tvi_functions_t *funcs = tvh->functions; + + sh_video = new_sh_video(demuxer,0); + +// sh->format=0x7476696e; /* "tvin" */ + if (funcs->control(tvh->priv, TVI_CONTROL_VID_GET_FORMAT, &sh_video->format) != TVI_CONTROL_TRUE) + sh_video->format = 0x00000000; + + if(!sh_video->fps) + { + if (funcs->control(tvh->priv, TVI_CONTROL_VID_GET_FPS, &sh_video->fps) != TVI_CONTROL_TRUE) + sh_video->fps = 24.0f; + } + sh_video->frametime = 1.0f/sh_video->fps; + + /* set width */ + if (tv_param_width != -1) + { + if (funcs->control(tvh->priv, TVI_CONTROL_VID_CHK_WIDTH, &tv_param_width) == TVI_CONTROL_TRUE) + { + funcs->control(tvh->priv, TVI_CONTROL_VID_SET_WIDTH, &tv_param_width); + sh_video->disp_w = tv_param_width; + } + else + { + printf("Unable set requested width: %d\n", tv_param_width); + funcs->control(tvh->priv, TVI_CONTROL_VID_GET_WIDTH, &sh_video->disp_w); + tv_param_width = sh_video->disp_w; + } + } + else + funcs->control(tvh->priv, TVI_CONTROL_VID_GET_WIDTH, &sh_video->disp_w); + + /* set height */ + if (tv_param_height != -1) + { + if (funcs->control(tvh->priv, TVI_CONTROL_VID_CHK_HEIGHT, &tv_param_height) == TVI_CONTROL_TRUE) + { + funcs->control(tvh->priv, TVI_CONTROL_VID_SET_HEIGHT, &tv_param_height); + sh_video->disp_h = tv_param_height; + } + else + { + printf("Unable set requested height: %d\n", tv_param_height); + funcs->control(tvh->priv, TVI_CONTROL_VID_GET_HEIGHT, &sh_video->disp_h); + tv_param_height = sh_video->disp_h; + } + } + else + funcs->control(tvh->priv, TVI_CONTROL_VID_GET_HEIGHT, &sh_video->disp_h); + + /* emulate BITMAPINFOHEADER */ + sh_video->bih = malloc(sizeof(BITMAPINFOHEADER)); + memset(sh_video->bih, 0, sizeof(BITMAPINFOHEADER)); + sh_video->bih->biSize = 40; + sh_video->bih->biWidth = sh_video->disp_w; + sh_video->bih->biHeight = sh_video->disp_h; + if (funcs->control(tvh->priv, TVI_CONTROL_VID_GET_PLANES, &sh_video->bih->biPlanes) != TVI_CONTROL_TRUE) + sh_video->bih->biPlanes = 1; + if (funcs->control(tvh->priv, TVI_CONTROL_VID_GET_BITS, &sh_video->bih->biBitCount) != TVI_CONTROL_TRUE) + sh_video->bih->biBitCount = 12; + sh_video->bih->biCompression = sh_video->format; + sh_video->bih->biSizeImage = sh_video->bih->biWidth * sh_video->bih->biHeight * 3; + + demuxer->video->sh = sh_video; + sh_video->ds = demuxer->video; + demuxer->video->id = 0; + + /* here comes audio init */ +} + +/* ================== STREAM_TV ===================== */ +tvi_handle_t *tv_begin() +{ + if (!strcmp(tv_param_driver, "dummy")) + return tvi_init_dummy(tv_param_device); + if (!strcmp(tv_param_driver, "v4l")) + return tvi_init_v4l(tv_param_device); + + mp_msg(MSGT_TV, MSGL_ERR, "No such driver: %s\n", tv_param_driver); + return(NULL); +} + +void tv_init(tvi_handle_t *tvi) +{ + printf("Using driver: %s\n", tvi->info->short_name); + printf(" name: %s\n", tvi->info->name); + printf(" author: %s\n", tvi->info->author); + if (tvi->info->comment) + printf(" comment: %s\n", tvi->info->comment); + + return tvi->functions->init(tvi->priv); +} +#endif /* USE_TV */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmpdemux/tv.h Fri Nov 09 23:46:06 2001 +0000 @@ -0,0 +1,62 @@ +#include "config.h" + +#ifdef USE_TV +extern float tv_param_freq; +extern char *tv_param_channel; +extern char *tv_param_norm; +extern int tv_param_on; +extern char *tv_param_device; +extern char *tv_param_driver; +extern int tv_param_width; +extern int tv_param_height; + +typedef struct tvi_info_s +{ + const char *name; + const char *short_name; + const char *author; + const char *comment; +} tvi_info_t; + +typedef struct tvi_functions_s +{ + int (*init)(); + int (*exit)(); + int (*control)(); + int (*grab_video_frame)(); + int (*get_video_framesize)(); + int (*grab_audio_frame)(); + int (*get_audio_framesize)(); +} tvi_functions_t; + +typedef struct tvi_handle_s { + tvi_info_t *info; + tvi_functions_t *functions; + void *priv; +} tvi_handle_t; + +#define TVI_CONTROL_FALSE 0 +#define TVI_CONTROL_TRUE 1 +#define TVI_CONTROL_NA -1 +#define TVI_CONTROL_UNKNOWN -2 + + +#define TVI_CONTROL_VID_GET_FPS 1 +#define TVI_CONTROL_VID_GET_PLANES 2 +#define TVI_CONTROL_VID_GET_BITS 3 +#define TVI_CONTROL_VID_CHK_BITS 4 +#define TVI_CONTROL_VID_SET_BITS 5 +#define TVI_CONTROL_VID_GET_FORMAT 6 +#define TVI_CONTROL_VID_CHK_FORMAT 7 +#define TVI_CONTROL_VID_SET_FORMAT 8 +#define TVI_CONTROL_VID_GET_WIDTH 9 +#define TVI_CONTROL_VID_CHK_WIDTH 10 +#define TVI_CONTROL_VID_SET_WIDTH 11 +#define TVI_CONTROL_VID_GET_HEIGHT 12 +#define TVI_CONTROL_VID_CHK_HEIGHT 13 +#define TVI_CONTROL_VID_SET_HEIGHT 14 + +#define TVI_CONTROL_TUN_GET_FREQ 100 +#define TVI_CONTROL_TUN_SET_FREQ 101 + +#endif /* USE_TV */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmpdemux/tvi_def.h Fri Nov 09 23:46:06 2001 +0000 @@ -0,0 +1,44 @@ +static int init(priv_t *priv); +static int exit(priv_t *priv); +static int control(priv_t *priv, int cmd, void *arg); +static int grab_video_frame(priv_t *priv, char *buffer, int len); +static int get_video_framesize(priv_t *priv); +static int grab_audio_frame(priv_t *priv, char *buffer, int len); +static int get_audio_framesize(priv_t *priv); + +static tvi_functions_t functions = +{ + init, + exit, + control, + grab_video_frame, + get_video_framesize, + grab_audio_frame, + get_audio_framesize +}; + +static tvi_handle_t *new_handle() +{ + tvi_handle_t *h = malloc(sizeof(tvi_handle_t)); + + if (!h) + return(NULL); + h->priv = malloc(sizeof(priv_t)); + if (!h->priv) + { + free(h); + return(NULL); + } + memset(h->priv, 0, sizeof(priv_t)); + h->info = &info; + h->functions = &functions; + return(h); +} + +static void free_handle(tvi_handle_t *h) +{ + if (h->priv) + free(h->priv); + if (h) + free(h); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmpdemux/tvi_dummy.c Fri Nov 09 23:46:06 2001 +0000 @@ -0,0 +1,58 @@ +#include <stdio.h> + +#include "config.h" + +#ifdef USE_TV +#include "tv.h" + +static tvi_info_t info = { + "NULL-TV", + "dummy", + "alex", + "non-completed" +}; + +typedef struct { +} priv_t; + +#include "tvi_def.h" + +tvi_handle_t *tvi_init_dummy(char *device) +{ + return new_handle(); +} + +static int init(priv_t *priv) +{ +} + +static int close(priv_t *priv) +{ +} + +static int control(priv_t *priv, int cmd, void *arg) +{ + return(TVI_CONTROL_UNKNOWN); +} + +static int grab_video_frame(priv_t *priv, char *buffer, int len) +{ + memset(buffer, 0x77, len); +} + +static int get_video_framesize(priv_t *priv) +{ + return 0; +} + +static int grab_audio_frame(priv_t *priv, char *buffer, int len) +{ + memset(buffer, 0x77, len); +} + +static int get_audio_framesize(priv_t *priv) +{ + return 0; +} + +#endif /* USE_TV */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmpdemux/tvi_v4l.c Fri Nov 09 23:46:06 2001 +0000 @@ -0,0 +1,267 @@ +#include "config.h" + +#ifdef USE_TV + +#include <stdio.h> +#include <errno.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <linux/videodev.h> +#include <unistd.h> +#include <sys/mman.h> + +#include "tv.h" + +static tvi_info_t info = { + "Video for Linux TV Input", + "v4l", + "alex", + "non-completed" +}; + +typedef struct { + char *video_device; + int fd; + struct video_capability capability; + struct video_channel *channels; + struct video_tuner tuner; + struct video_audio audio; + struct video_picture picture; + + int buffered; + struct video_mbuf mbuf; + unsigned int *mmap; + struct video_mmap *buf; + + int width; + int height; +} priv_t; + +#include "tvi_def.h" + +static const char *device_cap[] = { + "capture", "tuner", "teletext", "overlay", "chromakey", "clipping", + "frameram", "scales", "monochrome", NULL +}; + +tvi_handle_t *tvi_init_v4l(char *device) +{ + tvi_handle_t *h; + priv_t *priv; + + h = new_handle(); + if (!h) + return(NULL); + + priv = h->priv; + + if (!device) + { + priv->video_device = malloc(strlen("/dev/video0")); + strcpy(priv->video_device, &"/dev/video0"); + } + else + { + priv->video_device = malloc(strlen(device)); + strcpy(priv->video_device, device); + } + + return(h); +} + +static int init(priv_t *priv) +{ + int i; + + priv->fd = open(priv->video_device, O_RDONLY); + if (priv->fd == -1) + { + printf("v4l: open %s: %s\n", priv->video_device, strerror(errno)); + goto err; + } + + printf("fd: %d\n", priv->fd); + + /* get capabilities */ + if (ioctl(priv->fd, VIDIOCGCAP, &priv->capability) == -1) + { + printf("v4l: ioctl error: %s\n", strerror(errno)); + goto err; + } + + fcntl(priv->fd, F_SETFD, FD_CLOEXEC); + + printf("capabilites: "); + for (i = 0; device_cap[i] != NULL; i++) + if (priv->capability.type & (1 << i)) + printf(" %s", device_cap[i]); + printf("\n"); + printf(" type: %d\n", priv->capability.type); + printf(" size: %dx%d => %dx%d\n", + priv->capability.minwidth, priv->capability.minheight, + priv->capability.maxwidth, priv->capability.maxheight); + priv->width = priv->capability.minwidth; + priv->height = priv->capability.minheight; + printf(" channels: %d\n", priv->capability.channels); + + priv->channels = malloc(sizeof(struct video_channel)*priv->capability.channels); + memset(priv->channels, 0, sizeof(struct video_channel)*priv->capability.channels); + for (i = 0; i < priv->capability.channels; i++) + { + priv->channels[i].channel = i; + ioctl(priv->fd, VIDIOCGCHAN, &priv->channels[i]); + printf(" %s: tuners:%d %s%s %s%s\n", + priv->channels[i].name, + priv->channels[i].tuners, + (priv->channels[i].flags & VIDEO_VC_TUNER) ? "tuner " : "", + (priv->channels[i].flags & VIDEO_VC_AUDIO) ? "audio " : "", + (priv->channels[i].flags & VIDEO_TYPE_TV) ? "tv " : "", + (priv->channels[i].flags & VIDEO_TYPE_CAMERA) ? "camera " : ""); + } + + if (priv->capability.type & VID_TYPE_CAPTURE) + { + if (ioctl(priv->fd, VIDIOCGMBUF, &priv->mbuf) == 0) + { + printf("mbuf: size=%d, frames=%d (first offset: %p)\n", + priv->mbuf.size, priv->mbuf.frames, priv->mbuf.offsets[0]); + priv->mmap = mmap(0, priv->mbuf.size, PROT_READ|PROT_WRITE, + MAP_SHARED, priv->fd, 0); + if (priv->mmap == -1) + perror("mmap"); + } + else + priv->mmap = -1; + + if (priv->mmap != -1) + { + priv->buf = malloc(priv->mbuf.frames * sizeof(struct video_mmap)); + memset(priv->buf, 0, priv->mbuf.frames * sizeof(struct video_mmap)); + priv->buffered = 1; + } + else + priv->buffered = 0; + } + + printf("buffered: %d\n", priv->buffered); + + return(1); + +err: + if (priv->fd != -1) + close(priv->fd); + return(0); +} + +static int exit(priv_t *priv) +{ +} + +static int tune(priv_t *priv, int freq, int chan, int norm) +{ + if (freq) + { + ioctl(priv->fd, VIDIOCSFREQ, &freq); + return(1); + } + + if (chan && norm) + { + /* set channel & norm ! */ + } + + return(0); +} + +static int control(priv_t *priv, int cmd, void *arg) +{ + switch(cmd) + { + case TVI_CONTROL_VID_GET_FORMAT: + (int)*(void **)arg = 0x0; + return(TVI_CONTROL_TRUE); + case TVI_CONTROL_VID_GET_PLANES: + (int)*(void **)arg = 1; + return(TVI_CONTROL_TRUE); + case TVI_CONTROL_VID_GET_BITS: + (int)*(void **)arg = 12; + return(TVI_CONTROL_TRUE); + case TVI_CONTROL_VID_GET_WIDTH: + (int)*(void **)arg = priv->width; + return(TVI_CONTROL_TRUE); + case TVI_CONTROL_VID_CHK_WIDTH: + { + int req_width = (int)*(void **)arg; + + printf("req_width: %d\n", req_width); + if ((req_width > priv->capability.minwidth) && + (req_width < priv->capability.maxwidth)) + return(TVI_CONTROL_TRUE); + return(TVI_CONTROL_FALSE); + } + case TVI_CONTROL_VID_SET_WIDTH: + priv->width = (int)*(void **)arg; + return(TVI_CONTROL_TRUE); + case TVI_CONTROL_VID_GET_HEIGHT: + (int)*(void **)arg = priv->height; + return(TVI_CONTROL_TRUE); + case TVI_CONTROL_VID_CHK_HEIGHT: + { + int req_height = (int)*(void **)arg; + + printf("req_height: %d\n", req_height); + if ((req_height > priv->capability.minheight) && + (req_height < priv->capability.maxheight)) + return(TVI_CONTROL_TRUE); + return(TVI_CONTROL_FALSE); + } + case TVI_CONTROL_VID_SET_HEIGHT: + priv->height = (int)*(void **)arg; + return(TVI_CONTROL_TRUE); + + case TVI_CONTROL_TUN_SET_FREQ: + { + long freq = (long)*(void **)arg; /* shit: long -> freq */ + + printf("requested frequency: %f\n", freq); + if (ioctl(priv->fd, VIDIOCSFREQ, &freq) != -1) + return(TVI_CONTROL_TRUE); + return(TVI_CONTROL_FALSE); + } + } + + return(TVI_CONTROL_UNKNOWN); +} + +static int grab_video_frame(priv_t *priv, char *buffer, int len) +{ + priv->buf[0].frame = 0; + priv->buf[0].width = 320; + priv->buf[0].height = 240; + priv->buf[0].format = VIDEO_PALETTE_YUV422; + + if (ioctl(priv->fd, VIDIOCMCAPTURE, priv->buf) == -1) + { + printf("grab_video_frame failed: %s\n", strerror(errno)); + return 0; + } + + return 1; +} + +static int get_video_framesize(priv_t *priv) +{ + return 65536; +} + +static int grab_audio_frame(priv_t *priv, char *buffer, int len) +{ +} + +static int get_audio_framesize(priv_t *priv) +{ + return 65536; +} + +#endif /* USE_TV */