annotate audio.c @ 617:1ca4877e42f3 libavformat

some sanity checks on what is muxed, invalid timestamps in mpeg are very common and lead to strange errors in the mpeg muxer otherwise
author michael
date Tue, 14 Dec 2004 16:19:26 +0000
parents 0fdc96c2f2fe
children aa52767bb802
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
1 /*
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
2 * Linux audio play and grab interface
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
3 * Copyright (c) 2000, 2001 Fabrice Bellard.
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
4 *
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
5 * This library is free software; you can redistribute it and/or
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
6 * modify it under the terms of the GNU Lesser General Public
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
7 * License as published by the Free Software Foundation; either
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
8 * version 2 of the License, or (at your option) any later version.
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
9 *
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
10 * This library is distributed in the hope that it will be useful,
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
13 * Lesser General Public License for more details.
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
14 *
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
15 * You should have received a copy of the GNU Lesser General Public
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
16 * License along with this library; if not, write to the Free Software
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
18 */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
19 #include "avformat.h"
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
20
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
21 #include <stdlib.h>
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
22 #include <stdio.h>
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
23 #include <string.h>
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
24 #include <sys/soundcard.h>
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
25 #include <unistd.h>
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
26 #include <fcntl.h>
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
27 #include <sys/ioctl.h>
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
28 #include <sys/mman.h>
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
29 #include <sys/time.h>
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
30
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
31 #define AUDIO_BLOCK_SIZE 4096
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
32
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
33 typedef struct {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
34 int fd;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
35 int sample_rate;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
36 int channels;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
37 int frame_size; /* in bytes ! */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
38 int codec_id;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
39 int flip_left : 1;
65
a58a8a53eb46 * UINTX -> uintx_t INTX -> intx_t
kabi
parents: 56
diff changeset
40 uint8_t buffer[AUDIO_BLOCK_SIZE];
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
41 int buffer_ptr;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
42 } AudioData;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
43
30
90fd30dd68b3 grab device is in AVFormatParameter (at least better than global variable)
bellard
parents: 0
diff changeset
44 static int audio_open(AudioData *s, int is_output, const char *audio_device)
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
45 {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
46 int audio_fd;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
47 int tmp, err;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
48 char *flip = getenv("AUDIO_FLIP_LEFT");
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
49
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
50 /* open linux audio device */
30
90fd30dd68b3 grab device is in AVFormatParameter (at least better than global variable)
bellard
parents: 0
diff changeset
51 if (!audio_device)
90fd30dd68b3 grab device is in AVFormatParameter (at least better than global variable)
bellard
parents: 0
diff changeset
52 audio_device = "/dev/dsp";
90fd30dd68b3 grab device is in AVFormatParameter (at least better than global variable)
bellard
parents: 0
diff changeset
53
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
54 if (is_output)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
55 audio_fd = open(audio_device, O_WRONLY);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
56 else
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
57 audio_fd = open(audio_device, O_RDONLY);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
58 if (audio_fd < 0) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
59 perror(audio_device);
482
0fdc96c2f2fe sweeping change from -EIO -> AVERROR_IO
melanson
parents: 481
diff changeset
60 return AVERROR_IO;
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
61 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
62
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
63 if (flip && *flip == '1') {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
64 s->flip_left = 1;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
65 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
66
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
67 /* non blocking mode */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
68 if (!is_output)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
69 fcntl(audio_fd, F_SETFL, O_NONBLOCK);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
70
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
71 s->frame_size = AUDIO_BLOCK_SIZE;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
72 #if 0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
73 tmp = (NB_FRAGMENTS << 16) | FRAGMENT_BITS;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
74 err = ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &tmp);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
75 if (err < 0) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
76 perror("SNDCTL_DSP_SETFRAGMENT");
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
77 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
78 #endif
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
79
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
80 /* select format : favour native format */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
81 err = ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &tmp);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
82
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
83 #ifdef WORDS_BIGENDIAN
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
84 if (tmp & AFMT_S16_BE) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
85 tmp = AFMT_S16_BE;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
86 } else if (tmp & AFMT_S16_LE) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
87 tmp = AFMT_S16_LE;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
88 } else {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
89 tmp = 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
90 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
91 #else
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
92 if (tmp & AFMT_S16_LE) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
93 tmp = AFMT_S16_LE;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
94 } else if (tmp & AFMT_S16_BE) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
95 tmp = AFMT_S16_BE;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
96 } else {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
97 tmp = 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
98 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
99 #endif
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
100
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
101 switch(tmp) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
102 case AFMT_S16_LE:
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
103 s->codec_id = CODEC_ID_PCM_S16LE;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
104 break;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
105 case AFMT_S16_BE:
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
106 s->codec_id = CODEC_ID_PCM_S16BE;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
107 break;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
108 default:
370
845f9de2c883 av_log() patch by (Michel Bardiaux <mbardiaux at peaktime dot be>)
michael
parents: 241
diff changeset
109 av_log(NULL, AV_LOG_ERROR, "Soundcard does not support 16 bit sample format\n");
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
110 close(audio_fd);
482
0fdc96c2f2fe sweeping change from -EIO -> AVERROR_IO
melanson
parents: 481
diff changeset
111 return AVERROR_IO;
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
112 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
113 err=ioctl(audio_fd, SNDCTL_DSP_SETFMT, &tmp);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
114 if (err < 0) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
115 perror("SNDCTL_DSP_SETFMT");
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
116 goto fail;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
117 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
118
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
119 tmp = (s->channels == 2);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
120 err = ioctl(audio_fd, SNDCTL_DSP_STEREO, &tmp);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
121 if (err < 0) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
122 perror("SNDCTL_DSP_STEREO");
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
123 goto fail;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
124 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
125 if (tmp)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
126 s->channels = 2;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
127
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
128 tmp = s->sample_rate;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
129 err = ioctl(audio_fd, SNDCTL_DSP_SPEED, &tmp);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
130 if (err < 0) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
131 perror("SNDCTL_DSP_SPEED");
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
132 goto fail;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
133 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
134 s->sample_rate = tmp; /* store real sample rate */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
135 s->fd = audio_fd;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
136
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
137 return 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
138 fail:
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
139 close(audio_fd);
482
0fdc96c2f2fe sweeping change from -EIO -> AVERROR_IO
melanson
parents: 481
diff changeset
140 return AVERROR_IO;
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
141 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
142
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
143 static int audio_close(AudioData *s)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
144 {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
145 close(s->fd);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
146 return 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
147 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
148
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
149 /* sound output support */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
150 static int audio_write_header(AVFormatContext *s1)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
151 {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
152 AudioData *s = s1->priv_data;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
153 AVStream *st;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
154 int ret;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
155
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
156 st = s1->streams[0];
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
157 s->sample_rate = st->codec.sample_rate;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
158 s->channels = st->codec.channels;
30
90fd30dd68b3 grab device is in AVFormatParameter (at least better than global variable)
bellard
parents: 0
diff changeset
159 ret = audio_open(s, 1, NULL);
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
160 if (ret < 0) {
482
0fdc96c2f2fe sweeping change from -EIO -> AVERROR_IO
melanson
parents: 481
diff changeset
161 return AVERROR_IO;
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
162 } else {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
163 return 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
164 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
165 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
166
468
60f897e8dd2d pass AVPacket into av_write_frame()
michael
parents: 462
diff changeset
167 static int audio_write_packet(AVFormatContext *s1, AVPacket *pkt)
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
168 {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
169 AudioData *s = s1->priv_data;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
170 int len, ret;
468
60f897e8dd2d pass AVPacket into av_write_frame()
michael
parents: 462
diff changeset
171 int size= pkt->size;
60f897e8dd2d pass AVPacket into av_write_frame()
michael
parents: 462
diff changeset
172 uint8_t *buf= pkt->data;
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
173
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
174 while (size > 0) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
175 len = AUDIO_BLOCK_SIZE - s->buffer_ptr;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
176 if (len > size)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
177 len = size;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
178 memcpy(s->buffer + s->buffer_ptr, buf, len);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
179 s->buffer_ptr += len;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
180 if (s->buffer_ptr >= AUDIO_BLOCK_SIZE) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
181 for(;;) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
182 ret = write(s->fd, s->buffer, AUDIO_BLOCK_SIZE);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
183 if (ret > 0)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
184 break;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
185 if (ret < 0 && (errno != EAGAIN && errno != EINTR))
482
0fdc96c2f2fe sweeping change from -EIO -> AVERROR_IO
melanson
parents: 481
diff changeset
186 return AVERROR_IO;
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
187 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
188 s->buffer_ptr = 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
189 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
190 buf += len;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
191 size -= len;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
192 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
193 return 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
194 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
195
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
196 static int audio_write_trailer(AVFormatContext *s1)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
197 {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
198 AudioData *s = s1->priv_data;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
199
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
200 audio_close(s);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
201 return 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
202 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
203
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
204 /* grab support */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
205
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
206 static int audio_read_header(AVFormatContext *s1, AVFormatParameters *ap)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
207 {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
208 AudioData *s = s1->priv_data;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
209 AVStream *st;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
210 int ret;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
211
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
212 if (!ap || ap->sample_rate <= 0 || ap->channels <= 0)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
213 return -1;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
214
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
215 st = av_new_stream(s1, 0);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
216 if (!st) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
217 return -ENOMEM;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
218 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
219 s->sample_rate = ap->sample_rate;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
220 s->channels = ap->channels;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
221
30
90fd30dd68b3 grab device is in AVFormatParameter (at least better than global variable)
bellard
parents: 0
diff changeset
222 ret = audio_open(s, 0, ap->device);
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
223 if (ret < 0) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
224 av_free(st);
482
0fdc96c2f2fe sweeping change from -EIO -> AVERROR_IO
melanson
parents: 481
diff changeset
225 return AVERROR_IO;
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
226 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
227
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
228 /* take real parameters */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
229 st->codec.codec_type = CODEC_TYPE_AUDIO;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
230 st->codec.codec_id = s->codec_id;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
231 st->codec.sample_rate = s->sample_rate;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
232 st->codec.channels = s->channels;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
233
462
b69898ffc92a move time_base (pts_num/pts_den) from AVFormatContext -> AVStream
michael
parents: 370
diff changeset
234 av_set_pts_info(st, 48, 1, 1000000); /* 48 bits pts in us */
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
235 return 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
236 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
237
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
238 static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
239 {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
240 AudioData *s = s1->priv_data;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
241 int ret, bdelay;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
242 int64_t cur_time;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
243 struct audio_buf_info abufi;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
244
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
245 if (av_new_packet(pkt, s->frame_size) < 0)
482
0fdc96c2f2fe sweeping change from -EIO -> AVERROR_IO
melanson
parents: 481
diff changeset
246 return AVERROR_IO;
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
247 for(;;) {
56
01d48dc59dab Fix the 'hard cpu loop' problem when capturing audio from /dev/dsp. This
philipjsg
parents: 30
diff changeset
248 struct timeval tv;
01d48dc59dab Fix the 'hard cpu loop' problem when capturing audio from /dev/dsp. This
philipjsg
parents: 30
diff changeset
249 fd_set fds;
01d48dc59dab Fix the 'hard cpu loop' problem when capturing audio from /dev/dsp. This
philipjsg
parents: 30
diff changeset
250
01d48dc59dab Fix the 'hard cpu loop' problem when capturing audio from /dev/dsp. This
philipjsg
parents: 30
diff changeset
251 tv.tv_sec = 0;
01d48dc59dab Fix the 'hard cpu loop' problem when capturing audio from /dev/dsp. This
philipjsg
parents: 30
diff changeset
252 tv.tv_usec = 30 * 1000; /* 30 msecs -- a bit shorter than 1 frame at 30fps */
01d48dc59dab Fix the 'hard cpu loop' problem when capturing audio from /dev/dsp. This
philipjsg
parents: 30
diff changeset
253
01d48dc59dab Fix the 'hard cpu loop' problem when capturing audio from /dev/dsp. This
philipjsg
parents: 30
diff changeset
254 FD_ZERO(&fds);
01d48dc59dab Fix the 'hard cpu loop' problem when capturing audio from /dev/dsp. This
philipjsg
parents: 30
diff changeset
255 FD_SET(s->fd, &fds);
01d48dc59dab Fix the 'hard cpu loop' problem when capturing audio from /dev/dsp. This
philipjsg
parents: 30
diff changeset
256
01d48dc59dab Fix the 'hard cpu loop' problem when capturing audio from /dev/dsp. This
philipjsg
parents: 30
diff changeset
257 /* This will block until data is available or we get a timeout */
01d48dc59dab Fix the 'hard cpu loop' problem when capturing audio from /dev/dsp. This
philipjsg
parents: 30
diff changeset
258 (void) select(s->fd + 1, &fds, 0, 0, &tv);
01d48dc59dab Fix the 'hard cpu loop' problem when capturing audio from /dev/dsp. This
philipjsg
parents: 30
diff changeset
259
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
260 ret = read(s->fd, pkt->data, pkt->size);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
261 if (ret > 0)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
262 break;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
263 if (ret == -1 && (errno == EAGAIN || errno == EINTR)) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
264 av_free_packet(pkt);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
265 pkt->size = 0;
481
f1430abbbd8b A/V Synch in ffmpeg patch by (Luca Abeni <lucabe72 at email dot it>)
michael
parents: 468
diff changeset
266 pkt->pts = av_gettime() & ((1LL << 48) - 1);
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
267 return 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
268 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
269 if (!(ret == 0 || (ret == -1 && (errno == EAGAIN || errno == EINTR)))) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
270 av_free_packet(pkt);
482
0fdc96c2f2fe sweeping change from -EIO -> AVERROR_IO
melanson
parents: 481
diff changeset
271 return AVERROR_IO;
0
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
272 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
273 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
274 pkt->size = ret;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
275
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
276 /* compute pts of the start of the packet */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
277 cur_time = av_gettime();
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
278 bdelay = ret;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
279 if (ioctl(s->fd, SNDCTL_DSP_GETISPACE, &abufi) == 0) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
280 bdelay += abufi.bytes;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
281 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
282 /* substract time represented by the number of bytes in the audio fifo */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
283 cur_time -= (bdelay * 1000000LL) / (s->sample_rate * s->channels);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
284
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
285 /* convert to wanted units */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
286 pkt->pts = cur_time & ((1LL << 48) - 1);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
287
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
288 if (s->flip_left && s->channels == 2) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
289 int i;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
290 short *p = (short *) pkt->data;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
291
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
292 for (i = 0; i < ret; i += 4) {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
293 *p = ~*p;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
294 p += 2;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
295 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
296 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
297 return 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
298 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
299
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
300 static int audio_read_close(AVFormatContext *s1)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
301 {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
302 AudioData *s = s1->priv_data;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
303
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
304 audio_close(s);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
305 return 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
306 }
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
307
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
308 static AVInputFormat audio_in_format = {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
309 "audio_device",
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
310 "audio grab and output",
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
311 sizeof(AudioData),
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
312 NULL,
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
313 audio_read_header,
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
314 audio_read_packet,
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
315 audio_read_close,
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
316 .flags = AVFMT_NOFILE,
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
317 };
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
318
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
319 static AVOutputFormat audio_out_format = {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
320 "audio_device",
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
321 "audio grab and output",
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
322 "",
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
323 "",
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
324 sizeof(AudioData),
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
325 /* XXX: we make the assumption that the soundcard accepts this format */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
326 /* XXX: find better solution with "preinit" method, needed also in
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
327 other formats */
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
328 #ifdef WORDS_BIGENDIAN
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
329 CODEC_ID_PCM_S16BE,
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
330 #else
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
331 CODEC_ID_PCM_S16LE,
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
332 #endif
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
333 CODEC_ID_NONE,
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
334 audio_write_header,
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
335 audio_write_packet,
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
336 audio_write_trailer,
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
337 .flags = AVFMT_NOFILE,
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
338 };
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
339
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
340 int audio_init(void)
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
341 {
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
342 av_register_input_format(&audio_in_format);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
343 av_register_output_format(&audio_out_format);
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
344 return 0;
05318cf2e886 renamed libav to libavformat
bellard
parents:
diff changeset
345 }