Mercurial > mplayer.hg
comparison libmpdemux/tv.c @ 5087:1d54c3a27093
audio support and pts based packet handling by Charles Henrich
author | alex |
---|---|
date | Fri, 15 Mar 2002 16:07:06 +0000 |
parents | 70ac7ab2a982 |
children | 8cd761968f35 |
comparison
equal
deleted
inserted
replaced
5086:69778ca88835 | 5087:1d54c3a27093 |
---|---|
3 | 3 |
4 (C) Alex Beregszaszi <alex@naxine.org> | 4 (C) Alex Beregszaszi <alex@naxine.org> |
5 | 5 |
6 API idea based on libvo2 | 6 API idea based on libvo2 |
7 | 7 |
8 UNDER HEAVY DEVELOPEMENT, NO FEATURE REQUESTS PLEASE! :) | 8 Feb 19, 2002: Significant rewrites by Charles R. Henrich (henrich@msu.edu) |
9 try to fix audio support, and bktr *BSD support. | |
10 | |
9 */ | 11 */ |
10 | 12 |
11 #include <stdio.h> | 13 #include <stdio.h> |
12 #include <stdlib.h> | 14 #include <stdlib.h> |
13 #include <unistd.h> | 15 #include <unistd.h> |
14 #include <string.h> | 16 #include <string.h> |
17 #include <sys/time.h> | |
15 | 18 |
16 #include "config.h" | 19 #include "config.h" |
17 | 20 |
18 int tv_param_on = 0; | 21 int tv_param_on = 0; |
19 | 22 |
32 #include "tv.h" | 35 #include "tv.h" |
33 | 36 |
34 #include "frequencies.h" | 37 #include "frequencies.h" |
35 | 38 |
36 /* some default values */ | 39 /* some default values */ |
40 int tv_param_noaudio = 0; | |
37 char *tv_param_freq = NULL; | 41 char *tv_param_freq = NULL; |
38 char *tv_param_channel = NULL; | 42 char *tv_param_channel = NULL; |
39 char *tv_param_norm = "pal"; | 43 char *tv_param_norm = "pal"; |
40 char *tv_param_chanlist = "europe-east"; | 44 char *tv_param_chanlist = "europe-east"; |
41 char *tv_param_device = NULL; | 45 char *tv_param_device = NULL; |
51 Return value: | 55 Return value: |
52 0 = EOF(?) or no stream | 56 0 = EOF(?) or no stream |
53 1 = successfully read a packet | 57 1 = successfully read a packet |
54 */ | 58 */ |
55 /* fill demux->video and demux->audio */ | 59 /* fill demux->video and demux->audio */ |
60 | |
56 int demux_tv_fill_buffer(demuxer_t *demux, tvi_handle_t *tvh) | 61 int demux_tv_fill_buffer(demuxer_t *demux, tvi_handle_t *tvh) |
57 { | 62 { |
58 int seq = tvh->seq++; | |
59 demux_packet_t* dp; | 63 demux_packet_t* dp; |
60 int len; | 64 |
61 sh_video_t *sh_video = demux->video->sh; | 65 sh_video_t *sh_video = demux->video->sh; |
62 | 66 u_int len; |
63 mp_dbg(MSGT_DEMUX, MSGL_DBG2, "demux_tv_fill_buffer(sequence:%d) called!\n", seq); | 67 u_int cframe; |
64 | 68 int aframeswaiting; |
65 // demux->filepos = -1; | 69 |
66 | 70 len = cframe = -1; |
67 // seq++; | 71 |
68 // tvh->seq++; | 72 /* ================== ADD AUDIO PACKET =================== */ |
73 | |
74 if (tv_param_noaudio == 0 && | |
75 tvh->functions->control(tvh->priv, | |
76 TVI_CONTROL_IS_AUDIO, 0) == TVI_CONTROL_TRUE) | |
77 { | |
78 len = tvh->functions->get_audio_framesize(tvh->priv); | |
79 | |
80 do { | |
81 dp=new_demux_packet(len); | |
82 aframeswaiting=tvh->functions->grab_audio_frame(tvh->priv, | |
83 dp->buffer,len); | |
84 dp->pts=tvh->seq/sh_video->fps; | |
85 dp->pos=tvh->seq*len; | |
86 ds_add_packet(demux->audio,dp); | |
87 | |
88 tvh->seq++; | |
89 | |
90 } while (aframeswaiting > 0); | |
91 } | |
69 | 92 |
70 /* ================== ADD VIDEO PACKET =================== */ | 93 /* ================== ADD VIDEO PACKET =================== */ |
71 len = tvh->functions->get_video_framesize(tvh->priv); | 94 |
72 | 95 if (tvh->functions->control(tvh->priv, |
73 dp=new_demux_packet(len); | 96 TVI_CONTROL_IS_VIDEO, 0) == TVI_CONTROL_TRUE) |
74 tvh->functions->grab_video_frame(tvh->priv, dp->buffer, len); | 97 { |
75 dp->pts=seq/sh_video->fps; //(float)pts/90000.0f; | 98 len = tvh->functions->get_video_framesize(tvh->priv); |
76 //dp->pos=pos; | 99 |
77 //dp->flags=flags; | 100 dp=new_demux_packet(len); |
78 // append packet to DS stream: | 101 |
79 ds_add_packet(demux->video,dp); | 102 cframe=tvh->functions->grab_video_frame(tvh->priv, dp->buffer, |
80 | 103 len); |
81 /* ================== ADD AUDIO PACKET =================== */ | 104 |
82 if (tvh->functions->control(tvh->priv, TVI_CONTROL_IS_AUDIO, 0) != TVI_CONTROL_TRUE) | 105 if(tv_param_noaudio == 1) tvh->seq = cframe; |
83 return 1; /* no audio, only video */ | 106 |
84 | 107 dp->pos=tvh->seq*len; |
85 len = tvh->functions->get_audio_framesize(tvh->priv); | 108 dp->pts=tvh->seq/sh_video->fps; |
86 | 109 |
87 dp=new_demux_packet(len); | 110 ds_add_packet(demux->video,dp); |
88 tvh->functions->grab_audio_frame(tvh->priv, dp->buffer, len); | 111 } |
89 //dp->pts=pts; //(float)pts/90000.0f; | |
90 //dp->pos=pos; | |
91 //dp->flags=flags; | |
92 // append packet to DS stream: | |
93 ds_add_packet(demux->audio,dp); | |
94 | 112 |
95 return 1; | 113 return 1; |
96 } | 114 } |
97 | 115 |
98 int stream_open_tv(stream_t *stream, tvi_handle_t *tvh) | 116 int stream_open_tv(stream_t *stream, tvi_handle_t *tvh) |
165 tvh->norm = TV_NORM_NTSC; | 183 tvh->norm = TV_NORM_NTSC; |
166 else if (!strcasecmp(tv_param_norm, "secam")) | 184 else if (!strcasecmp(tv_param_norm, "secam")) |
167 tvh->norm = TV_NORM_SECAM; | 185 tvh->norm = TV_NORM_SECAM; |
168 | 186 |
169 mp_msg(MSGT_TV, MSGL_INFO, "Selected norm: %s\n", tv_param_norm); | 187 mp_msg(MSGT_TV, MSGL_INFO, "Selected norm: %s\n", tv_param_norm); |
188 funcs->control(tvh->priv, TVI_CONTROL_TUN_SET_NORM, &tvh->norm); | |
170 | 189 |
171 if (funcs->control(tvh->priv, TVI_CONTROL_IS_TUNER, 0) != TVI_CONTROL_TRUE) | 190 if (funcs->control(tvh->priv, TVI_CONTROL_IS_TUNER, 0) != TVI_CONTROL_TRUE) |
172 { | 191 { |
173 mp_msg(MSGT_TV, MSGL_WARN, "Selected input hasn't got a tuner!\n"); | 192 mp_msg(MSGT_TV, MSGL_WARN, "Selected input hasn't got a tuner!\n"); |
174 goto start_device; | 193 goto start_device; |
249 funcs->control(tvh->priv, TVI_CONTROL_VID_GET_FORMAT, &sh_video->format); | 268 funcs->control(tvh->priv, TVI_CONTROL_VID_GET_FORMAT, &sh_video->format); |
250 // if (IMGFMT_IS_RGB(sh_video->format) || IMGFMT_IS_BGR(sh_video->format)) | 269 // if (IMGFMT_IS_RGB(sh_video->format) || IMGFMT_IS_BGR(sh_video->format)) |
251 // sh_video->format = 0x0; | 270 // sh_video->format = 0x0; |
252 | 271 |
253 /* set FPS and FRAMETIME */ | 272 /* set FPS and FRAMETIME */ |
273 | |
254 if(!sh_video->fps) | 274 if(!sh_video->fps) |
255 { | 275 { |
256 if (funcs->control(tvh->priv, TVI_CONTROL_VID_GET_FPS, &sh_video->fps) != TVI_CONTROL_TRUE) | 276 int tmp; |
257 sh_video->fps = 25.0f; /* on PAL */ | 277 if (funcs->control(tvh->priv, TVI_CONTROL_VID_GET_FPS, &tmp) != TVI_CONTROL_TRUE) |
258 } | 278 sh_video->fps = 25.0f; /* on PAL */ |
279 else sh_video->fps = tmp; | |
280 } | |
281 | |
259 if (tv_param_fps != -1.0f) | 282 if (tv_param_fps != -1.0f) |
260 sh_video->fps = tv_param_fps; | 283 sh_video->fps = tv_param_fps; |
284 | |
261 sh_video->frametime = 1.0f/sh_video->fps; | 285 sh_video->frametime = 1.0f/sh_video->fps; |
262 | 286 |
263 printf("fps: %f, frametime: %f\n", sh_video->fps, sh_video->frametime); | 287 printf("fps: %f, frametime: %f\n", sh_video->fps, sh_video->frametime); |
264 | 288 |
265 /* set width */ | 289 /* set width */ |
275 demuxer->video->id = 0; | 299 demuxer->video->id = 0; |
276 | 300 |
277 // demuxer->seekable = 0; | 301 // demuxer->seekable = 0; |
278 | 302 |
279 /* here comes audio init */ | 303 /* here comes audio init */ |
280 if (funcs->control(tvh->priv, TVI_CONTROL_IS_AUDIO, 0) == TVI_CONTROL_TRUE) | 304 |
305 if (tv_param_noaudio == 0 && funcs->control(tvh->priv, TVI_CONTROL_IS_AUDIO, 0) == TVI_CONTROL_TRUE) | |
281 { | 306 { |
282 int audio_format; | 307 int audio_format; |
283 | 308 int sh_audio_format; |
284 sh_audio = new_sh_audio(demuxer, 0); | 309 |
285 | |
286 sh_audio->wf = malloc(sizeof(WAVEFORMATEX)); | |
287 memset(sh_audio->wf, 0, sizeof(WAVEFORMATEX)); | |
288 | |
289 /* yeah, audio is present */ | 310 /* yeah, audio is present */ |
290 if (funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_FORMAT, &audio_format) != TVI_CONTROL_TRUE) | 311 if (funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_FORMAT, &audio_format) != TVI_CONTROL_TRUE) |
291 goto no_audio; | 312 goto no_audio; |
292 sh_audio->sample_format = audio_format; | 313 |
293 sh_audio->wf->wBitsPerSample = 16; | |
294 switch(audio_format) | 314 switch(audio_format) |
295 { | 315 { |
296 case AFMT_U8: | 316 case AFMT_U8: |
297 case AFMT_S8: | 317 case AFMT_S8: |
298 case AFMT_U16_LE: | 318 case AFMT_U16_LE: |
299 case AFMT_U16_BE: | 319 case AFMT_U16_BE: |
300 case AFMT_S16_LE: | 320 case AFMT_S16_LE: |
301 case AFMT_S16_BE: | 321 case AFMT_S16_BE: |
302 case AFMT_S32_LE: | 322 case AFMT_S32_LE: |
303 case AFMT_S32_BE: | 323 case AFMT_S32_BE: |
304 sh_audio->format = 0x1; /* PCM */ | 324 sh_audio_format = 0x1; /* PCM */ |
305 break; | 325 break; |
306 case AFMT_IMA_ADPCM: | 326 case AFMT_IMA_ADPCM: |
307 case AFMT_MU_LAW: | 327 case AFMT_MU_LAW: |
308 case AFMT_A_LAW: | 328 case AFMT_A_LAW: |
309 case AFMT_MPEG: | 329 case AFMT_MPEG: |
311 default: | 331 default: |
312 mp_msg(MSGT_TV, MSGL_ERR, "Audio type '%s' unsupported!\n", audio_out_format_name(audio_format)); | 332 mp_msg(MSGT_TV, MSGL_ERR, "Audio type '%s' unsupported!\n", audio_out_format_name(audio_format)); |
313 goto no_audio; | 333 goto no_audio; |
314 } | 334 } |
315 | 335 |
316 funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_CHANNELS, &sh_audio->wf->nChannels); | 336 sh_audio = new_sh_audio(demuxer, 0); |
317 funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_SAMPLERATE, &sh_audio->wf->nSamplesPerSec); | 337 sh_audio->wf = (WAVEFORMATEX *)malloc(sizeof(WAVEFORMATEX)); |
318 funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_SAMPLESIZE, &sh_audio->wf->nAvgBytesPerSec); | 338 |
339 funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_SAMPLERATE, | |
340 &sh_audio->samplerate); | |
341 funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_SAMPLESIZE, | |
342 &sh_audio->samplesize); | |
343 funcs->control(tvh->priv, TVI_CONTROL_AUD_GET_CHANNELS, | |
344 &sh_audio->channels); | |
345 | |
346 sh_audio->format = sh_audio_format; | |
347 sh_audio->sample_format = audio_format; | |
348 | |
349 sh_audio->i_bps = sh_audio->o_bps = | |
350 sh_audio->samplerate * sh_audio->samplesize/8 * | |
351 sh_audio->channels; | |
352 | |
353 sh_audio->wf->wFormatTag = sh_audio->format; | |
354 sh_audio->wf->nChannels = sh_audio->channels; | |
355 switch(audio_format) | |
356 { | |
357 case AFMT_U8: | |
358 case AFMT_S8: | |
359 sh_audio->wf->wBitsPerSample = 8; | |
360 break; | |
361 case AFMT_U16_LE: | |
362 case AFMT_U16_BE: | |
363 case AFMT_S16_LE: | |
364 case AFMT_S16_BE: | |
365 sh_audio->wf->wBitsPerSample = 16; | |
366 break; | |
367 case AFMT_S32_LE: | |
368 case AFMT_S32_BE: | |
369 sh_audio->wf->wBitsPerSample = 32; | |
370 break; | |
371 } | |
372 sh_audio->wf->nSamplesPerSec = sh_audio->samplerate; | |
373 sh_audio->wf->nBlockAlign = sh_audio->wf->nAvgBytesPerSec; | |
374 sh_audio->wf->nAvgBytesPerSec = sh_audio->wf->nChannels * | |
375 sh_audio->samplesize/8 * | |
376 sh_audio->samplerate; | |
319 | 377 |
320 demuxer->audio->sh = sh_audio; | 378 demuxer->audio->sh = sh_audio; |
321 sh_audio->ds = demuxer->audio; | 379 sh_audio->ds = demuxer->audio; |
322 demuxer->audio->id = 0; | 380 demuxer->audio->id = 0; |
323 } | 381 } |
333 return (tvi_handle_t *)tvi_init_dummy(tv_param_device); | 391 return (tvi_handle_t *)tvi_init_dummy(tv_param_device); |
334 #ifdef HAVE_TV_V4L | 392 #ifdef HAVE_TV_V4L |
335 if (!strcmp(tv_param_driver, "v4l")) | 393 if (!strcmp(tv_param_driver, "v4l")) |
336 return (tvi_handle_t *)tvi_init_v4l(tv_param_device); | 394 return (tvi_handle_t *)tvi_init_v4l(tv_param_device); |
337 #endif | 395 #endif |
396 #ifdef HAVE_TV_BSDBT848 | |
397 if (!strcmp(tv_param_driver, "bsdbt848")) | |
398 return (tvi_handle_t *)tvi_init_bsdbt848(tv_param_device); | |
399 #endif | |
338 | 400 |
339 mp_msg(MSGT_TV, MSGL_ERR, "No such driver: %s\n", tv_param_driver); | 401 mp_msg(MSGT_TV, MSGL_ERR, "No such driver: %s\n", tv_param_driver); |
340 return(NULL); | 402 return(NULL); |
341 } | 403 } |
342 | 404 |