2 * sndio play and grab interface
3 * Copyright (c) 2010 Jacob Meuser
5 * This file is part of FFmpeg.
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.
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.
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
25 #include "libavformat/avformat.h"
26 #include "libavformat/internal.h"
27 #include "libavutil/opt.h"
28 #include "libavutil/time.h"
30 #include "sndio_common.h"
32 static av_cold
int audio_read_header(AVFormatContext
*s1
)
34 SndioData
*s
= s1
->priv_data
;
38 st
= avformat_new_stream(s1
, NULL
);
40 return AVERROR(ENOMEM
);
42 ret
= ff_sndio_open(s1
, 0, s1
->filename
);
46 /* take real parameters */
47 st
->codec
->codec_type
= AVMEDIA_TYPE_AUDIO
;
48 st
->codec
->codec_id
= s
->codec_id
;
49 st
->codec
->sample_rate
= s
->sample_rate
;
50 st
->codec
->channels
= s
->channels
;
52 avpriv_set_pts_info(st
, 64, 1, 1000000); /* 64 bits pts in us */
57 static int audio_read_packet(AVFormatContext
*s1
, AVPacket
*pkt
)
59 SndioData
*s
= s1
->priv_data
;
60 int64_t bdelay
, cur_time
;
63 if ((ret
= av_new_packet(pkt
, s
->buffer_size
)) < 0)
66 ret
= sio_read(s
->hdl
, pkt
->data
, pkt
->size
);
67 if (ret
== 0 || sio_eof(s
->hdl
)) {
75 /* compute pts of the start of the packet */
76 cur_time
= av_gettime();
78 bdelay
= ret
+ s
->hwpos
- s
->softpos
;
81 pkt
->pts
= cur_time
- ((bdelay
* 1000000) /
82 (s
->bps
* s
->channels
* s
->sample_rate
));
87 static av_cold
int audio_read_close(AVFormatContext
*s1
)
89 SndioData
*s
= s1
->priv_data
;
96 static const AVOption options
[] = {
97 { "sample_rate", "", offsetof(SndioData
, sample_rate
), AV_OPT_TYPE_INT
, {.i64
= 48000}, 1, INT_MAX
, AV_OPT_FLAG_DECODING_PARAM
},
98 { "channels", "", offsetof(SndioData
, channels
), AV_OPT_TYPE_INT
, {.i64
= 2}, 1, INT_MAX
, AV_OPT_FLAG_DECODING_PARAM
},
102 static const AVClass sndio_demuxer_class
= {
103 .class_name
= "sndio indev",
104 .item_name
= av_default_item_name
,
106 .version
= LIBAVUTIL_VERSION_INT
,
107 .category
= AV_CLASS_CATEGORY_DEVICE_AUDIO_INPUT
,
110 AVInputFormat ff_sndio_demuxer
= {
112 .long_name
= NULL_IF_CONFIG_SMALL("sndio audio capture"),
113 .priv_data_size
= sizeof(SndioData
),
114 .read_header
= audio_read_header
,
115 .read_packet
= audio_read_packet
,
116 .read_close
= audio_read_close
,
117 .flags
= AVFMT_NOFILE
,
118 .priv_class
= &sndio_demuxer_class
,