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"
25 #include "libavutil/mem.h"
30 struct oggcelt_private
{
31 int extra_headers_left
;
34 static int celt_header(AVFormatContext
*s
, int idx
)
36 struct ogg
*ogg
= s
->priv_data
;
37 struct ogg_stream
*os
= ogg
->streams
+ idx
;
38 AVStream
*st
= s
->streams
[idx
];
39 struct oggcelt_private
*priv
= os
->private;
40 uint8_t *p
= os
->buf
+ os
->pstart
;
43 if (os
->psize
== 60 &&
44 !memcmp(p
, ff_celt_codec
.magic
, ff_celt_codec
.magicsize
)) {
47 uint32_t version
, sample_rate
, nb_channels
;
48 uint32_t overlap
, extra_headers
;
50 priv
= av_malloc(sizeof(struct oggcelt_private
));
52 return AVERROR(ENOMEM
);
53 ret
= ff_alloc_extradata(st
->codecpar
, 2 * sizeof(uint32_t));
58 version
= AV_RL32(p
+ 28);
59 /* unused header size field skipped */
60 sample_rate
= AV_RL32(p
+ 36);
61 nb_channels
= AV_RL32(p
+ 40);
62 overlap
= AV_RL32(p
+ 48);
63 /* unused bytes per packet field skipped */
64 extra_headers
= AV_RL32(p
+ 56);
65 st
->codecpar
->codec_type
= AVMEDIA_TYPE_AUDIO
;
66 st
->codecpar
->codec_id
= AV_CODEC_ID_CELT
;
67 st
->codecpar
->sample_rate
= sample_rate
;
68 st
->codecpar
->ch_layout
.nb_channels
= nb_channels
;
70 avpriv_set_pts_info(st
, 64, 1, sample_rate
);
77 priv
->extra_headers_left
= 1 + extra_headers
;
79 AV_WL32(st
->codecpar
->extradata
+ 0, overlap
);
80 AV_WL32(st
->codecpar
->extradata
+ 4, version
);
82 } else if (priv
&& priv
->extra_headers_left
) {
83 /* Extra headers (vorbiscomment) */
85 ff_vorbis_stream_comment(s
, st
, p
, os
->psize
);
86 priv
->extra_headers_left
--;
93 const struct ogg_codec ff_celt_codec
= {
96 .header
= celt_header
,