mirror of
https://github.com/mpv-player/mpv
synced 2025-04-11 04:01:31 +00:00
added tv subsystem
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@2791 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
74aea030e1
commit
aabf596111
27
cfg-common.h
27
cfg-common.h
@ -1,4 +1,4 @@
|
|||||||
|
#ifdef MAIN_CONF /* this will be included in conf[] */
|
||||||
// ------------------------- stream options --------------------
|
// ------------------------- stream options --------------------
|
||||||
|
|
||||||
#ifdef USE_STREAM_CACHE
|
#ifdef USE_STREAM_CACHE
|
||||||
@ -79,3 +79,28 @@
|
|||||||
{"oldpp", "MPlayer was compiled without opendivx library", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0},
|
{"oldpp", "MPlayer was compiled without opendivx library", CONF_TYPE_PRINT, CONF_NOCFG, 0, 0},
|
||||||
#endif
|
#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
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
* config for cfgparser
|
* config for cfgparser
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "cfg-common.h"
|
||||||
|
|
||||||
#ifdef USE_FAKE_MONO
|
#ifdef USE_FAKE_MONO
|
||||||
extern int fakemono; // defined in dec_audio.c
|
extern int fakemono; // defined in dec_audio.c
|
||||||
#endif
|
#endif
|
||||||
@ -71,7 +73,9 @@ struct config conf[]={
|
|||||||
{"divx4opts", divx4opts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0},
|
{"divx4opts", divx4opts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0},
|
||||||
{"lameopts", lameopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0},
|
{"lameopts", lameopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0},
|
||||||
|
|
||||||
|
#define MAIN_CONF
|
||||||
#include "cfg-common.h"
|
#include "cfg-common.h"
|
||||||
|
#undef MAIN_CONF
|
||||||
|
|
||||||
// {"quiet", &quiet, CONF_TYPE_FLAG, 0, 0, 1},
|
// {"quiet", &quiet, CONF_TYPE_FLAG, 0, 0, 1},
|
||||||
{"verbose", &verbose, CONF_TYPE_INT, CONF_RANGE, 0, 100},
|
{"verbose", &verbose, CONF_TYPE_INT, CONF_RANGE, 0, 100},
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
* config for cfgparser
|
* config for cfgparser
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "cfg-common.h"
|
||||||
|
|
||||||
extern char *playlist_file;
|
extern char *playlist_file;
|
||||||
|
|
||||||
#ifdef HAVE_FBDEV
|
#ifdef HAVE_FBDEV
|
||||||
@ -214,7 +216,9 @@ struct config conf[]={
|
|||||||
{"skin", &skinName, CONF_TYPE_STRING, 0, 0, 0},
|
{"skin", &skinName, CONF_TYPE_STRING, 0, 0, 0},
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MAIN_CONF
|
||||||
#include "cfg-common.h"
|
#include "cfg-common.h"
|
||||||
|
#undef MAIN_CONF
|
||||||
|
|
||||||
{"quiet", &quiet, CONF_TYPE_FLAG, 0, 0, 1},
|
{"quiet", &quiet, CONF_TYPE_FLAG, 0, 0, 1},
|
||||||
{"verbose", &verbose, CONF_TYPE_INT, CONF_RANGE, 0, 100},
|
{"verbose", &verbose, CONF_TYPE_INT, CONF_RANGE, 0, 100},
|
||||||
|
@ -3,7 +3,7 @@ LIBNAME = libmpdemux.a
|
|||||||
|
|
||||||
include ../config.mak
|
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)
|
ifeq ($(STREAMING),yes)
|
||||||
SRCS += asf_streaming.c url.c http.c network.c
|
SRCS += asf_streaming.c url.c http.c network.c
|
||||||
endif
|
endif
|
||||||
|
@ -157,6 +157,9 @@ int demux_avi_fill_buffer_nini(demuxer_t *demux,demux_stream_t *ds);
|
|||||||
int demux_asf_fill_buffer(demuxer_t *demux);
|
int demux_asf_fill_buffer(demuxer_t *demux);
|
||||||
int demux_mov_fill_buffer(demuxer_t *demux,demux_stream_t* ds);
|
int demux_mov_fill_buffer(demuxer_t *demux,demux_stream_t* ds);
|
||||||
int demux_vivo_fill_buffer(demuxer_t *demux);
|
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){
|
int demux_fill_buffer(demuxer_t *demux,demux_stream_t *ds){
|
||||||
// Note: parameter 'ds' can be NULL!
|
// Note: parameter 'ds' can be NULL!
|
||||||
@ -170,6 +173,9 @@ int demux_fill_buffer(demuxer_t *demux,demux_stream_t *ds){
|
|||||||
case DEMUXER_TYPE_ASF: return demux_asf_fill_buffer(demux);
|
case DEMUXER_TYPE_ASF: return demux_asf_fill_buffer(demux);
|
||||||
case DEMUXER_TYPE_MOV: return demux_mov_fill_buffer(demux,ds);
|
case DEMUXER_TYPE_MOV: return demux_mov_fill_buffer(demux,ds);
|
||||||
case DEMUXER_TYPE_VIVO: return demux_vivo_fill_buffer(demux);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -344,6 +350,10 @@ demuxer_t* demux_open_avi(demuxer_t* demuxer);
|
|||||||
int mov_check_file(demuxer_t* demuxer);
|
int mov_check_file(demuxer_t* demuxer);
|
||||||
int mov_read_header(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){
|
demuxer_t* demux_open(stream_t *stream,int file_format,int audio_id,int video_id,int dvdsub_id){
|
||||||
|
|
||||||
@ -359,6 +369,17 @@ sh_video_t *sh_video=NULL;
|
|||||||
|
|
||||||
//printf("demux_open(%p,%d,%d,%d,%d) \n",stream,file_format,audio_id,video_id,dvdsub_id);
|
//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: =================
|
//=============== Try to open as AVI file: =================
|
||||||
if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_AVI){
|
if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_AVI){
|
||||||
demuxer=new_demuxer(stream,DEMUXER_TYPE_AVI,audio_id,video_id,dvdsub_id);
|
demuxer=new_demuxer(stream,DEMUXER_TYPE_AVI,audio_id,video_id,dvdsub_id);
|
||||||
@ -427,14 +448,6 @@ if(file_format==DEMUXER_TYPE_MPEG_ES){ // little hack, see above!
|
|||||||
mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_DetectedMPEGESfile);
|
mp_msg(MSGT_DEMUXER,MSGL_INFO,MSGTR_DetectedMPEGESfile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//=============== 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);
|
|
||||||
if(vivo_check_file(demuxer)){
|
|
||||||
mp_msg(MSGT_DEMUXER,MSGL_INFO,"Detected VIVO file format!\n");
|
|
||||||
file_format=DEMUXER_TYPE_VIVO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//=============== Try to open as MOV file: =================
|
//=============== Try to open as MOV file: =================
|
||||||
if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_MOV){
|
if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_MOV){
|
||||||
demuxer=new_demuxer(stream,DEMUXER_TYPE_MOV,audio_id,video_id,dvdsub_id);
|
demuxer=new_demuxer(stream,DEMUXER_TYPE_MOV,audio_id,video_id,dvdsub_id);
|
||||||
@ -443,6 +456,14 @@ if(file_format==DEMUXER_TYPE_UNKNOWN || file_format==DEMUXER_TYPE_MOV){
|
|||||||
file_format=DEMUXER_TYPE_MOV;
|
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);
|
||||||
|
if(vivo_check_file(demuxer)){
|
||||||
|
mp_msg(MSGT_DEMUXER,MSGL_INFO,"Detected VIVO file format!\n");
|
||||||
|
file_format=DEMUXER_TYPE_VIVO;
|
||||||
|
}
|
||||||
|
}
|
||||||
//=============== Unknown, exiting... ===========================
|
//=============== Unknown, exiting... ===========================
|
||||||
if(file_format==DEMUXER_TYPE_UNKNOWN){
|
if(file_format==DEMUXER_TYPE_UNKNOWN){
|
||||||
mp_msg(MSGT_DEMUXER,MSGL_ERR,MSGTR_FormatNotRecognized);
|
mp_msg(MSGT_DEMUXER,MSGL_ERR,MSGTR_FormatNotRecognized);
|
||||||
@ -531,6 +552,12 @@ switch(file_format){
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#ifdef USE_TV
|
||||||
|
case DEMUXER_TYPE_TV: {
|
||||||
|
demux_open_tv(demuxer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
} // switch(file_format)
|
} // switch(file_format)
|
||||||
pts_from_bps=0; // !!!
|
pts_from_bps=0; // !!!
|
||||||
return demuxer;
|
return demuxer;
|
||||||
@ -550,6 +577,10 @@ int demux_seek(demuxer_t *demuxer,float rel_seek_secs,int flags){
|
|||||||
if(!demuxer->seekable){
|
if(!demuxer->seekable){
|
||||||
if(demuxer->file_format==DEMUXER_TYPE_AVI)
|
if(demuxer->file_format==DEMUXER_TYPE_AVI)
|
||||||
mp_msg(MSGT_SEEK,MSGL_WARN,MSGTR_CantSeekRawAVI);
|
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
|
else
|
||||||
mp_msg(MSGT_SEEK,MSGL_WARN,MSGTR_CantSeekFile);
|
mp_msg(MSGT_SEEK,MSGL_WARN,MSGTR_CantSeekFile);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#define DEMUXER_TYPE_ASF 6
|
#define DEMUXER_TYPE_ASF 6
|
||||||
#define DEMUXER_TYPE_MOV 7
|
#define DEMUXER_TYPE_MOV 7
|
||||||
#define DEMUXER_TYPE_VIVO 8
|
#define DEMUXER_TYPE_VIVO 8
|
||||||
|
#define DEMUXER_TYPE_TV 9
|
||||||
|
|
||||||
#define DEMUXER_TIME_NONE 0
|
#define DEMUXER_TIME_NONE 0
|
||||||
#define DEMUXER_TIME_PTS 1
|
#define DEMUXER_TIME_PTS 1
|
||||||
|
@ -70,6 +70,11 @@ typedef struct {
|
|||||||
|
|
||||||
extern int vcd_get_track_end(int fd,int track);
|
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)
|
// Open a new stream (stdin/file/vcd/url)
|
||||||
|
|
||||||
stream_t* open_stream(char* filename,int vcd_track,int* file_format){
|
stream_t* open_stream(char* filename,int vcd_track,int* file_format){
|
||||||
@ -242,6 +247,19 @@ if(dvd_title){
|
|||||||
}
|
}
|
||||||
#endif
|
#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 ============
|
//============ Open STDIN ============
|
||||||
if(!strcmp(filename,"-")){
|
if(!strcmp(filename,"-")){
|
||||||
// read from stdin
|
// read from stdin
|
||||||
|
@ -52,6 +52,13 @@ int stream_fill_buffer(stream_t *s){
|
|||||||
} else len=-1; // error
|
} else len=-1; // error
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef USE_TV
|
||||||
|
case STREAMTYPE_TV:
|
||||||
|
{
|
||||||
|
len = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
default: len=0;
|
default: len=0;
|
||||||
}
|
}
|
||||||
@ -126,6 +133,11 @@ if(newpos==0 || newpos!=s->pos){
|
|||||||
if(stream_fill_buffer(s)<=0) break; // EOF
|
if(stream_fill_buffer(s)<=0) break; // EOF
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#ifdef USE_TV
|
||||||
|
case STREAMTYPE_TV:
|
||||||
|
s->pos=newpos; /* no sense */
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
// putchar('.');fflush(stdout);
|
// putchar('.');fflush(stdout);
|
||||||
//} else {
|
//} else {
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#define STREAMTYPE_STREAM 2 // same as FILE but no seeking (for stdin)
|
#define STREAMTYPE_STREAM 2 // same as FILE but no seeking (for stdin)
|
||||||
#define STREAMTYPE_DVD 3
|
#define STREAMTYPE_DVD 3
|
||||||
#define STREAMTYPE_MEMORY 4
|
#define STREAMTYPE_MEMORY 4
|
||||||
|
#define STREAMTYPE_TV 5
|
||||||
|
|
||||||
#define VCD_SECTOR_SIZE 2352
|
#define VCD_SECTOR_SIZE 2352
|
||||||
#define VCD_SECTOR_OFFS 24
|
#define VCD_SECTOR_OFFS 24
|
||||||
|
215
libmpdemux/tv.c
Normal file
215
libmpdemux/tv.c
Normal file
@ -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 */
|
62
libmpdemux/tv.h
Normal file
62
libmpdemux/tv.h
Normal file
@ -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 */
|
44
libmpdemux/tvi_def.h
Normal file
44
libmpdemux/tvi_def.h
Normal file
@ -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);
|
||||||
|
}
|
58
libmpdemux/tvi_dummy.c
Normal file
58
libmpdemux/tvi_dummy.c
Normal file
@ -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 */
|
267
libmpdemux/tvi_v4l.c
Normal file
267
libmpdemux/tvi_v4l.c
Normal file
@ -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 */
|
Loading…
Reference in New Issue
Block a user