FFmpeg
Loading...
Searching...
No Matches
codec2.c
Go to the documentation of this file.
1/*
2 * codec2 muxer and demuxers
3 * Copyright (c) 2017 Tomas Härdin
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
27#include "libavutil/opt.h"
28#include "avio_internal.h"
29#include "avformat.h"
30#include "demux.h"
31#include "internal.h"
32#include "mux.h"
33#include "rawenc.h"
34#include "pcm.h"
35
36#define CODEC2_HEADER_SIZE 7
37#define CODEC2_MAGIC 0xC0DEC2
38
39//the lowest version we should ever run across is 0.8
40//we may run across later versions as the format evolves
41#define EXPECTED_CODEC2_MAJOR_VERSION 0
42#define EXPECTED_CODEC2_MINOR_VERSION 8
43
44typedef struct {
45 const AVClass *class;
46 int mode;
49
50static int codec2_probe(const AVProbeData *p)
51{
52 //must start wih C0 DE C2
53 if (AV_RB24(p->buf) != CODEC2_MAGIC) {
54 return 0;
55 }
56
57 //no .c2 files prior to 0.8
58 //be strict about major version while we're at it
59 if (p->buf[3] != EXPECTED_CODEC2_MAJOR_VERSION ||
61 return 0;
62 }
63
64 //32 bits of identification -> low score
65 return AVPROBE_SCORE_EXTENSION + 1;
66}
67
68//Mimics codec2_samples_per_frame()
70{
71 int frame_size_table[CODEC2_MODE_MAX+1] = {
72 160, // 3200
73 160, // 2400
74 320, // 1600
75 320, // 1400
76 320, // 1300
77 320, // 1200
78 320, // 700
79 320, // 700B
80 320, // 700C
81 };
82
84 av_log(s, AV_LOG_ERROR, "unknown codec2 mode %i, can't find frame_size\n", mode);
85 return 0;
86 } else {
87 return frame_size_table[mode];
88 }
89}
90
91//Mimics (codec2_bits_per_frame()+7)/8
93{
94 int block_align_table[CODEC2_MODE_MAX+1] = {
95 8, // 3200
96 6, // 2400
97 8, // 1600
98 7, // 1400
99 7, // 1300
100 6, // 1200
101 4, // 700
102 4, // 700B
103 4, // 700C
104 };
105
107 av_log(s, AV_LOG_ERROR, "unknown codec2 mode %i, can't find block_align\n", mode);
108 return 0;
109 } else {
110 return block_align_table[mode];
111 }
112}
113
114//Computes bitrate from mode, with frames rounded up to the nearest octet.
115//So 700 bit/s (28 bits/frame) becomes 800 bits/s (32 bits/frame).
117{
119 int block_align = codec2_mode_block_align(s, mode);
120
121 if (frame_size <= 0 || block_align <= 0) {
122 return 0;
123 }
124
125 return 8 * 8000 * block_align / frame_size;
126}
127
151
153{
155 int ret, version;
156
157 if (!st) {
158 return AVERROR(ENOMEM);
159 }
160
161 if (avio_rb24(s->pb) != CODEC2_MAGIC) {
162 av_log(s, AV_LOG_ERROR, "not a .c2 file\n");
163 return AVERROR_INVALIDDATA;
164 }
165
167 if (ret) {
168 return ret;
169 }
170
172 if (ret < 0) {
173 return ret;
174 }
175
178 avpriv_report_missing_feature(s, "Major version %i", version >> 8);
180 }
181
183
184 return codec2_read_header_common(s, st);
185}
186
188{
189 Codec2Context *c2 = s->priv_data;
190 AVStream *st = s->streams[0];
191 int ret, size, n, block_align, frame_size;
192
193 block_align = st->codecpar->block_align;
195
196 if (block_align <= 0 || frame_size <= 0 || c2->frames_per_packet <= 0) {
197 return AVERROR(EINVAL);
198 }
199
200 //try to read desired number of frames, compute n from to actual number of bytes read
201 if (c2->frames_per_packet > INT_MAX / block_align)
202 return AVERROR(EINVAL);
203 size = c2->frames_per_packet * block_align;
204 ret = av_get_packet(s->pb, pkt, size);
205 if (ret < 0) {
206 return ret;
207 }
208
209 //only set duration - compute_pkt_fields() and ff_pcm_read_seek() takes care of everything else
210 //tested by spamming the seek functionality in ffplay
211 n = ret / block_align;
212 pkt->duration = (int64_t)n * frame_size;
213
214 return ret;
215}
216
218{
219 AVStream *st = s->streams[0];
220
222 av_log(s, AV_LOG_ERROR, ".c2 files require exactly %i bytes of extradata (got %i)\n",
224 return AVERROR(EINVAL);
225 }
226
229
230 return 0;
231}
232
234{
235 Codec2Context *c2 = s->priv_data;
236 AVStream *st;
237 int ret;
238
239 if (c2->mode < 0) {
240 //FIXME: using a default value of -1 for mandatory options is an incredibly ugly hack
241 av_log(s, AV_LOG_ERROR, "-mode must be set in order to make sense of raw codec2 files\n");
242 return AVERROR(EINVAL);
243 }
244
246 if (!st) {
247 return AVERROR(ENOMEM);
248 }
249
251 if (ret) {
252 return ret;
253 }
254
256
257 return codec2_read_header_common(s, st);
258}
259
260//transcoding report2074.c2 to wav went from 7.391s to 5.322s with -frames_per_packet 1000 compared to default, same sha1sum
261#define FRAMES_PER_PACKET \
262 { "frames_per_packet", "Number of frames to read at a time. Higher = faster decoding, lower granularity", \
263 offsetof(Codec2Context, frames_per_packet), AV_OPT_TYPE_INT, {.i64 = 1}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM}
264
265static const AVOption codec2_options[] = {
267 { NULL },
268};
269
270static const AVOption codec2raw_options[] = {
271 CODEC2_AVOPTIONS("codec2 mode [mandatory]", Codec2Context, -1, -1, AV_OPT_FLAG_DECODING_PARAM),
273 { NULL },
274};
275
277 .class_name = "codec2 demuxer",
278 .item_name = av_default_item_name,
279 .option = codec2_options,
280 .version = LIBAVUTIL_VERSION_INT,
281 .category = AV_CLASS_CATEGORY_DEMUXER,
282};
283
285 .class_name = "codec2raw demuxer",
286 .item_name = av_default_item_name,
287 .option = codec2raw_options,
288 .version = LIBAVUTIL_VERSION_INT,
289 .category = AV_CLASS_CATEGORY_DEMUXER,
290};
291
292#if CONFIG_CODEC2_DEMUXER
294 .p.name = "codec2",
295 .p.long_name = NULL_IF_CONFIG_SMALL("codec2 .c2 demuxer"),
296 .p.extensions = "c2",
297 .p.flags = AVFMT_GENERIC_INDEX,
298 .p.priv_class = &codec2_demux_class,
299 .priv_data_size = sizeof(Codec2Context),
304 .raw_codec_id = AV_CODEC_ID_CODEC2,
305};
306#endif
307
308#if CONFIG_CODEC2_MUXER
310 .p.name = "codec2",
311 .p.long_name = NULL_IF_CONFIG_SMALL("codec2 .c2 muxer"),
312 .p.extensions = "c2",
313 .p.audio_codec = AV_CODEC_ID_CODEC2,
314 .p.video_codec = AV_CODEC_ID_NONE,
315 .p.subtitle_codec = AV_CODEC_ID_NONE,
316 .p.flags = AVFMT_NOTIMESTAMPS,
317 .flags_internal = FF_OFMT_FLAG_MAX_ONE_OF_EACH |
319 .write_header = codec2_write_header,
320 .write_packet = ff_raw_write_packet,
321};
322#endif
323
324#if CONFIG_CODEC2RAW_DEMUXER
326 .p.name = "codec2raw",
327 .p.long_name = NULL_IF_CONFIG_SMALL("raw codec2 demuxer"),
328 .p.flags = AVFMT_GENERIC_INDEX,
329 .p.priv_class = &codec2raw_demux_class,
330 .priv_data_size = sizeof(Codec2Context),
334 .raw_codec_id = AV_CODEC_ID_CODEC2,
335};
336#endif
const FFInputFormat ff_codec2_demuxer
const FFOutputFormat ff_codec2_muxer
const FFInputFormat ff_codec2raw_demuxer
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_EXTENSION
score for file extension
Definition avformat.h:481
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition utils.c:98
#define AVFMT_GENERIC_INDEX
Use generic index building code.
Definition avformat.h:499
#define AVFMT_NOTIMESTAMPS
Format does not need / have any timestamps.
Definition avformat.h:498
void avio_wb24(AVIOContext *s, unsigned int val)
Definition aviobuf.c:458
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition aviobuf.c:206
unsigned int avio_rb24(AVIOContext *s)
Definition aviobuf.c:757
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 s(width, name)
Definition cbs_vp9.c:198
static int read_probe(const AVProbeData *p)
Definition cdg.c:30
Public libavutil channel layout APIs header.
static int codec2_mode_bit_rate(AVFormatContext *s, int mode)
Definition codec2.c:116
static int codec2raw_read_header(AVFormatContext *s)
Definition codec2.c:233
static int codec2_probe(const AVProbeData *p)
Definition codec2.c:50
static const AVOption codec2raw_options[]
Definition codec2.c:270
static int codec2_mode_block_align(AVFormatContext *s, int mode)
Definition codec2.c:92
static int codec2_read_header(AVFormatContext *s)
Definition codec2.c:152
#define FRAMES_PER_PACKET
Definition codec2.c:261
static int codec2_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition codec2.c:187
static int codec2_read_header_common(AVFormatContext *s, AVStream *st)
Definition codec2.c:128
static const AVClass codec2_demux_class
Definition codec2.c:276
static int codec2_write_header(AVFormatContext *s)
Definition codec2.c:217
#define EXPECTED_CODEC2_MAJOR_VERSION
Definition codec2.c:41
#define EXPECTED_CODEC2_MINOR_VERSION
Definition codec2.c:42
#define CODEC2_MAGIC
Definition codec2.c:37
static const AVClass codec2raw_demux_class
Definition codec2.c:284
#define CODEC2_HEADER_SIZE
Definition codec2.c:36
static int codec2_mode_frame_size(AVFormatContext *s, int mode)
Definition codec2.c:69
static const AVOption codec2_options[]
Definition codec2.c:265
#define CODEC2_AVOPTIONS(desc, classname, min_val, default_val, option_flags)
Definition codec2utils.h:36
static uint8_t codec2_mode_from_extradata(uint8_t *ptr)
Definition codec2utils.h:59
#define CODEC2_EXTRADATA_SIZE
Definition codec2utils.h:48
#define CODEC2_MODE_MAX
Definition codec2utils.h:30
static void codec2_make_extradata(uint8_t *ptr, int mode)
Definition codec2utils.h:51
#define NULL
Definition coverity.c:32
long long int64_t
Definition coverity.c:34
static AVPacket * pkt
mode
Use these values in ebur128_init (or'ed).
Definition ebur128.h:83
static int read_header(FFV1Context *f, RangeCoder *c)
Definition ffv1dec.c:578
static const uint8_t frame_size[4]
Definition g723_1.h:222
#define AV_OPT_FLAG_DECODING_PARAM
A generic parameter which can be set by the user for demuxing or decoding.
Definition opt.h:355
@ AV_CODEC_ID_NONE
Definition codec_id.h:48
@ AV_CODEC_ID_CODEC2
Definition codec_id.h:520
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
#define AV_CHANNEL_LAYOUT_MONO
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition error.h:64
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
@ AVMEDIA_TYPE_AUDIO
Definition avutil.h:201
@ AV_SAMPLE_FMT_S16
signed 16 bits
Definition samplefmt.h:58
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
#define AV_RB24(x)
#define AV_RB16(p)
int ff_alloc_extradata(AVCodecParameters *par, int size)
Allocate extradata with additional AV_INPUT_BUFFER_PADDING_SIZE at end which is always set to 0.
Definition utils.c:237
static av_always_inline FFFormatContext * ffformatcontext(AVFormatContext *s)
Definition internal.h:130
int ff_pcm_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Definition pcm.c:73
int ff_raw_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition rawenc.c:31
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition internal.h:88
void avpriv_report_missing_feature(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition libcdio.c:151
version
Definition libkvazaar.c:313
@ AV_CLASS_CATEGORY_DEMUXER
Definition log.h:33
static const uint64_t c2
Definition murmur3.c:53
#define FF_OFMT_FLAG_MAX_ONE_OF_EACH
If this flag is set, it indicates that for each codec type whose corresponding default codec (i....
Definition mux.h:50
#define FF_OFMT_FLAG_ONLY_DEFAULT_CODECS
If this flag is set, then the only permitted audio/video/subtitle codec ids are AVOutputFormat....
Definition mux.h:59
AVOptions.
An AVChannelLayout holds information about the channel layout of audio data.
Describe the class of an AVClass context structure.
Definition log.h:76
int extradata_size
Size of the extradata content in bytes.
Definition codec_par.h:75
int frame_size
Audio frame size, if known.
Definition codec_par.h:227
AVChannelLayout ch_layout
The channel layout and number of channels.
Definition codec_par.h:207
int64_t bit_rate
The average bitrate of the encoded data (in bits per second).
Definition codec_par.h:99
enum AVMediaType codec_type
General type of the encoded data.
Definition codec_par.h:53
int block_align
The number of bytes per coded audio frame, required by some formats.
Definition codec_par.h:221
uint8_t * extradata
Extra binary data needed for initializing the decoder, codec-dependent.
Definition codec_par.h:71
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
AVOption.
Definition opt.h:428
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
int frames_per_packet
Definition codec2.c:47
int64_t data_offset
offset of the first packet
Definition internal.h:89
Definition swscale.c:71
#define av_log(a,...)
int size