mirror of
https://github.com/mpv-player/mpv
synced 2025-03-24 12:22:25 +00:00
tv update
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@2803 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
31dc283826
commit
fc363d39bc
@ -94,11 +94,12 @@ 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},
|
||||
{"freq", &tv_param_freq, CONF_TYPE_INT, 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},
|
||||
{"input", &tv_param_input, CONF_TYPE_INT, 0, 0, 20},
|
||||
{NULL, NULL, 0, 0, 0, 0}
|
||||
};
|
||||
#endif
|
||||
|
@ -158,7 +158,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);
|
||||
#include "tv.h"
|
||||
extern tvi_handle_t *tv_handler;
|
||||
int demux_tv_fill_buffer(demuxer_t *demux, tvi_handle_t *tvh);
|
||||
#endif
|
||||
|
||||
int demux_fill_buffer(demuxer_t *demux,demux_stream_t *ds){
|
||||
@ -174,7 +176,7 @@ int demux_fill_buffer(demuxer_t *demux,demux_stream_t *ds){
|
||||
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);
|
||||
case DEMUXER_TYPE_TV: return demux_tv_fill_buffer(demux, tv_handler);
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
@ -554,7 +556,7 @@ switch(file_format){
|
||||
}
|
||||
#ifdef USE_TV
|
||||
case DEMUXER_TYPE_TV: {
|
||||
demux_open_tv(demuxer);
|
||||
demux_open_tv(demuxer, tv_handler);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
@ -72,7 +72,7 @@ extern int vcd_get_track_end(int fd,int track);
|
||||
|
||||
#ifdef USE_TV
|
||||
#include "tv.h"
|
||||
extern tvi_handle_t *tv_handler;
|
||||
tvi_handle_t *tv_handler;
|
||||
#endif
|
||||
|
||||
// Open a new stream (stdin/file/vcd/url)
|
||||
@ -251,12 +251,13 @@ if(dvd_title){
|
||||
//============ Check for TV-input ====
|
||||
if (tv_param_on==1)
|
||||
{
|
||||
stream=new_stream(-1,STREAMTYPE_TV);
|
||||
stream = new_stream(-1,STREAMTYPE_TV);
|
||||
tv_handler = tv_begin();
|
||||
if (!tv_handler)
|
||||
return(NULL);
|
||||
tv_init(tv_handler);
|
||||
return(stream);
|
||||
if (tv_init(tv_handler) == 1)
|
||||
return(stream);
|
||||
return(NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
168
libmpdemux/tv.c
168
libmpdemux/tv.c
@ -13,19 +13,16 @@
|
||||
#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;
|
||||
#include "tv.h"
|
||||
|
||||
/* some default values */
|
||||
float tv_param_freq = 0.0;
|
||||
unsigned long tv_param_freq = 0;
|
||||
char *tv_param_channel = "0";
|
||||
char *tv_param_norm = "pal";
|
||||
int tv_param_on = 0;
|
||||
@ -33,6 +30,7 @@ char *tv_param_device = NULL;
|
||||
char *tv_param_driver = "dummy";
|
||||
int tv_param_width = -1;
|
||||
int tv_param_height = -1;
|
||||
int tv_param_input = 0; /* used in v4l and bttv */
|
||||
|
||||
|
||||
/* ================== DEMUX_TV ===================== */
|
||||
@ -42,25 +40,32 @@ int tv_param_height = -1;
|
||||
1 = successfully read a packet
|
||||
*/
|
||||
/* fill demux->video and demux->audio */
|
||||
int demux_tv_fill_buffer(demuxer_t *demux)
|
||||
int demux_tv_fill_buffer(demuxer_t *demux, tvi_handle_t *tvh)
|
||||
{
|
||||
int seq;
|
||||
int seq = tvh->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;
|
||||
|
||||
printf("demux_tv_fill_buffer(sequence:%d) called!\n", seq);
|
||||
|
||||
demux->filepos = -1;
|
||||
|
||||
seq++;
|
||||
tvh->seq++;
|
||||
|
||||
/* ================== ADD VIDEO PACKET =================== */
|
||||
len_video = tv_handler->functions->get_video_framesize(tv_handler->priv);
|
||||
len_video = tvh->functions->get_video_framesize(tvh->priv);
|
||||
ds_video = demux->video;
|
||||
|
||||
if (!ds_video)
|
||||
{
|
||||
if (!ds_video->asf_packet)
|
||||
{
|
||||
/* create new packet */
|
||||
dp_video = new_demux_packet(len_video);
|
||||
tv_handler->functions->grab_video_frame(tv_handler->priv, dp_video->buffer, len_video);
|
||||
// printf("new dp_video->buffer: %p (%d bytes)\n", dp_video, len_video);
|
||||
tvh->functions->grab_video_frame(tvh->priv, dp_video->buffer, len_video);
|
||||
dp_video->pos = demux->filepos;
|
||||
ds_video->asf_packet = dp_video;
|
||||
ds_video->asf_seq = seq;
|
||||
@ -69,14 +74,17 @@ int demux_tv_fill_buffer(demuxer_t *demux)
|
||||
{
|
||||
if (ds_video->asf_seq != seq)
|
||||
{
|
||||
/* close segment, finalize packet */
|
||||
ds_add_packet(ds_video, ds_video->asf_packet);
|
||||
ds_video->asf_packet = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* append data to segment */
|
||||
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);
|
||||
// printf("dp_video->buffer: %p (%d bytes)\n", dp_video, dp_video->len+len_video);
|
||||
tvh->functions->grab_video_frame(tvh->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;
|
||||
}
|
||||
@ -84,13 +92,16 @@ int demux_tv_fill_buffer(demuxer_t *demux)
|
||||
|
||||
|
||||
/* ================== ADD AUDIO PACKET =================== */
|
||||
len_audio = tv_handler->functions->get_audio_framesize(tv_handler->priv);
|
||||
if (tvh->functions->control(tvh->priv, TVI_CONTROL_IS_AUDIO, 0) != TVI_CONTROL_TRUE)
|
||||
return 1; /* no audio, only video */
|
||||
|
||||
len_audio = tvh->functions->get_audio_framesize(tvh->priv);
|
||||
ds_audio = demux->audio;
|
||||
|
||||
if (!ds_audio)
|
||||
if (!ds_audio->asf_packet)
|
||||
{
|
||||
dp_audio = new_demux_packet(len_audio);
|
||||
tv_handler->functions->grab_audio_frame(tv_handler->priv, dp_audio->buffer, len_audio);
|
||||
tvh->functions->grab_audio_frame(tvh->priv, dp_audio->buffer, len_audio);
|
||||
dp_audio->pos = demux->filepos;
|
||||
ds_audio->asf_packet = dp_audio;
|
||||
ds_audio->asf_seq = seq;
|
||||
@ -106,7 +117,7 @@ int demux_tv_fill_buffer(demuxer_t *demux)
|
||||
{
|
||||
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);
|
||||
tvh->functions->grab_audio_frame(tvh->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;
|
||||
}
|
||||
@ -115,18 +126,30 @@ int demux_tv_fill_buffer(demuxer_t *demux)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int demux_open_tv(demuxer_t *demuxer)
|
||||
int demux_open_tv(demuxer_t *demuxer, tvi_handle_t *tvh)
|
||||
{
|
||||
sh_video_t *sh_video;
|
||||
tvi_handle_t *tvh = tv_handler;
|
||||
sh_video_t *sh_video = NULL;
|
||||
sh_audio_t *sh_audio = NULL;
|
||||
tvi_functions_t *funcs = tvh->functions;
|
||||
|
||||
sh_video = new_sh_video(demuxer,0);
|
||||
if (funcs->control(tvh->priv, TVI_CONTROL_IS_VIDEO, 0) != TVI_CONTROL_TRUE)
|
||||
{
|
||||
printf("Error: no video input present!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
/* hack to use YUV 4:2:0 format ;) */
|
||||
sh_video->format = IMGFMT_YV12;
|
||||
funcs->control(tvh->priv, TVI_CONTROL_VID_SET_FORMAT, &sh_video->format);
|
||||
|
||||
/* get IMGFMT_ */
|
||||
funcs->control(tvh->priv, TVI_CONTROL_VID_GET_FORMAT, &sh_video->format);
|
||||
if (IMGFMT_IS_RGB(sh_video->format) || IMGFMT_IS_BGR(sh_video->format))
|
||||
sh_video->format = 0x0;
|
||||
|
||||
/* set FPS and FRAMETIME */
|
||||
if(!sh_video->fps)
|
||||
{
|
||||
if (funcs->control(tvh->priv, TVI_CONTROL_VID_GET_FPS, &sh_video->fps) != TVI_CONTROL_TRUE)
|
||||
@ -169,47 +192,100 @@ int demux_open_tv(demuxer_t *demuxer)
|
||||
}
|
||||
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;
|
||||
|
||||
printf("Output size: %dx%d\n", sh_video->disp_w, sh_video->disp_h);
|
||||
|
||||
demuxer->video->sh = sh_video;
|
||||
sh_video->ds = demuxer->video;
|
||||
demuxer->video->id = 0;
|
||||
|
||||
/* here comes audio init */
|
||||
if (funcs->control(tvh->priv, TVI_CONTROL_IS_AUDIO, 0) == TVI_CONTROL_TRUE)
|
||||
{
|
||||
int audio_format;
|
||||
|
||||
sh_audio = new_sh_audio(demuxer, 0);
|
||||
|
||||
sh_audio->wf = malloc(sizeof(WAVEFORMATEX));
|
||||
memset(sh_audio->wf, 0, sizeof(WAVEFORMATEX));
|
||||
|
||||
/* yeah, audio is present */
|
||||
if (funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_FORMAT, &audio_format) != TVI_CONTROL_TRUE)
|
||||
goto no_audio;
|
||||
switch(audio_format)
|
||||
{
|
||||
case AFMT_U8:
|
||||
case AFMT_S8:
|
||||
case AFMT_U16_LE:
|
||||
case AFMT_U16_BE:
|
||||
case AFMT_S16_LE:
|
||||
case AFMT_S16_BE:
|
||||
case AFMT_S32_LE:
|
||||
case AFMT_S32_BE:
|
||||
sh_audio->format = 0x1; /* PCM */
|
||||
break;
|
||||
case AFMT_IMA_ADPCM:
|
||||
case AFMT_MU_LAW:
|
||||
case AFMT_A_LAW:
|
||||
case AFMT_MPEG:
|
||||
case AFMT_AC3:
|
||||
default:
|
||||
printf("%s unsupported!\n", audio_out_format_name(audio_format));
|
||||
goto no_audio;
|
||||
}
|
||||
|
||||
funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_CHANNELS, &sh_audio->wf->nChannels);
|
||||
funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_SAMPLERATE, &sh_audio->wf->nSamplesPerSec);
|
||||
funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_SAMPLESIZE, &sh_audio->wf->nAvgBytesPerSec);
|
||||
|
||||
demuxer->audio->sh = sh_audio;
|
||||
sh_audio->ds = demuxer->audio;
|
||||
demuxer->audio->id = 0;
|
||||
}
|
||||
no_audio:
|
||||
|
||||
/* set some params got from cmdline */
|
||||
funcs->control(tvh->priv, TVI_CONTROL_SPC_SET_INPUT, &tv_param_input);
|
||||
|
||||
/* set freq in MHz - change this to float ! */
|
||||
funcs->control(tvh->priv, TVI_CONTROL_TUN_SET_FREQ, &tv_param_freq);
|
||||
|
||||
funcs->control(tvh->priv, TVI_CONTROL_TUN_GET_FREQ, &tv_param_freq);
|
||||
printf("freq: %lu\n", tv_param_freq);
|
||||
|
||||
/* also start device! */
|
||||
funcs->start(tvh->priv);
|
||||
}
|
||||
|
||||
/* ================== STREAM_TV ===================== */
|
||||
tvi_handle_t *tv_begin()
|
||||
tvi_handle_t *tv_begin(void)
|
||||
{
|
||||
if (!strcmp(tv_param_driver, "dummy"))
|
||||
return tvi_init_dummy(tv_param_device);
|
||||
return (tvi_handle_t *)tvi_init_dummy(tv_param_device);
|
||||
if (!strcmp(tv_param_driver, "v4l"))
|
||||
return tvi_init_v4l(tv_param_device);
|
||||
return (tvi_handle_t *)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)
|
||||
int tv_init(tvi_handle_t *tvh)
|
||||
{
|
||||
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);
|
||||
tvi_param_t *params;
|
||||
|
||||
return tvi->functions->init(tvi->priv);
|
||||
printf("Selected driver: %s\n", tvh->info->short_name);
|
||||
printf(" name: %s\n", tvh->info->name);
|
||||
printf(" author: %s\n", tvh->info->author);
|
||||
if (tvh->info->comment)
|
||||
printf(" comment: %s\n", tvh->info->comment);
|
||||
|
||||
params = malloc(sizeof(tvi_param_t)*2);
|
||||
params[0].opt = malloc(strlen("input"));
|
||||
sprintf((char *)params[0].opt, "input");
|
||||
params[0].value = malloc(sizeof(int));
|
||||
(int)*(void **)params[0].value = tv_param_input;
|
||||
params[1].opt = params[1].value = NULL;
|
||||
|
||||
return tvh->functions->init(tvh->priv, params);
|
||||
}
|
||||
#endif /* USE_TV */
|
||||
|
@ -1,7 +1,10 @@
|
||||
#include "config.h"
|
||||
|
||||
#ifdef USE_TV
|
||||
extern float tv_param_freq;
|
||||
#include "../libao2/afmt.h"
|
||||
#include "../libvo/img_format.h"
|
||||
|
||||
extern unsigned long tv_param_freq;
|
||||
extern char *tv_param_channel;
|
||||
extern char *tv_param_norm;
|
||||
extern int tv_param_on;
|
||||
@ -9,6 +12,7 @@ extern char *tv_param_device;
|
||||
extern char *tv_param_driver;
|
||||
extern int tv_param_width;
|
||||
extern int tv_param_height;
|
||||
extern int tv_param_input;
|
||||
|
||||
typedef struct tvi_info_s
|
||||
{
|
||||
@ -21,42 +25,78 @@ typedef struct tvi_info_s
|
||||
typedef struct tvi_functions_s
|
||||
{
|
||||
int (*init)();
|
||||
int (*exit)();
|
||||
int (*uninit)();
|
||||
int (*control)();
|
||||
int (*start)();
|
||||
int (*grab_video_frame)();
|
||||
int (*get_video_framesize)();
|
||||
int (*grab_audio_frame)();
|
||||
int (*get_audio_framesize)();
|
||||
} tvi_functions_t;
|
||||
|
||||
typedef struct tvi_param_s {
|
||||
const char *opt;
|
||||
void *value;
|
||||
} tvi_param_t;
|
||||
|
||||
typedef struct tvi_handle_s {
|
||||
tvi_info_t *info;
|
||||
tvi_functions_t *functions;
|
||||
void *priv;
|
||||
tvi_info_t *info;
|
||||
tvi_functions_t *functions;
|
||||
void *priv;
|
||||
tvi_param_t *params;
|
||||
int seq;
|
||||
} tvi_handle_t;
|
||||
|
||||
|
||||
#define TVI_CONTROL_FALSE 0
|
||||
#define TVI_CONTROL_TRUE 1
|
||||
#define TVI_CONTROL_NA -1
|
||||
#define TVI_CONTROL_UNKNOWN -2
|
||||
|
||||
/* ======================== CONTROLS =========================== */
|
||||
|
||||
#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
|
||||
/* GENERIC controls */
|
||||
#define TVI_CONTROL_IS_AUDIO 0x1
|
||||
#define TVI_CONTROL_IS_VIDEO 0x2
|
||||
#define TVI_CONTROL_IS_TUNER 0x3
|
||||
|
||||
#define TVI_CONTROL_TUN_GET_FREQ 100
|
||||
#define TVI_CONTROL_TUN_SET_FREQ 101
|
||||
/* VIDEO controls */
|
||||
#define TVI_CONTROL_VID_GET_FPS 0x101
|
||||
#define TVI_CONTROL_VID_GET_PLANES 0x102
|
||||
#define TVI_CONTROL_VID_GET_BITS 0x103
|
||||
#define TVI_CONTROL_VID_CHK_BITS 0x104
|
||||
#define TVI_CONTROL_VID_SET_BITS 0x105
|
||||
#define TVI_CONTROL_VID_GET_FORMAT 0x106
|
||||
#define TVI_CONTROL_VID_CHK_FORMAT 0x107
|
||||
#define TVI_CONTROL_VID_SET_FORMAT 0x108
|
||||
#define TVI_CONTROL_VID_GET_WIDTH 0x109
|
||||
#define TVI_CONTROL_VID_CHK_WIDTH 0x110
|
||||
#define TVI_CONTROL_VID_SET_WIDTH 0x111
|
||||
#define TVI_CONTROL_VID_GET_HEIGHT 0x112
|
||||
#define TVI_CONTROL_VID_CHK_HEIGHT 0x113
|
||||
#define TVI_CONTROL_VID_SET_HEIGHT 0x114
|
||||
|
||||
/* TUNER controls */
|
||||
#define TVI_CONTROL_TUN_GET_FREQ 0x201
|
||||
#define TVI_CONTROL_TUN_SET_FREQ 0x202
|
||||
#define TVI_CONTROL_TUN_GET_TUNER 0x203 /* update priv->tuner struct for used input */
|
||||
#define TVI_CONTROL_TUN_SET_TUNER 0x204 /* update priv->tuner struct for used input */
|
||||
#define TVI_CONTROL_TUN_GET_NORM 0x205
|
||||
#define TVI_CONTROL_TUN_SET_NORM 0x206
|
||||
|
||||
/* AUDIO controls */
|
||||
#define TVI_CONTROL_AUD_GET_FORMAT 0x301
|
||||
#define TVI_CONTROL_AUD_GET_SAMPLERATE 0x302
|
||||
#define TVI_CONTROL_AUD_GET_SAMPLESIZE 0x303
|
||||
#define TVI_CONTROL_AUD_GET_CHANNELS 0x304
|
||||
|
||||
/* SPECIFIC controls */
|
||||
#define TVI_CONTROL_SPC_GET_INPUT 0x401 /* set input channel (tv,s-video,composite..) */
|
||||
#define TVI_CONTROL_SPC_SET_INPUT 0x402 /* set input channel (tv,s-video,composite..) */
|
||||
|
||||
//extern int demux_tv_fill_buffer(demuxer_t *demux, tvi_handle_t *tvh);
|
||||
//extern int demux_open_tv(demuxer_t *demux, tvi_handle_t *tvh);
|
||||
extern tvi_handle_t *tv_begin(void);
|
||||
extern int tv_init(tvi_handle_t *tvh);
|
||||
|
||||
#endif /* USE_TV */
|
||||
|
@ -1,6 +1,7 @@
|
||||
static int init(priv_t *priv);
|
||||
static int exit(priv_t *priv);
|
||||
static int init(priv_t *priv, tvi_param_t *params);
|
||||
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 int get_video_framesize(priv_t *priv);
|
||||
static int grab_audio_frame(priv_t *priv, char *buffer, int len);
|
||||
@ -9,8 +10,9 @@ static int get_audio_framesize(priv_t *priv);
|
||||
static tvi_functions_t functions =
|
||||
{
|
||||
init,
|
||||
exit,
|
||||
uninit,
|
||||
control,
|
||||
start,
|
||||
grab_video_frame,
|
||||
get_video_framesize,
|
||||
grab_audio_frame,
|
||||
@ -23,7 +25,7 @@ static tvi_handle_t *new_handle()
|
||||
|
||||
if (!h)
|
||||
return(NULL);
|
||||
h->priv = malloc(sizeof(priv_t));
|
||||
h->priv = (priv_t *)malloc(sizeof(priv_t));
|
||||
if (!h->priv)
|
||||
{
|
||||
free(h);
|
||||
@ -32,6 +34,8 @@ static tvi_handle_t *new_handle()
|
||||
memset(h->priv, 0, sizeof(priv_t));
|
||||
h->info = &info;
|
||||
h->functions = &functions;
|
||||
h->params = NULL;
|
||||
h->seq = 0;
|
||||
return(h);
|
||||
}
|
||||
|
||||
|
@ -1,58 +1,92 @@
|
||||
#include <stdio.h>
|
||||
/*
|
||||
Only a sample!
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef USE_TV
|
||||
|
||||
#include <stdio.h>
|
||||
#include "tv.h"
|
||||
|
||||
/* information about this file */
|
||||
static tvi_info_t info = {
|
||||
"NULL-TV",
|
||||
"dummy",
|
||||
"alex",
|
||||
"non-completed"
|
||||
NULL
|
||||
};
|
||||
|
||||
/* private data's */
|
||||
typedef struct {
|
||||
int width;
|
||||
int height;
|
||||
} priv_t;
|
||||
|
||||
#include "tvi_def.h"
|
||||
|
||||
/* handler creator - entry point ! */
|
||||
tvi_handle_t *tvi_init_dummy(char *device)
|
||||
{
|
||||
return new_handle();
|
||||
}
|
||||
|
||||
static int init(priv_t *priv)
|
||||
/* initialisation */
|
||||
static int init(priv_t *priv, tvi_param_t *params)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* that's the real start, we'got the format parameters (checked with control) */
|
||||
static int start(priv_t *priv)
|
||||
{
|
||||
}
|
||||
|
||||
static int close(priv_t *priv)
|
||||
static int uninit(priv_t *priv)
|
||||
{
|
||||
}
|
||||
|
||||
static int control(priv_t *priv, int cmd, void *arg)
|
||||
{
|
||||
switch(cmd)
|
||||
{
|
||||
case TVI_CONTROL_IS_VIDEO:
|
||||
return(TVI_CONTROL_TRUE);
|
||||
case TVI_CONTROL_VID_GET_FORMAT:
|
||||
(int)*(void **)arg = IMGFMT_YV12;
|
||||
return(TVI_CONTROL_TRUE);
|
||||
case TVI_CONTROL_VID_SET_WIDTH:
|
||||
priv->width = (int)*(void **)arg;
|
||||
return(TVI_CONTROL_TRUE);
|
||||
case TVI_CONTROL_VID_SET_HEIGHT:
|
||||
priv->height = (int)*(void **)arg;
|
||||
return(TVI_CONTROL_TRUE);
|
||||
case TVI_CONTROL_VID_CHK_WIDTH:
|
||||
case TVI_CONTROL_VID_CHK_HEIGHT:
|
||||
return(TVI_CONTROL_TRUE);
|
||||
}
|
||||
return(TVI_CONTROL_UNKNOWN);
|
||||
}
|
||||
|
||||
static int grab_video_frame(priv_t *priv, char *buffer, int len)
|
||||
{
|
||||
memset(buffer, 0x77, len);
|
||||
memset(buffer, 0x42, len);
|
||||
}
|
||||
|
||||
static int get_video_framesize(priv_t *priv)
|
||||
{
|
||||
return 0;
|
||||
/* YV12 */
|
||||
return priv->width*priv->height*12/8;
|
||||
}
|
||||
|
||||
static int grab_audio_frame(priv_t *priv, char *buffer, int len)
|
||||
{
|
||||
memset(buffer, 0x77, len);
|
||||
memset(buffer, 0x42, len);
|
||||
}
|
||||
|
||||
static int get_audio_framesize(priv_t *priv)
|
||||
{
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* USE_TV */
|
||||
|
@ -1,3 +1,14 @@
|
||||
/*
|
||||
v4l interface for libmpemux/tvi
|
||||
|
||||
(C) Alex Beregszaszi <alex@naxine.org>
|
||||
|
||||
Some ideas are based on xawtv/libng's grab-v4l.c written by
|
||||
Gerd Knorr <kraxel@bytesex.org>
|
||||
|
||||
CODE IS UNDER DEVELOPMENT, NO FEATURE REQUESTS PLEASE!
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef USE_TV
|
||||
@ -5,6 +16,7 @@
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/videodev.h>
|
||||
@ -16,35 +28,168 @@
|
||||
static tvi_info_t info = {
|
||||
"Video for Linux TV Input",
|
||||
"v4l",
|
||||
"alex",
|
||||
"non-completed"
|
||||
"Alex Beregszaszi <alex@naxine.org>",
|
||||
"under development"
|
||||
};
|
||||
|
||||
struct vid_fmt {
|
||||
int fmtid;
|
||||
int width;
|
||||
int height;
|
||||
int bytesperline;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
/* general */
|
||||
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;
|
||||
|
||||
/* video */
|
||||
struct video_picture picture;
|
||||
int format; /* output format */
|
||||
int width;
|
||||
int height;
|
||||
int bytesperline;
|
||||
|
||||
struct video_mbuf mbuf;
|
||||
unsigned char *mmap;
|
||||
struct video_mmap *buf;
|
||||
int nbuf;
|
||||
int queue;
|
||||
|
||||
/* audio */
|
||||
struct video_audio audio;
|
||||
} priv_t;
|
||||
|
||||
#include "tvi_def.h"
|
||||
|
||||
static const char *device_cap[] = {
|
||||
"capture", "tuner", "teletext", "overlay", "chromakey", "clipping",
|
||||
"frameram", "scales", "monochrome", NULL
|
||||
"frameram", "scales", "monochrome", "subcapture", "mpeg-decoder",
|
||||
"mpeg-encoder", "mjpeg-decoder", "mjpeg-encoder", NULL
|
||||
};
|
||||
|
||||
static const char *device_pal[] = {
|
||||
"-", "grey", "hi240", "rgb16", "rgb24", "rgb32", "rgb15", "yuv422",
|
||||
"yuyv", "uyvy", "yuv420", "yuv411", "raw", "yuv422p", "yuv411p",
|
||||
"yuv420p", "yuv410p", NULL
|
||||
};
|
||||
#define PALETTE(x) ((x < sizeof(device_pal)/sizeof(char*)) ? device_pal[x] : "UNKNOWN")
|
||||
|
||||
static int palette2depth(int palette)
|
||||
{
|
||||
if (palette == VIDEO_PALETTE_YUV420P)
|
||||
return 12;
|
||||
return 32;
|
||||
}
|
||||
|
||||
static int format2palette(int format)
|
||||
{
|
||||
if (format == IMGFMT_YV12)
|
||||
return VIDEO_PALETTE_YUV420P;
|
||||
return VIDEO_PALETTE_RGB24;
|
||||
}
|
||||
|
||||
#if 0
|
||||
struct STRTAB {
|
||||
long nr;
|
||||
const char *str;
|
||||
};
|
||||
|
||||
static struct STRTAB stereo[] = {
|
||||
{ 0, "auto" },
|
||||
{ VIDEO_SOUND_MONO, "mono" },
|
||||
{ VIDEO_SOUND_STEREO, "stereo" },
|
||||
{ VIDEO_SOUND_LANG1, "lang1" },
|
||||
{ VIDEO_SOUND_LANG2, "lang1" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static struct STRTAB norms_v4l[] = {
|
||||
{ VIDEO_MODE_PAL, "PAL" },
|
||||
{ VIDEO_MODE_NTSC, "NTSC" },
|
||||
{ VIDEO_MODE_SECAM, "SECAM" },
|
||||
{ VIDEO_MODE_AUTO, "AUTO" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static struct STRTAB norms_bttv[] = {
|
||||
{ VIDEO_MODE_PAL, "PAL" },
|
||||
{ VIDEO_MODE_NTSC, "NTSC" },
|
||||
{ VIDEO_MODE_SECAM, "SECAM" },
|
||||
{ 3, "PAL-NC" },
|
||||
{ 4, "PAL-M" },
|
||||
{ 5, "PAL-N" },
|
||||
{ 6, "NTSC-JP" },
|
||||
{ -1, NULL }
|
||||
};
|
||||
|
||||
static unsigned short _format2palette[VIDEO_FMT_COUNT] = {
|
||||
0, /* unused */
|
||||
VIDEO_PALETTE_HI240, /* RGB8 */
|
||||
VIDEO_PALETTE_GREY,
|
||||
VIDEO_PALETTE_RGB555,
|
||||
VIDEO_PALETTE_RGB565,
|
||||
0,
|
||||
0,
|
||||
VIDEO_PALETTE_RGB24,
|
||||
VIDEO_PALETTE_RGB32,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
VIDEO_PALETTE_YUV422,
|
||||
VIDEO_PALETTE_YUV422P,
|
||||
VIDEO_PALETTE_YUV420P,
|
||||
};
|
||||
#define FMT2PAL(fmt) ((fmt < sizeof(format2palette)/sizeof(unsigned short)) ? \
|
||||
format2palette[fmt] : 0);
|
||||
|
||||
const unsigned int vfmt_to_depth[] = {
|
||||
0,
|
||||
8,
|
||||
8,
|
||||
16,
|
||||
16,
|
||||
16,
|
||||
16,
|
||||
24,
|
||||
32,
|
||||
24,
|
||||
32,
|
||||
16,
|
||||
32,
|
||||
16,
|
||||
16,
|
||||
12,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
#endif
|
||||
|
||||
static int one = 1, zero = 0;
|
||||
|
||||
static int alarms;
|
||||
|
||||
static void sigalarm(int signal)
|
||||
{
|
||||
alarms++;
|
||||
printf("v4l: timeout (got SIGALRM), hardware/driver problems?\n");
|
||||
}
|
||||
|
||||
static void siginit(void)
|
||||
{
|
||||
struct sigaction act, old;
|
||||
|
||||
memset(&act, 0, sizeof(act));
|
||||
act.sa_handler = sigalarm;
|
||||
sigemptyset(&act.sa_mask);
|
||||
sigaction(SIGALRM, &act, &old);
|
||||
}
|
||||
|
||||
tvi_handle_t *tvi_init_v4l(char *device)
|
||||
{
|
||||
tvi_handle_t *h;
|
||||
@ -56,10 +201,11 @@ tvi_handle_t *tvi_init_v4l(char *device)
|
||||
|
||||
priv = h->priv;
|
||||
|
||||
/* set video device name */
|
||||
if (!device)
|
||||
{
|
||||
priv->video_device = malloc(strlen("/dev/video0"));
|
||||
strcpy(priv->video_device, &"/dev/video0");
|
||||
sprintf(priv->video_device, "/dev/video0");
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -70,40 +216,52 @@ tvi_handle_t *tvi_init_v4l(char *device)
|
||||
return(h);
|
||||
}
|
||||
|
||||
static int init(priv_t *priv)
|
||||
static int init(priv_t *priv, tvi_param_t *params)
|
||||
{
|
||||
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));
|
||||
printf("v4l: unable to open '%s': %s\n",
|
||||
priv->video_device, strerror(errno));
|
||||
goto err;
|
||||
}
|
||||
|
||||
printf("fd: %d\n", priv->fd);
|
||||
|
||||
/* get capabilities */
|
||||
/* get capabilities (priv->capability is needed!) */
|
||||
if (ioctl(priv->fd, VIDIOCGCAP, &priv->capability) == -1)
|
||||
{
|
||||
printf("v4l: ioctl error: %s\n", strerror(errno));
|
||||
printf("ioctl get capabilites error: %s\n", strerror(errno));
|
||||
goto err;
|
||||
}
|
||||
|
||||
fcntl(priv->fd, F_SETFD, FD_CLOEXEC);
|
||||
|
||||
printf("capabilites: ");
|
||||
siginit();
|
||||
|
||||
#if 0
|
||||
for (i=0; params[i].opt; i++)
|
||||
{
|
||||
if (!strcmp(params[i].opt, "input"))
|
||||
priv->input = (int)*(void **)params[i].value;
|
||||
}
|
||||
printf("priv->input: %d\n", priv->input);
|
||||
#endif
|
||||
|
||||
printf("Selected device: %s\n", priv->capability.name);
|
||||
printf(" Capabilites: ");
|
||||
for (i = 0; device_cap[i] != NULL; i++)
|
||||
if (priv->capability.type & (1 << i))
|
||||
printf(" %s", device_cap[i]);
|
||||
printf("%s ", device_cap[i]);
|
||||
printf("\n");
|
||||
printf(" type: %d\n", priv->capability.type);
|
||||
printf(" size: %dx%d => %dx%d\n",
|
||||
printf(" Device type: %d\n", priv->capability.type);
|
||||
printf(" Supported sizes: %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);
|
||||
printf(" Inputs: %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);
|
||||
@ -111,40 +269,51 @@ static int init(priv_t *priv)
|
||||
{
|
||||
priv->channels[i].channel = i;
|
||||
ioctl(priv->fd, VIDIOCGCHAN, &priv->channels[i]);
|
||||
printf(" %s: tuners:%d %s%s %s%s\n",
|
||||
printf(" %d: %s: %s%s%s%s (tuner:%d, norm:%d)\n", i,
|
||||
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 " : "");
|
||||
(priv->channels[i].flags & VIDEO_TYPE_CAMERA) ? "camera " : "",
|
||||
priv->channels[i].tuners,
|
||||
priv->channels[i].norm);
|
||||
}
|
||||
|
||||
if (priv->capability.type & VID_TYPE_CAPTURE)
|
||||
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("Only grabbing supported (for overlay use another program)\n");
|
||||
goto err;
|
||||
}
|
||||
|
||||
printf("buffered: %d\n", priv->buffered);
|
||||
/* map grab buffer */
|
||||
if (ioctl(priv->fd, VIDIOCGMBUF, &priv->mbuf) == -1)
|
||||
{
|
||||
printf("ioctl get mbuf failed: %s\n", strerror(errno));
|
||||
goto err;
|
||||
}
|
||||
|
||||
printf("mbuf: size=%d, frames=%d\n",
|
||||
priv->mbuf.size, priv->mbuf.frames);
|
||||
priv->mmap = mmap(0, priv->mbuf.size, PROT_READ|PROT_WRITE,
|
||||
MAP_SHARED, priv->fd, 0);
|
||||
if (priv->mmap == -1)
|
||||
{
|
||||
printf("Unabel to map memory for buffers: %s\n", strerror(errno));
|
||||
priv->mmap = malloc(priv->mbuf.size); /* our buffer */
|
||||
}
|
||||
if (!priv->mmap)
|
||||
{
|
||||
printf("Unable to allocate memory for buffers: %s\n", strerror(errno));
|
||||
goto err;
|
||||
}
|
||||
printf("our buffer: %p\n", priv->mmap);
|
||||
|
||||
/* num of buffers */
|
||||
priv->nbuf = priv->mbuf.frames;
|
||||
|
||||
/* video buffers */
|
||||
priv->buf = malloc(priv->nbuf * sizeof(struct video_mmap));
|
||||
memset(priv->buf, 0, priv->nbuf * sizeof(struct video_mmap));
|
||||
|
||||
return(1);
|
||||
|
||||
@ -154,32 +323,119 @@ err:
|
||||
return(0);
|
||||
}
|
||||
|
||||
static int exit(priv_t *priv)
|
||||
static int uninit(priv_t *priv)
|
||||
{
|
||||
#warning "Implement uninit!"
|
||||
}
|
||||
|
||||
static int tune(priv_t *priv, int freq, int chan, int norm)
|
||||
static int start(priv_t *priv)
|
||||
{
|
||||
if (freq)
|
||||
int i;
|
||||
|
||||
|
||||
if (ioctl(priv->fd, VIDIOCGPICT, &priv->picture) == -1)
|
||||
{
|
||||
ioctl(priv->fd, VIDIOCSFREQ, &freq);
|
||||
return(1);
|
||||
printf("ioctl get picture failed: %s\n", strerror(errno));
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (chan && norm)
|
||||
priv->picture.palette = format2palette(priv->format);
|
||||
priv->picture.depth = palette2depth(priv->picture.palette);
|
||||
priv->bytesperline = priv->width * priv->picture.depth / 8;
|
||||
|
||||
printf("Picture values:\n");
|
||||
printf(" Depth: %d, Palette: %d (Format: %s)\n", priv->picture.depth,
|
||||
priv->picture.palette, vo_format_name(priv->format));
|
||||
printf(" Brightness: %d, Hue: %d, Colour: %d, Contrast: %d\n",
|
||||
priv->picture.brightness, priv->picture.hue,
|
||||
priv->picture.colour, priv->picture.contrast);
|
||||
|
||||
|
||||
if (ioctl(priv->fd, VIDIOCSPICT, &priv->picture) == -1)
|
||||
{
|
||||
/* set channel & norm ! */
|
||||
printf("ioctl set picture failed: %s\n", strerror(errno));
|
||||
return(0);
|
||||
}
|
||||
|
||||
return(0);
|
||||
priv->nbuf = priv->mbuf.frames;
|
||||
for (i=0; i < priv->nbuf; i++)
|
||||
{
|
||||
priv->buf[i].format = priv->picture.palette;
|
||||
priv->buf[i].frame = i;
|
||||
priv->buf[i].width = priv->width;
|
||||
priv->buf[i].height = priv->height;
|
||||
printf("buffer: %d => %p\n", i, &priv->buf[i]);
|
||||
}
|
||||
|
||||
/* start capture */
|
||||
if (ioctl(priv->fd, VIDIOCCAPTURE, &one) == -1)
|
||||
{
|
||||
printf("ioctl capture failed: %s\n", strerror(errno));
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
static int control(priv_t *priv, int cmd, void *arg)
|
||||
{
|
||||
printf("debug: control(priv=%p, cmd=%d, arg=%p)\n",
|
||||
priv, cmd, arg);
|
||||
switch(cmd)
|
||||
{
|
||||
/* ========== GENERIC controls =========== */
|
||||
case TVI_CONTROL_IS_VIDEO:
|
||||
{
|
||||
if (priv->capability.type & VID_TYPE_CAPTURE)
|
||||
return(TVI_CONTROL_TRUE);
|
||||
return(TVI_CONTROL_FALSE);
|
||||
}
|
||||
case TVI_CONTROL_IS_AUDIO:
|
||||
return(TVI_CONTROL_FALSE); /* IMPLEMENT CHECK! */
|
||||
case TVI_CONTROL_IS_TUNER:
|
||||
{
|
||||
if (priv->capability.type & VID_TYPE_TUNER)
|
||||
return(TVI_CONTROL_TRUE);
|
||||
return(TVI_CONTROL_FALSE);
|
||||
}
|
||||
|
||||
/* ========== VIDEO controls =========== */
|
||||
case TVI_CONTROL_VID_GET_FORMAT:
|
||||
(int)*(void **)arg = 0x0;
|
||||
{
|
||||
int output_fmt = -1;
|
||||
|
||||
#if 0
|
||||
switch(priv->palette)
|
||||
{
|
||||
case VIDEO_PALETTE_RGB555:
|
||||
output_fmt = IMGFMT_RGB15;
|
||||
break;
|
||||
case VIDEO_PALETTE_RGB565:
|
||||
output_fmt = IMGFMT_RGB16;
|
||||
break;
|
||||
case VIDEO_PALETTE_RGB24:
|
||||
output_fmt = IMGFMT_RGB24;
|
||||
break;
|
||||
case VIDEO_PALETTE_RGB32:
|
||||
output_fmt = IMGFMT_RGB32;
|
||||
break;
|
||||
case VIDEO_PALETTE_UYVY:
|
||||
output_fmt = IMGFMT_UYVY;
|
||||
break;
|
||||
case VIDEO_PALETTE_YUV420P:
|
||||
output_fmt = IMGFMT_YV12;
|
||||
break;
|
||||
default:
|
||||
printf("no suitable output format found (%s)\n",
|
||||
PALETTE(priv->palette));
|
||||
return(TVI_CONTROL_FALSE);
|
||||
}
|
||||
#endif
|
||||
output_fmt = priv->format;
|
||||
(int)*(void **)arg = output_fmt;
|
||||
printf("Output format: %s\n", vo_format_name(output_fmt));
|
||||
return(TVI_CONTROL_TRUE);
|
||||
}
|
||||
case TVI_CONTROL_VID_SET_FORMAT:
|
||||
priv->format = (int)*(void **)arg;
|
||||
return(TVI_CONTROL_TRUE);
|
||||
case TVI_CONTROL_VID_GET_PLANES:
|
||||
(int)*(void **)arg = 1;
|
||||
@ -194,7 +450,7 @@ static int control(priv_t *priv, int cmd, void *arg)
|
||||
{
|
||||
int req_width = (int)*(void **)arg;
|
||||
|
||||
printf("req_width: %d\n", req_width);
|
||||
printf("Requested width: %d\n", req_width);
|
||||
if ((req_width > priv->capability.minwidth) &&
|
||||
(req_width < priv->capability.maxwidth))
|
||||
return(TVI_CONTROL_TRUE);
|
||||
@ -210,7 +466,7 @@ static int control(priv_t *priv, int cmd, void *arg)
|
||||
{
|
||||
int req_height = (int)*(void **)arg;
|
||||
|
||||
printf("req_height: %d\n", req_height);
|
||||
printf("Requested height: %d\n", req_height);
|
||||
if ((req_height > priv->capability.minheight) &&
|
||||
(req_height < priv->capability.maxheight))
|
||||
return(TVI_CONTROL_TRUE);
|
||||
@ -220,14 +476,163 @@ static int control(priv_t *priv, int cmd, void *arg)
|
||||
priv->height = (int)*(void **)arg;
|
||||
return(TVI_CONTROL_TRUE);
|
||||
|
||||
/* ========== TUNER controls =========== */
|
||||
case TVI_CONTROL_TUN_GET_FREQ:
|
||||
{
|
||||
unsigned long freq;
|
||||
|
||||
if (ioctl(priv->fd, VIDIOCGFREQ, &freq) == -1)
|
||||
{
|
||||
printf("ioctl get freq failed: %s\n", strerror(errno));
|
||||
return(TVI_CONTROL_FALSE);
|
||||
}
|
||||
|
||||
/* tuner uses khz not mhz ! */
|
||||
if (priv->tuner.flags & VIDEO_TUNER_LOW)
|
||||
freq /= 1000;
|
||||
(unsigned long)*(void **)arg = freq;
|
||||
return(TVI_CONTROL_TRUE);
|
||||
}
|
||||
case TVI_CONTROL_TUN_SET_FREQ:
|
||||
{
|
||||
long freq = (long)*(void **)arg; /* shit: long -> freq */
|
||||
/* argument is in MHz ! */
|
||||
unsigned long freq = (unsigned long)*(void **)arg;
|
||||
|
||||
printf("requested frequency: %f\n", freq);
|
||||
if (ioctl(priv->fd, VIDIOCSFREQ, &freq) != -1)
|
||||
return(TVI_CONTROL_TRUE);
|
||||
return(TVI_CONTROL_FALSE);
|
||||
printf("requested frequency: %lu MHz\n", (float)freq/16);
|
||||
|
||||
/* tuner uses khz not mhz ! */
|
||||
if (priv->tuner.flags & VIDEO_TUNER_LOW)
|
||||
freq *= 1000;
|
||||
printf(" requesting from driver: freq=%.3f\n", (float)freq/16);
|
||||
if (ioctl(priv->fd, VIDIOCSFREQ, &freq) == -1)
|
||||
{
|
||||
printf("ioctl set freq failed: %s\n", strerror(errno));
|
||||
return(TVI_CONTROL_FALSE);
|
||||
}
|
||||
return(TVI_CONTROL_TRUE);
|
||||
}
|
||||
case TVI_CONTROL_TUN_GET_TUNER:
|
||||
{
|
||||
if (ioctl(priv->fd, VIDIOCGTUNER, &priv->tuner) == -1)
|
||||
{
|
||||
printf("ioctl get tuner failed: %s\n", strerror(errno));
|
||||
return(TVI_CONTROL_FALSE);
|
||||
}
|
||||
|
||||
printf("Tuner (%s) range: %lu -> %lu\n", priv->tuner.name,
|
||||
priv->tuner.rangelow, priv->tuner.rangehigh);
|
||||
return(TVI_CONTROL_TRUE);
|
||||
}
|
||||
case TVI_CONTROL_TUN_SET_TUNER:
|
||||
{
|
||||
if (ioctl(priv->fd, VIDIOCSTUNER, &priv->tuner) == -1)
|
||||
{
|
||||
printf("ioctl get tuner failed: %s\n", strerror(errno));
|
||||
return(TVI_CONTROL_FALSE);
|
||||
}
|
||||
return(TVI_CONTROL_TRUE);
|
||||
}
|
||||
case TVI_CONTROL_TUN_SET_NORM:
|
||||
{
|
||||
int req_mode = (int)*(void **)arg;
|
||||
|
||||
if ((!(priv->tuner.flags & VIDEO_TUNER_NORM)) ||
|
||||
((req_mode == VIDEO_MODE_PAL) && !(priv->tuner.flags & VIDEO_TUNER_PAL)) ||
|
||||
((req_mode == VIDEO_MODE_NTSC) && !(priv->tuner.flags & VIDEO_TUNER_NTSC)) ||
|
||||
((req_mode == VIDEO_MODE_SECAM) && !(priv->tuner.flags & VIDEO_TUNER_SECAM)))
|
||||
{
|
||||
printf("tuner isn't capable to set norm!\n");
|
||||
return(TVI_CONTROL_FALSE);
|
||||
}
|
||||
|
||||
priv->tuner.mode = req_mode;
|
||||
|
||||
if (control(priv->fd, TVI_CONTROL_TUN_SET_TUNER, &priv->tuner) != TVI_CONTROL_TRUE)
|
||||
return(TVI_CONTROL_FALSE);
|
||||
return(TVI_CONTROL_TRUE);
|
||||
}
|
||||
case TVI_CONTROL_TUN_GET_NORM:
|
||||
{
|
||||
(int)*(void **)arg = priv->tuner.mode;
|
||||
|
||||
return(TVI_CONTROL_TRUE);
|
||||
}
|
||||
|
||||
/* ========== AUDIO controls =========== */
|
||||
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 = 76000;
|
||||
return(TVI_CONTROL_TRUE);
|
||||
}
|
||||
|
||||
/* ========== SPECIFIC controls =========== */
|
||||
case TVI_CONTROL_SPC_GET_INPUT:
|
||||
{
|
||||
int req_chan = (int)*(void **)arg;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < priv->capability.channels; i++)
|
||||
{
|
||||
if (priv->channels[i].channel == req_chan)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ioctl(priv->fd, VIDIOCGCHAN, &priv->channels[i]) == -1)
|
||||
{
|
||||
printf("ioctl get channel failed: %s\n", strerror(errno));
|
||||
return(TVI_CONTROL_FALSE);
|
||||
}
|
||||
return(TVI_CONTROL_TRUE);
|
||||
}
|
||||
|
||||
case TVI_CONTROL_SPC_SET_INPUT:
|
||||
{
|
||||
struct video_channel chan;
|
||||
int req_chan = (int)*(void **)arg;
|
||||
int i;
|
||||
|
||||
if (req_chan >= priv->capability.channels)
|
||||
{
|
||||
printf("Invalid input requested: %d, valid: 0-%d\n",
|
||||
req_chan, priv->capability.channels);
|
||||
return(TVI_CONTROL_FALSE);
|
||||
}
|
||||
|
||||
for (i = 0; i < priv->capability.channels; i++)
|
||||
{
|
||||
if (priv->channels[i].channel == req_chan)
|
||||
chan = priv->channels[i];
|
||||
}
|
||||
|
||||
if (ioctl(priv->fd, VIDIOCSCHAN, &chan) == -1)
|
||||
{
|
||||
printf("ioctl set chan failed: %s\n", strerror(errno));
|
||||
return(TVI_CONTROL_FALSE);
|
||||
}
|
||||
printf("Using input '%s'\n", chan.name);
|
||||
|
||||
/* update tuner state */
|
||||
if (priv->capability.type & VID_TYPE_TUNER)
|
||||
control(priv, TVI_CONTROL_TUN_GET_TUNER, 0);
|
||||
|
||||
/* update local channel list */
|
||||
control(priv, TVI_CONTROL_SPC_GET_INPUT, &req_chan);
|
||||
return(TVI_CONTROL_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -236,23 +641,33 @@ static int control(priv_t *priv, int cmd, void *arg)
|
||||
|
||||
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)
|
||||
int frame = priv->queue % priv->nbuf;
|
||||
|
||||
printf("grab_video_frame(priv=%p, buffer=%p, len=%d\n",
|
||||
priv, buffer, len);
|
||||
|
||||
printf("buf: %p + frame: %d => %p\n",
|
||||
priv->buf, frame, &priv->buf[frame]);
|
||||
if (ioctl(priv->fd, VIDIOCMCAPTURE, &priv->buf[frame]) == -1)
|
||||
{
|
||||
printf("grab_video_frame failed: %s\n", strerror(errno));
|
||||
return 0;
|
||||
printf("ioctl mcapture failed: %s\n", strerror(errno));
|
||||
return(0);
|
||||
}
|
||||
|
||||
return 1;
|
||||
ioctl(priv->fd, VIDIOCSYNC, &priv->buf[frame]);
|
||||
priv->queue++;
|
||||
|
||||
printf("mmap: %p + offset: %d => %p\n",
|
||||
priv->mmap, priv->mbuf.offsets[frame],
|
||||
priv->mmap+priv->mbuf.offsets[frame]);
|
||||
memcpy(buffer, priv->mmap+priv->mbuf.offsets[frame], len);
|
||||
|
||||
return(len);
|
||||
}
|
||||
|
||||
static int get_video_framesize(priv_t *priv)
|
||||
{
|
||||
return 65536;
|
||||
return priv->bytesperline * priv->height;
|
||||
}
|
||||
|
||||
static int grab_audio_frame(priv_t *priv, char *buffer, int len)
|
||||
|
Loading…
Reference in New Issue
Block a user