2 * Xiph CELT parser for Ogg
3 * Copyright (c) 2011 Nicolas George
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
24 #include "libavutil/intreadwrite.h"
29 struct oggcelt_private
{
30 int extra_headers_left
;
33 static int celt_header(AVFormatContext
*s
, int idx
)
35 struct ogg
*ogg
= s
->priv_data
;
36 struct ogg_stream
*os
= ogg
->streams
+ idx
;
37 AVStream
*st
= s
->streams
[idx
];
38 struct oggcelt_private
*priv
= os
->private;
39 uint8_t *p
= os
->buf
+ os
->pstart
;
41 if (os
->psize
== 60 &&
42 !memcmp(p
, ff_celt_codec
.magic
, ff_celt_codec
.magicsize
)) {
45 uint32_t version
, sample_rate
, nb_channels
;
46 uint32_t overlap
, extra_headers
;
48 priv
= av_malloc(sizeof(struct oggcelt_private
));
50 return AVERROR(ENOMEM
);
51 if (ff_alloc_extradata(st
->codec
, 2 * sizeof(uint32_t)) < 0) {
53 return AVERROR(ENOMEM
);
55 version
= AV_RL32(p
+ 28);
56 /* unused header size field skipped */
57 sample_rate
= AV_RL32(p
+ 36);
58 nb_channels
= AV_RL32(p
+ 40);
59 overlap
= AV_RL32(p
+ 48);
60 /* unused bytes per packet field skipped */
61 extra_headers
= AV_RL32(p
+ 56);
62 st
->codec
->codec_type
= AVMEDIA_TYPE_AUDIO
;
63 st
->codec
->codec_id
= AV_CODEC_ID_CELT
;
64 st
->codec
->sample_rate
= sample_rate
;
65 st
->codec
->channels
= nb_channels
;
67 avpriv_set_pts_info(st
, 64, 1, sample_rate
);
68 priv
->extra_headers_left
= 1 + extra_headers
;
71 AV_WL32(st
->codec
->extradata
+ 0, overlap
);
72 AV_WL32(st
->codec
->extradata
+ 4, version
);
74 } else if (priv
&& priv
->extra_headers_left
) {
75 /* Extra headers (vorbiscomment) */
77 ff_vorbis_stream_comment(s
, st
, p
, os
->psize
);
78 priv
->extra_headers_left
--;
85 const struct ogg_codec ff_celt_codec
= {
88 .header
= celt_header
,