Mercurial > mplayer.hg
comparison libmpdemux/ai_alsa1x.c @ 7060:b14880a6cccb
new v4l capture patch by Jindrich Makovicka <makovick@kmlinux.fjfi.cvut.cz>:
- multithreaded audio/video buffering (I know mplayer crew hates threads
but it seems to me as the only way of doing reliable a/v capture)
- a/v timebase synchronization (sample count vs. gettimeofday)
- "immediate" mode support for mplayer
- fixed colorspace stuff - RGB?? and YUY2 modes now work as expected
- native ALSA audio capture
- separated audio input layer
author | arpi |
---|---|
date | Wed, 21 Aug 2002 22:50:40 +0000 |
parents | |
children | aaac9080b8a3 |
comparison
equal
deleted
inserted
replaced
7059:5285a81929a5 | 7060:b14880a6cccb |
---|---|
1 #include "config.h" | |
2 | |
3 #ifdef HAVE_ALSA9 | |
4 #include <alsa/asoundlib.h> | |
5 #include "audio_in.h" | |
6 #include "mp_msg.h" | |
7 | |
8 int ai_alsa_setup(audio_in_t *ai) | |
9 { | |
10 snd_pcm_hw_params_t *params; | |
11 snd_pcm_sw_params_t *swparams; | |
12 size_t buffer_size; | |
13 int err; | |
14 size_t n; | |
15 unsigned int rate; | |
16 snd_pcm_uframes_t start_threshold, stop_threshold; | |
17 | |
18 snd_pcm_hw_params_alloca(¶ms); | |
19 snd_pcm_sw_params_alloca(&swparams); | |
20 | |
21 err = snd_pcm_hw_params_any(ai->alsa.handle, params); | |
22 if (err < 0) { | |
23 mp_msg(MSGT_TV, MSGL_ERR, "Broken configuration for this PCM: no configurations available\n"); | |
24 return -1; | |
25 } | |
26 err = snd_pcm_hw_params_set_access(ai->alsa.handle, params, | |
27 SND_PCM_ACCESS_RW_INTERLEAVED); | |
28 if (err < 0) { | |
29 mp_msg(MSGT_TV, MSGL_ERR, "Access type not available\n"); | |
30 return -1; | |
31 } | |
32 err = snd_pcm_hw_params_set_format(ai->alsa.handle, params, SND_PCM_FORMAT_S16_LE); | |
33 if (err < 0) { | |
34 mp_msg(MSGT_TV, MSGL_ERR, "Sample format not available\n"); | |
35 return -1; | |
36 } | |
37 err = snd_pcm_hw_params_set_channels(ai->alsa.handle, params, ai->req_channels); | |
38 if (err < 0) { | |
39 ai->channels = snd_pcm_hw_params_get_channels(params); | |
40 mp_msg(MSGT_TV, MSGL_ERR, "Channel count not available - reverting to default: %d\n", | |
41 ai->channels); | |
42 } else { | |
43 ai->channels = ai->req_channels; | |
44 } | |
45 | |
46 err = snd_pcm_hw_params_set_rate_near(ai->alsa.handle, params, ai->req_samplerate, 0); | |
47 assert(err >= 0); | |
48 rate = err; | |
49 ai->samplerate = rate; | |
50 | |
51 ai->alsa.buffer_time = 1000000; | |
52 ai->alsa.buffer_time = snd_pcm_hw_params_set_buffer_time_near(ai->alsa.handle, params, | |
53 ai->alsa.buffer_time, 0); | |
54 assert(ai->alsa.buffer_time >= 0); | |
55 ai->alsa.period_time = ai->alsa.buffer_time / 4; | |
56 ai->alsa.period_time = snd_pcm_hw_params_set_period_time_near(ai->alsa.handle, params, | |
57 ai->alsa.period_time, 0); | |
58 assert(ai->alsa.period_time >= 0); | |
59 err = snd_pcm_hw_params(ai->alsa.handle, params); | |
60 if (err < 0) { | |
61 mp_msg(MSGT_TV, MSGL_ERR, "Unable to install hw params:"); | |
62 snd_pcm_hw_params_dump(params, ai->alsa.log); | |
63 return -1; | |
64 } | |
65 ai->alsa.chunk_size = snd_pcm_hw_params_get_period_size(params, 0); | |
66 buffer_size = snd_pcm_hw_params_get_buffer_size(params); | |
67 if (ai->alsa.chunk_size == buffer_size) { | |
68 mp_msg(MSGT_TV, MSGL_ERR, "Can't use period equal to buffer size (%u == %lu)\n", ai->alsa.chunk_size, (long)buffer_size); | |
69 return -1; | |
70 } | |
71 snd_pcm_sw_params_current(ai->alsa.handle, swparams); | |
72 err = snd_pcm_sw_params_set_sleep_min(ai->alsa.handle, swparams,0); | |
73 assert(err >= 0); | |
74 err = snd_pcm_sw_params_set_avail_min(ai->alsa.handle, swparams, ai->alsa.chunk_size); | |
75 assert(err >= 0); | |
76 | |
77 err = snd_pcm_sw_params_set_start_threshold(ai->alsa.handle, swparams, 0); | |
78 assert(err >= 0); | |
79 err = snd_pcm_sw_params_set_stop_threshold(ai->alsa.handle, swparams, buffer_size); | |
80 assert(err >= 0); | |
81 | |
82 assert(err >= 0); | |
83 if (snd_pcm_sw_params(ai->alsa.handle, swparams) < 0) { | |
84 mp_msg(MSGT_TV, MSGL_ERR, "unable to install sw params:\n"); | |
85 snd_pcm_sw_params_dump(swparams, ai->alsa.log); | |
86 return -1; | |
87 } | |
88 | |
89 if (mp_msg_test(MSGT_TV, MSGL_V)) { | |
90 snd_pcm_dump(ai->alsa.handle, ai->alsa.log); | |
91 } | |
92 | |
93 ai->alsa.bits_per_sample = snd_pcm_format_physical_width(SND_PCM_FORMAT_S16_LE); | |
94 ai->alsa.bits_per_frame = ai->alsa.bits_per_sample * ai->channels; | |
95 ai->blocksize = ai->alsa.chunk_size * ai->alsa.bits_per_frame / 8; | |
96 ai->samplesize = ai->alsa.bits_per_sample; | |
97 ai->bytes_per_sample = ai->alsa.bits_per_sample/8; | |
98 | |
99 return 0; | |
100 } | |
101 | |
102 int ai_alsa_init(audio_in_t *ai) | |
103 { | |
104 int err; | |
105 | |
106 err = snd_pcm_open(&ai->alsa.handle, ai->alsa.device, SND_PCM_STREAM_CAPTURE, 0); | |
107 if (err < 0) { | |
108 mp_msg(MSGT_TV, MSGL_ERR, "Error opening audio"); | |
109 return -1; | |
110 } | |
111 | |
112 err = snd_output_stdio_attach(&ai->alsa.log, stderr, 0); | |
113 | |
114 if (err < 0) { | |
115 return -1; | |
116 } | |
117 | |
118 err = ai_alsa_setup(ai); | |
119 | |
120 return err; | |
121 } | |
122 | |
123 #endif /* HAVE_ALSA9 */ |