• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * RAW PCM demuxers
3  * Copyright (c) 2002 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_components.h"
23 
24 #include "libavutil/avstring.h"
25 #include "libavutil/channel_layout.h"
26 #include "avformat.h"
27 #include "internal.h"
28 #include "pcm.h"
29 #include "libavutil/log.h"
30 #include "libavutil/opt.h"
31 #include "libavutil/avassert.h"
32 
33 typedef struct PCMAudioDemuxerContext {
34     AVClass *class;
35     int sample_rate;
36 #if FF_API_OLD_CHANNEL_LAYOUT
37     int channels;
38 #endif
39     AVChannelLayout ch_layout;
40 } PCMAudioDemuxerContext;
41 
pcm_read_header(AVFormatContext * s)42 static int pcm_read_header(AVFormatContext *s)
43 {
44     PCMAudioDemuxerContext *s1 = s->priv_data;
45     AVCodecParameters *par;
46     AVStream *st;
47     uint8_t *mime_type = NULL;
48     int ret;
49 
50     st = avformat_new_stream(s, NULL);
51     if (!st)
52         return AVERROR(ENOMEM);
53     par = st->codecpar;
54 
55     par->codec_type  = AVMEDIA_TYPE_AUDIO;
56     par->codec_id    = s->iformat->raw_codec_id;
57     par->sample_rate = s1->sample_rate;
58 #if FF_API_OLD_CHANNEL_LAYOUT
59     if (s1->ch_layout.nb_channels) {
60 #endif
61     ret = av_channel_layout_copy(&par->ch_layout, &s1->ch_layout);
62     if (ret < 0)
63         return ret;
64 #if FF_API_OLD_CHANNEL_LAYOUT
65     } else
66         par->ch_layout.nb_channels = s1->channels;
67 #endif
68 
69     av_opt_get(s->pb, "mime_type", AV_OPT_SEARCH_CHILDREN, &mime_type);
70     if (mime_type && s->iformat->mime_type) {
71         int rate = 0, channels = 0, little_endian = 0;
72         const char *options;
73         if (av_stristart(mime_type, s->iformat->mime_type, &options)) { /* audio/L16 */
74             while (options = strchr(options, ';')) {
75                 options++;
76                 if (!rate)
77                     sscanf(options, " rate=%d",     &rate);
78                 if (!channels)
79                     sscanf(options, " channels=%d", &channels);
80                 if (!little_endian) {
81                      char val[sizeof("little-endian")];
82                      if (sscanf(options, " endianness=%13s", val) == 1) {
83                          little_endian = strcmp(val, "little-endian") == 0;
84                      }
85                 }
86             }
87             if (rate <= 0) {
88                 av_log(s, AV_LOG_ERROR,
89                        "Invalid sample_rate found in mime_type \"%s\"\n",
90                        mime_type);
91                 av_freep(&mime_type);
92                 return AVERROR_INVALIDDATA;
93             }
94             par->sample_rate = rate;
95             if (channels > 0) {
96                 av_channel_layout_uninit(&par->ch_layout);
97                 par->ch_layout.nb_channels = channels;
98             }
99             if (little_endian)
100                 par->codec_id = AV_CODEC_ID_PCM_S16LE;
101         }
102     }
103     av_freep(&mime_type);
104 
105     par->bits_per_coded_sample = av_get_bits_per_sample(par->codec_id);
106 
107     av_assert0(par->bits_per_coded_sample > 0);
108 
109     par->block_align = par->bits_per_coded_sample * par->ch_layout.nb_channels / 8;
110 
111     avpriv_set_pts_info(st, 64, 1, par->sample_rate);
112     return 0;
113 }
114 
115 static const AVOption pcm_options[] = {
116     { "sample_rate", "", offsetof(PCMAudioDemuxerContext, sample_rate), AV_OPT_TYPE_INT, {.i64 = 44100}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
117 #if FF_API_OLD_CHANNEL_LAYOUT
118     { "channels",    "", offsetof(PCMAudioDemuxerContext, channels),    AV_OPT_TYPE_INT, {.i64 = 1}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_DEPRECATED },
119     { "ch_layout",   "", offsetof(PCMAudioDemuxerContext, ch_layout),   AV_OPT_TYPE_CHLAYOUT, {.str = NULL}, 0, 0, AV_OPT_FLAG_DECODING_PARAM },
120 #else
121     { "ch_layout",   "", offsetof(PCMAudioDemuxerContext, ch_layout),   AV_OPT_TYPE_CHLAYOUT, {.str = "mono"}, 0, 0, AV_OPT_FLAG_DECODING_PARAM },
122 #endif
123     { NULL },
124 };
125 static const AVClass pcm_demuxer_class = {
126     .class_name = "pcm demuxer",
127     .item_name  = av_default_item_name,
128     .option     = pcm_options,
129     .version    = LIBAVUTIL_VERSION_INT,
130 };
131 
132 #define PCMDEF_0(name_, long_name_, ext, codec, ...)
133 #define PCMDEF_1(name_, long_name_, ext, codec, ...)        \
134 const AVInputFormat ff_pcm_ ## name_ ## _demuxer = {        \
135     .name           = #name_,                               \
136     .long_name      = NULL_IF_CONFIG_SMALL(long_name_),     \
137     .priv_data_size = sizeof(PCMAudioDemuxerContext),       \
138     .read_header    = pcm_read_header,                      \
139     .read_packet    = ff_pcm_read_packet,                   \
140     .read_seek      = ff_pcm_read_seek,                     \
141     .flags          = AVFMT_GENERIC_INDEX,                  \
142     .extensions     = ext,                                  \
143     .raw_codec_id   = codec,                                \
144     .priv_class     = &pcm_demuxer_class,                   \
145     __VA_ARGS__                                             \
146 };
147 #define PCMDEF_2(name, long_name, ext, codec, enabled, ...) \
148     PCMDEF_ ## enabled(name, long_name, ext, codec, __VA_ARGS__)
149 #define PCMDEF_3(name, long_name, ext, codec, config, ...)  \
150     PCMDEF_2(name, long_name, ext, codec, config,   __VA_ARGS__)
151 #define PCMDEF_EXT(name, long_name, ext, uppercase, ...)    \
152     PCMDEF_3(name, long_name, ext, AV_CODEC_ID_PCM_ ## uppercase, \
153              CONFIG_PCM_ ## uppercase ## _DEMUXER,  __VA_ARGS__)
154 #define PCMDEF(name, long_name, ext, uppercase)             \
155     PCMDEF_EXT(name, long_name, ext, uppercase, )
156 
157 PCMDEF(f64be, "PCM 64-bit floating-point big-endian",           NULL, F64BE)
158 PCMDEF(f64le, "PCM 64-bit floating-point little-endian",        NULL, F64LE)
159 PCMDEF(f32be, "PCM 32-bit floating-point big-endian",           NULL, F32BE)
160 PCMDEF(f32le, "PCM 32-bit floating-point little-endian",        NULL, F32LE)
161 PCMDEF(s32be, "PCM signed 32-bit big-endian",                   NULL, S32BE)
162 PCMDEF(s32le, "PCM signed 32-bit little-endian",                NULL, S32LE)
163 PCMDEF(s24be, "PCM signed 24-bit big-endian",                   NULL, S24BE)
164 PCMDEF(s24le, "PCM signed 24-bit little-endian",                NULL, S24LE)
165 PCMDEF_EXT(s16be, "PCM signed 16-bit big-endian",
166            AV_NE("sw", NULL), S16BE, .mime_type = "audio/L16")
167 PCMDEF(s16le, "PCM signed 16-bit little-endian",   AV_NE(NULL, "sw"), S16LE)
168 PCMDEF(s8,    "PCM signed 8-bit",                               "sb",    S8)
169 PCMDEF(u32be, "PCM unsigned 32-bit big-endian",                 NULL, U32BE)
170 PCMDEF(u32le, "PCM unsigned 32-bit little-endian",              NULL, U32LE)
171 PCMDEF(u24be, "PCM unsigned 24-bit big-endian",                 NULL, U24BE)
172 PCMDEF(u24le, "PCM unsigned 24-bit little-endian",              NULL, U24LE)
173 PCMDEF(u16be, "PCM unsigned 16-bit big-endian",    AV_NE("uw", NULL), U16BE)
174 PCMDEF(u16le, "PCM unsigned 16-bit little-endian", AV_NE(NULL, "uw"), U16LE)
175 PCMDEF(u8,    "PCM unsigned 8-bit",                             "ub",    U8)
176 PCMDEF(alaw,  "PCM A-law",                                      "al",  ALAW)
177 PCMDEF(mulaw, "PCM mu-law",                                     "ul", MULAW)
178 PCMDEF(vidc,  "PCM Archimedes VIDC",                            NULL,  VIDC)
179 
180 #if CONFIG_SLN_DEMUXER
181 static const AVOption sln_options[] = {
182     { "sample_rate", "", offsetof(PCMAudioDemuxerContext, sample_rate), AV_OPT_TYPE_INT, {.i64 = 8000}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
183 #if FF_API_OLD_CHANNEL_LAYOUT
184     { "channels",    "", offsetof(PCMAudioDemuxerContext, channels),    AV_OPT_TYPE_INT, {.i64 = 1}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_DEPRECATED },
185     { "ch_layout",   "", offsetof(PCMAudioDemuxerContext, ch_layout),   AV_OPT_TYPE_CHLAYOUT, {.str = NULL}, 0, 0, AV_OPT_FLAG_DECODING_PARAM },
186 #else
187     { "ch_layout",   "", offsetof(PCMAudioDemuxerContext, ch_layout),   AV_OPT_TYPE_CHLAYOUT, {.str = "mono"}, 0, 0, AV_OPT_FLAG_DECODING_PARAM },
188 #endif
189     { NULL },
190 };
191 
192 static const AVClass sln_demuxer_class = {
193     .class_name = "sln demuxer",
194     .item_name  = av_default_item_name,
195     .option     = sln_options,
196     .version    = LIBAVUTIL_VERSION_INT,
197 };
198 
199 const AVInputFormat ff_sln_demuxer = {
200     .name           = "sln",
201     .long_name      = NULL_IF_CONFIG_SMALL("Asterisk raw pcm"),
202     .priv_data_size = sizeof(PCMAudioDemuxerContext),
203     .read_header    = pcm_read_header,
204     .read_packet    = ff_pcm_read_packet,
205     .read_seek      = ff_pcm_read_seek,
206     .flags          = AVFMT_GENERIC_INDEX,
207     .extensions     = "sln",
208     .raw_codec_id   = AV_CODEC_ID_PCM_S16LE,
209     .priv_class     = &sln_demuxer_class,
210 };
211 #endif
212