oss_audio.c
Go to the documentation of this file.
1 /*
2  * Linux audio play and grab interface
3  * Copyright (c) 2000, 2001 Fabrice Bellard
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "config.h"
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <stdint.h>
26 #include <string.h>
27 #include <errno.h>
28 #if HAVE_SOUNDCARD_H
29 #include <soundcard.h>
30 #else
31 #include <sys/soundcard.h>
32 #endif
33 #include <unistd.h>
34 #include <fcntl.h>
35 #include <sys/ioctl.h>
36 
37 #include "libavutil/log.h"
38 #include "libavutil/opt.h"
39 #include "libavutil/time.h"
40 #include "libavcodec/avcodec.h"
41 #include "avdevice.h"
42 #include "libavformat/internal.h"
43 
44 #define AUDIO_BLOCK_SIZE 4096
45 
46 typedef struct {
47  AVClass *class;
48  int fd;
50  int channels;
51  int frame_size; /* in bytes ! */
53  unsigned int flip_left : 1;
56 } AudioData;
57 
58 static int audio_open(AVFormatContext *s1, int is_output, const char *audio_device)
59 {
60  AudioData *s = s1->priv_data;
61  int audio_fd;
62  int tmp, err;
63  char *flip = getenv("AUDIO_FLIP_LEFT");
64 
65  if (is_output)
66  audio_fd = open(audio_device, O_WRONLY);
67  else
68  audio_fd = open(audio_device, O_RDONLY);
69  if (audio_fd < 0) {
70  av_log(s1, AV_LOG_ERROR, "%s: %s\n", audio_device, strerror(errno));
71  return AVERROR(EIO);
72  }
73 
74  if (flip && *flip == '1') {
75  s->flip_left = 1;
76  }
77 
78  /* non blocking mode */
79  if (!is_output) {
80  if (fcntl(audio_fd, F_SETFL, O_NONBLOCK) < 0) {
81  av_log(s1, AV_LOG_WARNING, "%s: Could not enable non block mode (%s)\n", audio_device, strerror(errno));
82  }
83  }
84 
86 
87  /* select format : favour native format */
88  err = ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &tmp);
89 
90 #if HAVE_BIGENDIAN
91  if (tmp & AFMT_S16_BE) {
92  tmp = AFMT_S16_BE;
93  } else if (tmp & AFMT_S16_LE) {
94  tmp = AFMT_S16_LE;
95  } else {
96  tmp = 0;
97  }
98 #else
99  if (tmp & AFMT_S16_LE) {
100  tmp = AFMT_S16_LE;
101  } else if (tmp & AFMT_S16_BE) {
102  tmp = AFMT_S16_BE;
103  } else {
104  tmp = 0;
105  }
106 #endif
107 
108  switch(tmp) {
109  case AFMT_S16_LE:
111  break;
112  case AFMT_S16_BE:
114  break;
115  default:
116  av_log(s1, AV_LOG_ERROR, "Soundcard does not support 16 bit sample format\n");
117  close(audio_fd);
118  return AVERROR(EIO);
119  }
120  err=ioctl(audio_fd, SNDCTL_DSP_SETFMT, &tmp);
121  if (err < 0) {
122  av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_SETFMT: %s\n", strerror(errno));
123  goto fail;
124  }
125 
126  tmp = (s->channels == 2);
127  err = ioctl(audio_fd, SNDCTL_DSP_STEREO, &tmp);
128  if (err < 0) {
129  av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_STEREO: %s\n", strerror(errno));
130  goto fail;
131  }
132 
133  tmp = s->sample_rate;
134  err = ioctl(audio_fd, SNDCTL_DSP_SPEED, &tmp);
135  if (err < 0) {
136  av_log(s1, AV_LOG_ERROR, "SNDCTL_DSP_SPEED: %s\n", strerror(errno));
137  goto fail;
138  }
139  s->sample_rate = tmp; /* store real sample rate */
140  s->fd = audio_fd;
141 
142  return 0;
143  fail:
144  close(audio_fd);
145  return AVERROR(EIO);
146 }
147 
148 static int audio_close(AudioData *s)
149 {
150  close(s->fd);
151  return 0;
152 }
153 
154 /* sound output support */
156 {
157  AudioData *s = s1->priv_data;
158  AVStream *st;
159  int ret;
160 
161  st = s1->streams[0];
162  s->sample_rate = st->codec->sample_rate;
163  s->channels = st->codec->channels;
164  ret = audio_open(s1, 1, s1->filename);
165  if (ret < 0) {
166  return AVERROR(EIO);
167  } else {
168  return 0;
169  }
170 }
171 
173 {
174  AudioData *s = s1->priv_data;
175  int len, ret;
176  int size= pkt->size;
177  uint8_t *buf= pkt->data;
178 
179  while (size > 0) {
180  len = FFMIN(AUDIO_BLOCK_SIZE - s->buffer_ptr, size);
181  memcpy(s->buffer + s->buffer_ptr, buf, len);
182  s->buffer_ptr += len;
183  if (s->buffer_ptr >= AUDIO_BLOCK_SIZE) {
184  for(;;) {
185  ret = write(s->fd, s->buffer, AUDIO_BLOCK_SIZE);
186  if (ret > 0)
187  break;
188  if (ret < 0 && (errno != EAGAIN && errno != EINTR))
189  return AVERROR(EIO);
190  }
191  s->buffer_ptr = 0;
192  }
193  buf += len;
194  size -= len;
195  }
196  return 0;
197 }
198 
200 {
201  AudioData *s = s1->priv_data;
202 
203  audio_close(s);
204  return 0;
205 }
206 
207 /* grab support */
208 
210 {
211  AudioData *s = s1->priv_data;
212  AVStream *st;
213  int ret;
214 
215  st = avformat_new_stream(s1, NULL);
216  if (!st) {
217  return AVERROR(ENOMEM);
218  }
219 
220  ret = audio_open(s1, 0, s1->filename);
221  if (ret < 0) {
222  return AVERROR(EIO);
223  }
224 
225  /* take real parameters */
227  st->codec->codec_id = s->codec_id;
228  st->codec->sample_rate = s->sample_rate;
229  st->codec->channels = s->channels;
230 
231  avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */
232  return 0;
233 }
234 
236 {
237  AudioData *s = s1->priv_data;
238  int ret, bdelay;
239  int64_t cur_time;
240  struct audio_buf_info abufi;
241 
242  if ((ret=av_new_packet(pkt, s->frame_size)) < 0)
243  return ret;
244 
245  ret = read(s->fd, pkt->data, pkt->size);
246  if (ret <= 0){
247  av_free_packet(pkt);
248  pkt->size = 0;
249  if (ret<0) return AVERROR(errno);
250  else return AVERROR_EOF;
251  }
252  pkt->size = ret;
253 
254  /* compute pts of the start of the packet */
255  cur_time = av_gettime();
256  bdelay = ret;
257  if (ioctl(s->fd, SNDCTL_DSP_GETISPACE, &abufi) == 0) {
258  bdelay += abufi.bytes;
259  }
260  /* subtract time represented by the number of bytes in the audio fifo */
261  cur_time -= (bdelay * 1000000LL) / (s->sample_rate * s->channels);
262 
263  /* convert to wanted units */
264  pkt->pts = cur_time;
265 
266  if (s->flip_left && s->channels == 2) {
267  int i;
268  short *p = (short *) pkt->data;
269 
270  for (i = 0; i < ret; i += 4) {
271  *p = ~*p;
272  p += 2;
273  }
274  }
275  return 0;
276 }
277 
279 {
280  AudioData *s = s1->priv_data;
281 
282  audio_close(s);
283  return 0;
284 }
285 
286 #if CONFIG_OSS_INDEV
287 static const AVOption options[] = {
288  { "sample_rate", "", offsetof(AudioData, sample_rate), AV_OPT_TYPE_INT, {.i64 = 48000}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
289  { "channels", "", offsetof(AudioData, channels), AV_OPT_TYPE_INT, {.i64 = 2}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
290  { NULL },
291 };
292 
293 static const AVClass oss_demuxer_class = {
294  .class_name = "OSS demuxer",
295  .item_name = av_default_item_name,
296  .option = options,
297  .version = LIBAVUTIL_VERSION_INT,
298 };
299 
300 AVInputFormat ff_oss_demuxer = {
301  .name = "oss",
302  .long_name = NULL_IF_CONFIG_SMALL("OSS (Open Sound System) capture"),
303  .priv_data_size = sizeof(AudioData),
307  .flags = AVFMT_NOFILE,
308  .priv_class = &oss_demuxer_class,
309 };
310 #endif
311 
312 #if CONFIG_OSS_OUTDEV
313 AVOutputFormat ff_oss_muxer = {
314  .name = "oss",
315  .long_name = NULL_IF_CONFIG_SMALL("OSS (Open Sound System) playback"),
316  .priv_data_size = sizeof(AudioData),
317  /* XXX: we make the assumption that the soundcard accepts this format */
318  /* XXX: find better solution with "preinit" method, needed also in
319  other formats */
321  .video_codec = AV_CODEC_ID_NONE,
322  .write_header = audio_write_header,
323  .write_packet = audio_write_packet,
324  .write_trailer = audio_write_trailer,
325  .flags = AVFMT_NOFILE,
326 };
327 #endif
const char * s
Definition: avisynth_c.h:668
struct AudioData AudioData
void av_free_packet(AVPacket *pkt)
Free a packet.
Definition: avpacket.c:242
AVOption.
Definition: opt.h:251
Audio buffer used for intermediate storage between conversion phases.
Definition: oss_audio.c:46
av_default_item_name
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:154
static int64_t cur_time
Definition: ffserver.c:325
Format I/O context.
Definition: avformat.h:944
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:55
uint8_t
static int audio_write_header(AVFormatContext *s1)
Definition: oss_audio.c:155
AVOptions.
static AVPacket pkt
Definition: demuxing.c:56
#define AV_NE(be, le)
Definition: common.h:44
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
int buffer_ptr
Definition: oss_audio.c:55
AVStream ** streams
Definition: avformat.h:992
static int audio_write_trailer(AVFormatContext *s1)
Definition: oss_audio.c:199
static int audio_read_close(AVFormatContext *s1)
Definition: oss_audio.c:278
uint8_t * data
#define AVERROR_EOF
End of file.
Definition: error.h:55
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:145
static int audio_open(AVFormatContext *s1, int is_output, const char *audio_device)
Definition: oss_audio.c:58
const OptionDef options[]
Definition: ffserver.c:4697
Main libavdevice API header.
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: avpacket.c:73
AVCodecID
Identify the syntax and semantics of the bitstream.
int channels
channel count
Definition: oss_audio.c:50
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
enum AVCodecID codec_id
Definition: mov_chan.c:433
external API header
enum AVCodecID codec_id
Definition: oss_audio.c:52
int size
AVCodecContext * codec
Codec context associated with this stream.
Definition: avformat.h:662
char filename[1024]
input or output filename
Definition: avformat.h:994
#define FFMIN(a, b)
Definition: common.h:58
ret
Definition: avfilter.c:821
static int audio_close(AudioData *s)
Definition: oss_audio.c:148
const char * name
Definition: avformat.h:378
unsigned int flip_left
Definition: oss_audio.c:53
LIBAVUTIL_VERSION_INT
Definition: eval.c:55
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:517
int64_t av_gettime(void)
Get the current time in microseconds.
Definition: time.c:39
Stream structure.
Definition: avformat.h:643
NULL
Definition: eval.c:55
sample_rate
uint8_t buffer[AUDIO_BLOCK_SIZE]
Definition: oss_audio.c:54
enum AVMediaType codec_type
enum AVCodecID codec_id
static int audio_read_header(AVFormatContext *s1)
Definition: oss_audio.c:209
int sample_rate
samples per second
static void close(AVCodecParserContext *s)
Definition: h264_parser.c:375
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
void * buf
Definition: avisynth_c.h:594
static int read_packet(AVFormatContext *ctx, AVPacket *pkt)
Definition: libcdio.c:114
#define AUDIO_BLOCK_SIZE
Definition: oss_audio.c:44
static int audio_write_packet(AVFormatContext *s1, AVPacket *pkt)
Definition: oss_audio.c:172
Describe the class of an AVClass context structure.
Definition: log.h:50
synthesis window for stochastic i
#define AV_OPT_FLAG_DECODING_PARAM
a generic parameter which can be set by the user for demuxing or decoding
Definition: opt.h:282
#define s1
Definition: regdef.h:38
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Buffer references ownership and permissions
static int flags
Definition: cpu.c:23
#define AVFMT_NOFILE
Demuxer will use avio_open, no opened file should be provided by the caller.
Definition: avformat.h:345
int sample_rate
Definition: oss_audio.c:49
static void flip(AVCodecContext *avctx, AVPicture *picture)
int fd
Definition: oss_audio.c:48
the buffer and buffer reference mechanism is intended to as much as expensive copies of that data while still allowing the filters to produce correct results The data is stored in buffers represented by AVFilterBuffer structures They must not be accessed but through references stored in AVFilterBufferRef structures Several references can point to the same buffer
int len
int channels
number of audio channels
void * priv_data
Format private data.
Definition: avformat.h:964
int frame_size
Definition: oss_audio.c:51
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:461
static int audio_read_packet(AVFormatContext *s1, AVPacket *pkt)
Definition: oss_audio.c:235
This structure stores compressed data.
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
for(j=16;j >0;--j)