Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavformat
oggparseflac.c
Go to the documentation of this file.
1
/*
2
* Copyright (C) 2005 Matthieu CASTET
3
*
4
* This file is part of Libav.
5
*
6
* Libav is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Lesser General Public
8
* License as published by the Free Software Foundation; either
9
* version 2.1 of the License, or (at your option) any later version.
10
*
11
* Libav is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* Lesser General Public License for more details.
15
*
16
* You should have received a copy of the GNU Lesser General Public
17
* License along with Libav; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19
*/
20
21
#include <stdlib.h>
22
#include "
libavcodec/get_bits.h
"
23
#include "
libavcodec/flac.h
"
24
#include "
avformat.h
"
25
#include "
internal.h
"
26
#include "
oggdec.h
"
27
28
#define OGG_FLAC_METADATA_TYPE_STREAMINFO 0x7F
29
30
static
int
31
flac_header
(
AVFormatContext
* s,
int
idx)
32
{
33
struct
ogg
*
ogg
= s->
priv_data
;
34
struct
ogg_stream
*os = ogg->
streams
+ idx;
35
AVStream
*st = s->
streams
[idx];
36
GetBitContext
gb;
37
FLACStreaminfo
si;
38
int
mdt;
39
40
if
(os->
buf
[os->
pstart
] == 0xff)
41
return
0;
42
43
init_get_bits
(&gb, os->
buf
+ os->
pstart
, os->
psize
*8);
44
skip_bits1
(&gb);
/* metadata_last */
45
mdt =
get_bits
(&gb, 7);
46
47
if
(mdt ==
OGG_FLAC_METADATA_TYPE_STREAMINFO
) {
48
uint8_t *streaminfo_start = os->
buf
+ os->
pstart
+ 5 + 4 + 4 + 4;
49
skip_bits_long
(&gb, 4*8);
/* "FLAC" */
50
if
(
get_bits
(&gb, 8) != 1)
/* unsupported major version */
51
return
-1;
52
skip_bits_long
(&gb, 8 + 16);
/* minor version + header count */
53
skip_bits_long
(&gb, 4*8);
/* "fLaC" */
54
55
/* METADATA_BLOCK_HEADER */
56
if
(
get_bits_long
(&gb, 32) !=
FLAC_STREAMINFO_SIZE
)
57
return
-1;
58
59
avpriv_flac_parse_streaminfo
(st->
codec
, &si, streaminfo_start);
60
61
st->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
62
st->
codec
->
codec_id
=
CODEC_ID_FLAC
;
63
64
st->
codec
->
extradata
=
65
av_malloc
(
FLAC_STREAMINFO_SIZE
+
FF_INPUT_BUFFER_PADDING_SIZE
);
66
memcpy(st->
codec
->
extradata
, streaminfo_start,
FLAC_STREAMINFO_SIZE
);
67
st->
codec
->
extradata_size
=
FLAC_STREAMINFO_SIZE
;
68
69
avpriv_set_pts_info
(st, 64, 1, st->
codec
->
sample_rate
);
70
}
else
if
(mdt ==
FLAC_METADATA_TYPE_VORBIS_COMMENT
) {
71
ff_vorbis_comment
(s, &st->
metadata
, os->
buf
+ os->
pstart
+ 4, os->
psize
- 4);
72
}
73
74
return
1;
75
}
76
77
static
int
78
old_flac_header
(
AVFormatContext
* s,
int
idx)
79
{
80
AVStream
*st = s->
streams
[idx];
81
st->
codec
->
codec_type
=
AVMEDIA_TYPE_AUDIO
;
82
st->
codec
->
codec_id
=
CODEC_ID_FLAC
;
83
84
return
0;
85
}
86
87
const
struct
ogg_codec
ff_flac_codec
= {
88
.
magic
=
"\177FLAC"
,
89
.magicsize = 5,
90
.header =
flac_header
91
};
92
93
const
struct
ogg_codec
ff_old_flac_codec
= {
94
.
magic
=
"fLaC"
,
95
.magicsize = 4,
96
.header =
old_flac_header
97
};