From fc363d39bc8a1aecc72b62c1108d7cc3b0b40a64 Mon Sep 17 00:00:00 2001 From: alex Date: Sat, 10 Nov 2001 23:32:10 +0000 Subject: tv update git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@2803 b3059339-0415-0410-9bf9-f77b7e298cf2 --- libmpdemux/tv.c | 168 ++++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 122 insertions(+), 46 deletions(-) (limited to 'libmpdemux/tv.c') diff --git a/libmpdemux/tv.c b/libmpdemux/tv.c index ed1377433c..48f089bad3 100644 --- a/libmpdemux/tv.c +++ b/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; + + 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 tvi->functions->init(tvi->priv); + return tvh->functions->init(tvh->priv, params); } #endif /* USE_TV */ -- cgit v1.2.3