2 * Limitless Audio Format demuxer
3 * Copyright (c) 2022 Paul B Mahol
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
22 #include "libavutil/intfloat.h"
23 #include "libavutil/intreadwrite.h"
24 #include "libavutil/mem.h"
26 #include "avio_internal.h"
30 #define MAX_STREAMS 4096
32 typedef struct StreamParams
{
33 AVChannelLayout layout
;
40 typedef struct LAFContext
{
43 unsigned stored_index
;
47 StreamParams p
[MAX_STREAMS
];
50 uint8_t header
[(MAX_STREAMS
+ 7) / 8];
53 static int laf_probe(const AVProbeData
*p
)
55 if (memcmp(p
->buf
, "LIMITLESS", 9))
57 if (memcmp(p
->buf
+ 9, "HEAD", 4))
59 return AVPROBE_SCORE_MAX
;
62 static int laf_read_header(AVFormatContext
*ctx
)
64 LAFContext
*s
= ctx
->priv_data
;
65 AVIOContext
*pb
= ctx
->pb
;
66 unsigned st_count
, mode
;
74 if (avio_rb32(pb
) != MKBETAG('H','E','A','D'))
75 return AVERROR_INVALIDDATA
;
77 quality
= avio_r8(pb
);
79 return AVERROR_INVALIDDATA
;
82 return AVERROR_INVALIDDATA
;
83 st_count
= avio_rl32(pb
);
84 if (st_count
== 0 || st_count
> MAX_STREAMS
)
85 return AVERROR_INVALIDDATA
;
87 for (int i
= 0; i
< st_count
; i
++) {
88 StreamParams
*stp
= &s
->p
[i
];
90 stp
->vertical
= av_int2float(avio_rl32(pb
));
91 stp
->horizontal
= av_int2float(avio_rl32(pb
));
92 stp
->lfe
= avio_r8(pb
);
94 stp
->layout
= (AVChannelLayout
)AV_CHANNEL_LAYOUT_MASK(1, (AV_CH_LOW_FREQUENCY
));
95 } else if (stp
->vertical
== 0.f
&&
96 stp
->horizontal
== 0.f
) {
97 stp
->layout
= (AVChannelLayout
)AV_CHANNEL_LAYOUT_MASK(1, (AV_CH_FRONT_CENTER
));
98 } else if (stp
->vertical
== 0.f
&&
99 stp
->horizontal
== -30.f
) {
100 stp
->layout
= (AVChannelLayout
)AV_CHANNEL_LAYOUT_MASK(1, (AV_CH_FRONT_LEFT
));
101 } else if (stp
->vertical
== 0.f
&&
102 stp
->horizontal
== 30.f
) {
103 stp
->layout
= (AVChannelLayout
)AV_CHANNEL_LAYOUT_MASK(1, (AV_CH_FRONT_RIGHT
));
104 } else if (stp
->vertical
== 0.f
&&
105 stp
->horizontal
== -110.f
) {
106 stp
->layout
= (AVChannelLayout
)AV_CHANNEL_LAYOUT_MASK(1, (AV_CH_SIDE_LEFT
));
107 } else if (stp
->vertical
== 0.f
&&
108 stp
->horizontal
== 110.f
) {
109 stp
->layout
= (AVChannelLayout
)AV_CHANNEL_LAYOUT_MASK(1, (AV_CH_SIDE_RIGHT
));
111 stp
->layout
= (AVChannelLayout
)AV_CHANNEL_LAYOUT_MONO
;
115 sample_rate
= avio_rl32(pb
);
116 duration
= avio_rl64(pb
) / st_count
;
119 return AVERROR_INVALIDDATA
;
123 codec_id
= AV_CODEC_ID_PCM_U8
;
127 codec_id
= AV_CODEC_ID_PCM_S16LE
;
131 codec_id
= AV_CODEC_ID_PCM_F32LE
;
135 codec_id
= AV_CODEC_ID_PCM_S24LE
;
139 return AVERROR_INVALIDDATA
;
145 if ((int64_t)bpp
* st_count
* (int64_t)sample_rate
>= INT32_MAX
||
146 (int64_t)bpp
* st_count
* (int64_t)sample_rate
== 0
148 return AVERROR_INVALIDDATA
;
149 s
->data
= av_calloc(st_count
* sample_rate
, bpp
);
151 return AVERROR(ENOMEM
);
153 for (unsigned i
= 0; i
< st_count
; i
++) {
154 StreamParams
*stp
= &s
->p
[i
];
155 AVCodecParameters
*par
;
156 AVStream
*st
= avformat_new_stream(ctx
, NULL
);
158 return AVERROR(ENOMEM
);
161 par
->codec_id
= codec_id
;
162 par
->codec_type
= AVMEDIA_TYPE_AUDIO
;
163 par
->ch_layout
.nb_channels
= 1;
164 par
->ch_layout
= stp
->layout
;
165 par
->sample_rate
= sample_rate
;
166 st
->duration
= duration
;
168 avpriv_set_pts_info(st
, 64, 1, st
->codecpar
->sample_rate
);
171 s
->header_len
= (ctx
->nb_streams
+ 7) / 8;
176 static int laf_read_packet(AVFormatContext
*ctx
, AVPacket
*pkt
)
178 AVIOContext
*pb
= ctx
->pb
;
179 LAFContext
*s
= ctx
->priv_data
;
180 AVStream
*st
= ctx
->streams
[0];
181 const int bpp
= s
->bpp
;
192 if (s
->index
>= ctx
->nb_streams
) {
193 int cur_st
= 0, st_count
= 0, st_index
= 0;
195 ret
= ffio_read_size(pb
, s
->header
, s
->header_len
);
198 for (int i
= 0; i
< s
->header_len
; i
++) {
199 uint8_t val
= s
->header
[i
];
201 for (int j
= 0; j
< 8 && cur_st
< ctx
->nb_streams
; j
++, cur_st
++) {
202 StreamParams
*stp
= &s
->p
[st_index
];
214 s
->index
= s
->stored_index
= 0;
215 s
->nb_stored
= st_count
;
217 return AVERROR_INVALIDDATA
;
218 ret
= ffio_read_size(pb
, s
->data
, st_count
* st
->codecpar
->sample_rate
* bpp
);
223 st
= ctx
->streams
[s
->index
];
224 stp
= &s
->p
[s
->index
];
225 while (!stp
->stored
) {
227 if (s
->index
>= ctx
->nb_streams
)
229 stp
= &s
->p
[s
->index
];
231 st
= ctx
->streams
[s
->index
];
233 ret
= av_new_packet(pkt
, st
->codecpar
->sample_rate
* bpp
);
239 for (int n
= 0; n
< st
->codecpar
->sample_rate
; n
++)
240 pkt
->data
[n
] = s
->data
[n
* s
->nb_stored
+ s
->stored_index
];
243 for (int n
= 0; n
< st
->codecpar
->sample_rate
; n
++)
244 AV_WN16(pkt
->data
+ n
* 2, AV_RN16(s
->data
+ n
* s
->nb_stored
* 2 + s
->stored_index
* 2));
247 for (int n
= 0; n
< st
->codecpar
->sample_rate
; n
++)
248 AV_WL24(pkt
->data
+ n
* 3, AV_RL24(s
->data
+ n
* s
->nb_stored
* 3 + s
->stored_index
* 3));
251 for (int n
= 0; n
< st
->codecpar
->sample_rate
; n
++)
252 AV_WN32(pkt
->data
+ n
* 4, AV_RN32(s
->data
+ n
* s
->nb_stored
* 4 + s
->stored_index
* 4));
256 pkt
->stream_index
= s
->index
;
264 static int laf_read_close(AVFormatContext
*ctx
)
266 LAFContext
*s
= ctx
->priv_data
;
273 static int laf_read_seek(AVFormatContext
*ctx
, int stream_index
,
274 int64_t timestamp
, int flags
)
276 LAFContext
*s
= ctx
->priv_data
;
278 s
->stored_index
= s
->index
= s
->nb_stored
= 0;
283 const FFInputFormat ff_laf_demuxer
= {
285 .p
.long_name
= NULL_IF_CONFIG_SMALL("LAF (Limitless Audio Format)"),
286 .p
.extensions
= "laf",
287 .p
.flags
= AVFMT_GENERIC_INDEX
,
288 .priv_data_size
= sizeof(LAFContext
),
289 .read_probe
= laf_probe
,
290 .read_header
= laf_read_header
,
291 .read_packet
= laf_read_packet
,
292 .read_close
= laf_read_close
,
293 .read_seek
= laf_read_seek
,
294 .flags_internal
= FF_INFMT_FLAG_INIT_CLEANUP
,