Mercurial > mplayer.hg
annotate libmpdemux/tv.c @ 2865:72c750bbc249
*** empty log message ***
author | gabucino |
---|---|
date | Tue, 13 Nov 2001 13:17:46 +0000 |
parents | aebdcb39cadb |
children | bce9c945b29c |
rev | line source |
---|---|
2790 | 1 /* |
2 TV subsystem for libMPDemux by Alex | |
3 | |
4 API idea based on libvo2's | |
5 | |
6 UNDER HEAVY DEVELOPEMENT, DO NOT USE! :) | |
7 */ | |
8 | |
9 #include <stdio.h> | |
10 #include <stdlib.h> | |
11 #include <unistd.h> | |
12 | |
13 #include "config.h" | |
14 | |
2819
2e58962dc9fe
cleaned up some warnings, and tv_param_on moved out from #ifdef USE_TV
alex
parents:
2818
diff
changeset
|
15 int tv_param_on = 0; |
2e58962dc9fe
cleaned up some warnings, and tv_param_on moved out from #ifdef USE_TV
alex
parents:
2818
diff
changeset
|
16 |
2790 | 17 #ifdef USE_TV |
18 #include "mp_msg.h" | |
19 #include "help_mp.h" | |
20 | |
21 #include "stream.h" | |
22 #include "demuxer.h" | |
23 #include "stheader.h" | |
2830 | 24 |
25 #include "../libao2/afmt.h" | |
26 #include "../libvo/img_format.h" | |
27 #include "../libvo/fastmemcpy.h" | |
28 | |
2802 | 29 #include "tv.h" |
2790 | 30 |
31 /* some default values */ | |
2837 | 32 char *tv_param_freq = NULL; |
2790 | 33 char *tv_param_channel = "0"; |
34 char *tv_param_norm = "pal"; | |
35 char *tv_param_device = NULL; | |
36 char *tv_param_driver = "dummy"; | |
37 int tv_param_width = -1; | |
38 int tv_param_height = -1; | |
2802 | 39 int tv_param_input = 0; /* used in v4l and bttv */ |
2817 | 40 char *tv_param_outfmt = "yv12"; |
2790 | 41 |
42 | |
43 /* ================== DEMUX_TV ===================== */ | |
44 /* | |
45 Return value: | |
46 0 = EOF(?) or no stream | |
47 1 = successfully read a packet | |
48 */ | |
49 /* fill demux->video and demux->audio */ | |
2802 | 50 int demux_tv_fill_buffer(demuxer_t *demux, tvi_handle_t *tvh) |
2790 | 51 { |
2810 | 52 int seq = tvh->seq++; |
2813 | 53 demux_packet_t* dp; |
54 int len; | |
2790 | 55 |
2818 | 56 mp_msg(MSGT_DEMUX, MSGL_DBG2, "demux_tv_fill_buffer(sequence:%d) called!\n", seq); |
2802 | 57 |
2813 | 58 // demux->filepos = -1; |
2790 | 59 |
2810 | 60 // seq++; |
61 // tvh->seq++; | |
2802 | 62 |
2790 | 63 /* ================== ADD VIDEO PACKET =================== */ |
2813 | 64 len = tvh->functions->get_video_framesize(tvh->priv); |
2790 | 65 |
2813 | 66 dp=new_demux_packet(len); |
67 tvh->functions->grab_video_frame(tvh->priv, dp->buffer, len); | |
68 dp->pts=seq/25.0; //(float)pts/90000.0f; | |
69 //dp->pos=pos; | |
70 //dp->flags=flags; | |
71 // append packet to DS stream: | |
72 ds_add_packet(demux->video,dp); | |
2790 | 73 |
74 /* ================== ADD AUDIO PACKET =================== */ | |
2802 | 75 if (tvh->functions->control(tvh->priv, TVI_CONTROL_IS_AUDIO, 0) != TVI_CONTROL_TRUE) |
76 return 1; /* no audio, only video */ | |
77 | |
2813 | 78 len = tvh->functions->get_audio_framesize(tvh->priv); |
79 | |
80 dp=new_demux_packet(len); | |
81 tvh->functions->grab_audio_frame(tvh->priv, dp->buffer, len); | |
82 //dp->pts=pts; //(float)pts/90000.0f; | |
83 //dp->pos=pos; | |
84 //dp->flags=flags; | |
85 // append packet to DS stream: | |
86 ds_add_packet(demux->audio,dp); | |
2790 | 87 |
88 return 1; | |
89 } | |
90 | |
2802 | 91 int demux_open_tv(demuxer_t *demuxer, tvi_handle_t *tvh) |
2790 | 92 { |
2802 | 93 sh_video_t *sh_video = NULL; |
94 sh_audio_t *sh_audio = NULL; | |
2790 | 95 tvi_functions_t *funcs = tvh->functions; |
96 | |
2802 | 97 if (funcs->control(tvh->priv, TVI_CONTROL_IS_VIDEO, 0) != TVI_CONTROL_TRUE) |
98 { | |
2818 | 99 mp_msg(MSGT_TV, MSGL_ERR, "Error: no video input present!\n"); |
2802 | 100 return; |
101 } | |
102 | |
103 sh_video = new_sh_video(demuxer, 0); | |
2790 | 104 |
2817 | 105 if (!strcasecmp(tv_param_outfmt, "yv12")) |
106 sh_video->format = IMGFMT_YV12; | |
107 else if (!strcasecmp(tv_param_outfmt, "uyvy")) | |
108 sh_video->format = IMGFMT_UYVY; | |
109 else if (!strcasecmp(tv_param_outfmt, "rgb32")) | |
110 sh_video->format = IMGFMT_RGB32; | |
111 else if (!strcasecmp(tv_param_outfmt, "rgb24")) | |
112 sh_video->format = IMGFMT_RGB24; | |
113 else if (!strcasecmp(tv_param_outfmt, "rgb16")) | |
114 sh_video->format = IMGFMT_RGB16; | |
115 else if (!strcasecmp(tv_param_outfmt, "rgb15")) | |
116 sh_video->format = IMGFMT_RGB15; | |
117 else | |
118 { | |
2818 | 119 mp_msg(MSGT_TV, MSGL_ERR, "Unknown format given: %s\n", tv_param_outfmt); |
120 mp_msg(MSGT_TV, MSGL_INFO, "Using default: Planar YV12\n"); | |
2817 | 121 sh_video->format = IMGFMT_YV12; |
122 } | |
2802 | 123 funcs->control(tvh->priv, TVI_CONTROL_VID_SET_FORMAT, &sh_video->format); |
2790 | 124 |
2802 | 125 /* get IMGFMT_ */ |
126 funcs->control(tvh->priv, TVI_CONTROL_VID_GET_FORMAT, &sh_video->format); | |
2810 | 127 // if (IMGFMT_IS_RGB(sh_video->format) || IMGFMT_IS_BGR(sh_video->format)) |
2802 | 128 sh_video->format = 0x0; |
129 | |
130 /* set FPS and FRAMETIME */ | |
2790 | 131 if(!sh_video->fps) |
132 { | |
133 if (funcs->control(tvh->priv, TVI_CONTROL_VID_GET_FPS, &sh_video->fps) != TVI_CONTROL_TRUE) | |
134 sh_video->fps = 24.0f; | |
135 } | |
136 sh_video->frametime = 1.0f/sh_video->fps; | |
137 | |
138 /* set width */ | |
139 if (tv_param_width != -1) | |
140 { | |
141 if (funcs->control(tvh->priv, TVI_CONTROL_VID_CHK_WIDTH, &tv_param_width) == TVI_CONTROL_TRUE) | |
142 { | |
143 funcs->control(tvh->priv, TVI_CONTROL_VID_SET_WIDTH, &tv_param_width); | |
144 sh_video->disp_w = tv_param_width; | |
145 } | |
146 else | |
147 { | |
2818 | 148 mp_msg(MSGT_TV, MSGL_ERR, "Unable set requested width: %d\n", tv_param_width); |
2790 | 149 funcs->control(tvh->priv, TVI_CONTROL_VID_GET_WIDTH, &sh_video->disp_w); |
150 tv_param_width = sh_video->disp_w; | |
151 } | |
152 } | |
153 else | |
154 funcs->control(tvh->priv, TVI_CONTROL_VID_GET_WIDTH, &sh_video->disp_w); | |
155 | |
156 /* set height */ | |
157 if (tv_param_height != -1) | |
158 { | |
159 if (funcs->control(tvh->priv, TVI_CONTROL_VID_CHK_HEIGHT, &tv_param_height) == TVI_CONTROL_TRUE) | |
160 { | |
161 funcs->control(tvh->priv, TVI_CONTROL_VID_SET_HEIGHT, &tv_param_height); | |
162 sh_video->disp_h = tv_param_height; | |
163 } | |
164 else | |
165 { | |
2818 | 166 mp_msg(MSGT_TV, MSGL_ERR, "Unable set requested height: %d\n", tv_param_height); |
2790 | 167 funcs->control(tvh->priv, TVI_CONTROL_VID_GET_HEIGHT, &sh_video->disp_h); |
168 tv_param_height = sh_video->disp_h; | |
169 } | |
170 } | |
171 else | |
172 funcs->control(tvh->priv, TVI_CONTROL_VID_GET_HEIGHT, &sh_video->disp_h); | |
2802 | 173 |
2818 | 174 mp_msg(MSGT_TV, MSGL_INFO, "Output size: %dx%d\n", sh_video->disp_w, sh_video->disp_h); |
2790 | 175 |
176 demuxer->video->sh = sh_video; | |
177 sh_video->ds = demuxer->video; | |
178 demuxer->video->id = 0; | |
179 | |
180 /* here comes audio init */ | |
2802 | 181 if (funcs->control(tvh->priv, TVI_CONTROL_IS_AUDIO, 0) == TVI_CONTROL_TRUE) |
182 { | |
183 int audio_format; | |
184 | |
185 sh_audio = new_sh_audio(demuxer, 0); | |
186 | |
187 sh_audio->wf = malloc(sizeof(WAVEFORMATEX)); | |
188 memset(sh_audio->wf, 0, sizeof(WAVEFORMATEX)); | |
189 | |
190 /* yeah, audio is present */ | |
191 if (funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_FORMAT, &audio_format) != TVI_CONTROL_TRUE) | |
192 goto no_audio; | |
193 switch(audio_format) | |
194 { | |
195 case AFMT_U8: | |
196 case AFMT_S8: | |
197 case AFMT_U16_LE: | |
198 case AFMT_U16_BE: | |
199 case AFMT_S16_LE: | |
200 case AFMT_S16_BE: | |
201 case AFMT_S32_LE: | |
202 case AFMT_S32_BE: | |
203 sh_audio->format = 0x1; /* PCM */ | |
204 break; | |
205 case AFMT_IMA_ADPCM: | |
206 case AFMT_MU_LAW: | |
207 case AFMT_A_LAW: | |
208 case AFMT_MPEG: | |
209 case AFMT_AC3: | |
210 default: | |
2818 | 211 mp_msg(MSGT_TV, MSGL_ERR, "Audio type '%s' unsupported!\n", audio_out_format_name(audio_format)); |
2802 | 212 goto no_audio; |
213 } | |
214 | |
215 funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_CHANNELS, &sh_audio->wf->nChannels); | |
216 funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_SAMPLERATE, &sh_audio->wf->nSamplesPerSec); | |
217 funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_SAMPLESIZE, &sh_audio->wf->nAvgBytesPerSec); | |
218 | |
219 demuxer->audio->sh = sh_audio; | |
220 sh_audio->ds = demuxer->audio; | |
221 demuxer->audio->id = 0; | |
222 } | |
223 no_audio: | |
224 | |
225 /* set some params got from cmdline */ | |
226 funcs->control(tvh->priv, TVI_CONTROL_SPC_SET_INPUT, &tv_param_input); | |
227 | |
2837 | 228 /* we need to set frequency */ |
2842 | 229 if (tv_param_freq && (funcs->control(tvh->priv, TVI_CONTROL_IS_TUNER, 0) == TVI_CONTROL_TRUE)) |
2837 | 230 { |
231 unsigned long freq = atof(tv_param_freq)*16; | |
232 | |
233 printf("freq: %lu\n", freq); | |
2802 | 234 |
2837 | 235 /* set freq in MHz */ |
236 funcs->control(tvh->priv, TVI_CONTROL_TUN_SET_FREQ, &freq); | |
237 | |
238 funcs->control(tvh->priv, TVI_CONTROL_TUN_GET_FREQ, &freq); | |
239 mp_msg(MSGT_TV, MSGL_INFO, "Current frequency: %lu (%.3f)\n", | |
240 freq, (float)freq/16); | |
241 } | |
2802 | 242 |
243 /* also start device! */ | |
2837 | 244 return(funcs->start(tvh->priv)); |
2790 | 245 } |
246 | |
247 /* ================== STREAM_TV ===================== */ | |
2802 | 248 tvi_handle_t *tv_begin(void) |
2790 | 249 { |
250 if (!strcmp(tv_param_driver, "dummy")) | |
2802 | 251 return (tvi_handle_t *)tvi_init_dummy(tv_param_device); |
2790 | 252 if (!strcmp(tv_param_driver, "v4l")) |
2802 | 253 return (tvi_handle_t *)tvi_init_v4l(tv_param_device); |
2790 | 254 |
255 mp_msg(MSGT_TV, MSGL_ERR, "No such driver: %s\n", tv_param_driver); | |
256 return(NULL); | |
257 } | |
258 | |
2802 | 259 int tv_init(tvi_handle_t *tvh) |
2790 | 260 { |
2802 | 261 tvi_param_t *params; |
262 | |
2818 | 263 mp_msg(MSGT_TV, MSGL_INFO, "Selected driver: %s\n", tvh->info->short_name); |
264 mp_msg(MSGT_TV, MSGL_INFO, " name: %s\n", tvh->info->name); | |
265 mp_msg(MSGT_TV, MSGL_INFO, " author: %s\n", tvh->info->author); | |
2802 | 266 if (tvh->info->comment) |
2818 | 267 mp_msg(MSGT_TV, MSGL_INFO, " comment: %s\n", tvh->info->comment); |
2790 | 268 |
2802 | 269 params = malloc(sizeof(tvi_param_t)*2); |
270 params[0].opt = malloc(strlen("input")); | |
271 sprintf((char *)params[0].opt, "input"); | |
272 params[0].value = malloc(sizeof(int)); | |
273 (int)*(void **)params[0].value = tv_param_input; | |
274 params[1].opt = params[1].value = NULL; | |
275 | |
2837 | 276 return(tvh->functions->init(tvh->priv, params)); |
277 } | |
278 | |
279 int tv_uninit(tvi_handle_t *tvh) | |
280 { | |
281 return(tvh->functions->uninit(tvh->priv)); | |
2790 | 282 } |
283 #endif /* USE_TV */ |