FFmpeg
Loading...
Searching...
No Matches
lafdec.c
Go to the documentation of this file.
1/*
2 * Limitless Audio Format demuxer
3 * Copyright (c) 2022 Paul B Mahol
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 "libavutil/intfloat.h"
24#include "libavutil/mem.h"
25#include "avformat.h"
26#include "avio_internal.h"
27#include "demux.h"
28#include "internal.h"
29
30#define MAX_STREAMS 4096
31
39
40typedef struct LAFContext {
41 uint8_t *data;
42 unsigned nb_stored;
43 unsigned stored_index;
44 unsigned index;
45 unsigned bpp;
46
48
50 uint8_t header[(MAX_STREAMS + 7) / 8];
52
53static int laf_probe(const AVProbeData *p)
54{
55 if (memcmp(p->buf, "LIMITLESS", 9))
56 return 0;
57 if (memcmp(p->buf + 9, "HEAD", 4))
58 return 0;
59 return AVPROBE_SCORE_MAX;
60}
61
63{
64 LAFContext *s = ctx->priv_data;
65 AVIOContext *pb = ctx->pb;
66 unsigned st_count, mode;
67 unsigned sample_rate;
69 int codec_id;
70 int quality;
71 int bpp;
72
73 avio_skip(pb, 9);
74 if (avio_rb32(pb) != MKBETAG('H','E','A','D'))
76
77 quality = avio_r8(pb);
78 if (quality > 3)
80 mode = avio_r8(pb);
81 if (mode > 1)
83 st_count = avio_rl32(pb);
84 if (st_count == 0 || st_count > MAX_STREAMS)
86
87 for (int i = 0; i < st_count; i++) {
88 StreamParams *stp = &s->p[i];
89
92 stp->lfe = avio_r8(pb);
93 if (stp->lfe) {
95 } else if (stp->vertical == 0.f &&
96 stp->horizontal == 0.f) {
98 } else if (stp->vertical == 0.f &&
99 stp->horizontal == -30.f) {
101 } else if (stp->vertical == 0.f &&
102 stp->horizontal == 30.f) {
104 } else if (stp->vertical == 0.f &&
105 stp->horizontal == -110.f) {
107 } else if (stp->vertical == 0.f &&
108 stp->horizontal == 110.f) {
110 } else {
112 }
113 }
114
115 sample_rate = avio_rl32(pb);
116 duration = avio_rl64(pb) / st_count;
117
118 if (avio_feof(pb))
119 return AVERROR_INVALIDDATA;
120
121 switch (quality) {
122 case 0:
124 bpp = 1;
125 break;
126 case 1:
128 bpp = 2;
129 break;
130 case 2:
132 bpp = 4;
133 break;
134 case 3:
136 bpp = 3;
137 break;
138 default:
139 return AVERROR_INVALIDDATA;
140 }
141
142 s->index = 0;
143 s->stored_index = 0;
144 s->bpp = bpp;
145 if ((int64_t)bpp * st_count * (int64_t)sample_rate >= INT32_MAX ||
146 (int64_t)bpp * st_count * (int64_t)sample_rate == 0
147 )
148 return AVERROR_INVALIDDATA;
149 s->data = av_calloc(st_count * sample_rate, bpp);
150 if (!s->data)
151 return AVERROR(ENOMEM);
152
153 for (unsigned i = 0; i < st_count; i++) {
154 StreamParams *stp = &s->p[i];
157 if (!st)
158 return AVERROR(ENOMEM);
159
160 par = st->codecpar;
161 par->codec_id = codec_id;
163 par->ch_layout.nb_channels = 1;
164 par->ch_layout = stp->layout;
165 par->sample_rate = sample_rate;
166 st->duration = duration;
167
169 }
170
171 s->header_len = (ctx->nb_streams + 7) / 8;
172
173 return 0;
174}
175
177{
178 AVIOContext *pb = ctx->pb;
179 LAFContext *s = ctx->priv_data;
180 AVStream *st = ctx->streams[0];
181 const int bpp = s->bpp;
182 StreamParams *stp;
183 int64_t pos;
184 int ret;
185
186 pos = avio_tell(pb);
187
188again:
189 if (avio_feof(pb))
190 return AVERROR_EOF;
191
192 if (s->index >= ctx->nb_streams) {
193 int cur_st = 0, st_count = 0, st_index = 0;
194
195 ret = ffio_read_size(pb, s->header, s->header_len);
196 if (ret < 0)
197 return ret;
198 for (int i = 0; i < s->header_len; i++) {
199 uint8_t val = s->header[i];
200
201 for (int j = 0; j < 8 && cur_st < ctx->nb_streams; j++, cur_st++) {
202 s->p[st_index].stored = val & 1;
203 st_count += val & 1;
204 val >>= 1;
205 st_index++;
206 }
207 }
208
209 s->index = s->stored_index = 0;
210 s->nb_stored = st_count;
211 if (!st_count)
212 return AVERROR_INVALIDDATA;
213 ret = ffio_read_size(pb, s->data, st_count * st->codecpar->sample_rate * bpp);
214 if (ret < 0)
215 return ret;
216 }
217
218 st = ctx->streams[s->index];
219 stp = &s->p[s->index];
220 while (!stp->stored) {
221 s->index++;
222 if (s->index >= ctx->nb_streams)
223 goto again;
224 stp = &s->p[s->index];
225 }
226 st = ctx->streams[s->index];
227
228 ret = av_new_packet(pkt, st->codecpar->sample_rate * bpp);
229 if (ret < 0)
230 return ret;
231
232 switch (bpp) {
233 case 1:
234 for (int n = 0; n < st->codecpar->sample_rate; n++)
235 pkt->data[n] = s->data[n * s->nb_stored + s->stored_index];
236 break;
237 case 2:
238 for (int n = 0; n < st->codecpar->sample_rate; n++)
239 AV_WN16(pkt->data + n * 2, AV_RN16(s->data + n * s->nb_stored * 2 + s->stored_index * 2));
240 break;
241 case 3:
242 for (int n = 0; n < st->codecpar->sample_rate; n++)
243 AV_WL24(pkt->data + n * 3, AV_RL24(s->data + n * s->nb_stored * 3 + s->stored_index * 3));
244 break;
245 case 4:
246 for (int n = 0; n < st->codecpar->sample_rate; n++)
247 AV_WN32(pkt->data + n * 4, AV_RN32(s->data + n * s->nb_stored * 4 + s->stored_index * 4));
248 break;
249 }
250
251 pkt->stream_index = s->index;
252 pkt->pos = pos;
253 s->index++;
254 s->stored_index++;
255
256 return 0;
257}
258
260{
261 LAFContext *s = ctx->priv_data;
262
263 av_freep(&s->data);
264
265 return 0;
266}
267
268static int laf_read_seek(AVFormatContext *ctx, int stream_index,
269 int64_t timestamp, int flags)
270{
271 LAFContext *s = ctx->priv_data;
272
273 s->stored_index = s->index = s->nb_stored = 0;
274
275 return -1;
276}
277
279 .p.name = "laf",
280 .p.long_name = NULL_IF_CONFIG_SMALL("LAF (Limitless Audio Format)"),
281 .p.extensions = "laf",
282 .p.flags = AVFMT_GENERIC_INDEX,
283 .priv_data_size = sizeof(LAFContext),
289 .flags_internal = FF_INFMT_FLAG_INIT_CLEANUP,
290};
static double val(void *priv, double ch)
Definition aeval.c:77
const FFInputFormat ff_laf_demuxer
Definition lafdec.c:278
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition avformat.c:834
Main libavformat public API header.
#define AVPROBE_SCORE_MAX
maximum score
Definition avformat.h:483
#define AVFMT_GENERIC_INDEX
Use generic index building code.
Definition avformat.h:499
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition aviobuf.c:349
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition avio.h:494
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition aviobuf.c:321
unsigned int avio_rl32(AVIOContext *s)
Definition aviobuf.c:733
unsigned int avio_rb32(AVIOContext *s)
Definition aviobuf.c:764
int avio_r8(AVIOContext *s)
Definition aviobuf.c:606
uint64_t avio_rl64(AVIOContext *s)
Definition aviobuf.c:741
int ffio_read_size(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition aviobuf.c:665
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
#define flags(name, subs,...)
Definition cbs_h264.c:74
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
static int read_probe(const AVProbeData *p)
Definition cdg.c:30
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
#define FF_INFMT_FLAG_INIT_CLEANUP
For an FFInputFormat with this flag set read_close() needs to be called by the caller upon read_heade...
Definition demux.h:35
static AVPacket * pkt
static int64_t duration
Definition ffplay.c:330
static int read_header(FFV1Context *f, RangeCoder *c)
Definition ffv1dec.c:578
#define AV_CH_SIDE_LEFT
#define AV_CH_FRONT_RIGHT
#define AV_CH_FRONT_CENTER
#define AV_CH_SIDE_RIGHT
#define AV_CH_LOW_FREQUENCY
#define AV_CH_FRONT_LEFT
@ AV_CODEC_ID_PCM_F32LE
Definition codec_id.h:351
@ AV_CODEC_ID_PCM_U8
Definition codec_id.h:335
@ AV_CODEC_ID_PCM_S16LE
Definition codec_id.h:330
@ AV_CODEC_ID_PCM_S24LE
Definition codec_id.h:342
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition packet.c:98
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
#define AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MASK(nb, m)
Macro to define native channel layouts.
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR_EOF
End of file.
Definition error.h:57
#define AVERROR(e)
Definition error.h:45
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
static av_always_inline float av_int2float(uint32_t i)
Reinterpret a 32-bit integer as a float.
Definition intfloat.h:40
#define AV_RL24(x)
#define AV_WN32(p, v)
#define AV_RN32(p)
#define AV_WL24(p, d)
#define AV_WN16(p, v)
#define AV_RN16(p)
static int laf_read_header(AVFormatContext *ctx)
Definition lafdec.c:62
#define MAX_STREAMS
Definition lafdec.c:30
static int laf_read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition lafdec.c:268
static int laf_read_packet(AVFormatContext *ctx, AVPacket *pkt)
Definition lafdec.c:176
static int laf_read_close(AVFormatContext *ctx)
Definition lafdec.c:259
static int laf_probe(const AVProbeData *p)
Definition lafdec.c:53
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
static av_cold int read_close(AVFormatContext *ctx)
Definition libcdio.c:143
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition libcdio.c:151
#define MKBETAG(a, b, c, d)
Definition macros.h:56
void * av_calloc(size_t nmemb, size_t size)
Definition mem.c:264
Memory handling functions.
unsigned int pos
Definition spdifenc.c:431
An AVChannelLayout holds information about the channel layout of audio data.
int nb_channels
Number of channels in this layout.
This struct describes the properties of an encoded stream.
Definition codec_par.h:49
AVChannelLayout ch_layout
The channel layout and number of channels.
Definition codec_par.h:207
enum AVMediaType codec_type
General type of the encoded data.
Definition codec_par.h:53
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition codec_par.h:57
int sample_rate
The number of audio samples per second.
Definition codec_par.h:213
Format I/O context.
Definition avformat.h:1333
Bytestream IO Context.
Definition avio.h:160
This structure stores compressed data.
Definition packet.h:580
This structure contains the data a format has to probe a file.
Definition avformat.h:471
Stream structure.
Definition avformat.h:766
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition avformat.h:789
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition avformat.h:825
uint8_t * data
Definition lafdec.c:41
unsigned nb_stored
Definition lafdec.c:42
unsigned index
Definition lafdec.c:44
unsigned bpp
Definition lafdec.c:45
uint8_t header[(MAX_STREAMS+7)/8]
Definition lafdec.c:50
unsigned stored_index
Definition lafdec.c:43
StreamParams p[MAX_STREAMS]
Definition lafdec.c:47
int header_len
Definition lafdec.c:49
int stored
Definition lafdec.c:37
float vertical
Definition lafdec.c:35
AVChannelLayout layout
Definition lafdec.c:33
float horizontal
Definition lafdec.c:34
Definition swscale.c:71
#define av_freep(p)
static AVFormatContext * ctx
Definition movenc.c:49
enum AVCodecID codec_id
static const uint8_t quality[]
Definition vmixdec.c:58