1/* 2 * Copyright (C) 2005 Matthieu CASTET 3 * 4 * This file is part of FFmpeg. 5 * 6 * FFmpeg 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 * FFmpeg 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 FFmpeg; 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/bitstream.h" 23#include "libavcodec/flac.h" 24#include "avformat.h" 25#include "oggdec.h" 26 27#define OGG_FLAC_METADATA_TYPE_STREAMINFO 0x7F 28 29static int 30flac_header (AVFormatContext * s, int idx) 31{ 32 struct ogg *ogg = s->priv_data; 33 struct ogg_stream *os = ogg->streams + idx; 34 AVStream *st = s->streams[idx]; 35 GetBitContext gb; 36 FLACStreaminfo si; 37 int mdt; 38 39 if (os->buf[os->pstart] == 0xff) 40 return 0; 41 42 init_get_bits(&gb, os->buf + os->pstart, os->psize*8); 43 skip_bits1(&gb); /* metadata_last */ 44 mdt = get_bits(&gb, 7); 45 46 if (mdt == OGG_FLAC_METADATA_TYPE_STREAMINFO) { 47 uint8_t *streaminfo_start = os->buf + os->pstart + 5 + 4 + 4 + 4; 48 skip_bits_long(&gb, 4*8); /* "FLAC" */ 49 if(get_bits(&gb, 8) != 1) /* unsupported major version */ 50 return -1; 51 skip_bits_long(&gb, 8 + 16); /* minor version + header count */ 52 skip_bits_long(&gb, 4*8); /* "fLaC" */ 53 54 /* METADATA_BLOCK_HEADER */ 55 if (get_bits_long(&gb, 32) != FLAC_STREAMINFO_SIZE) 56 return -1; 57 58 ff_flac_parse_streaminfo(st->codec, &si, streaminfo_start); 59 60 st->codec->codec_type = CODEC_TYPE_AUDIO; 61 st->codec->codec_id = CODEC_ID_FLAC; 62 63 st->codec->extradata = 64 av_malloc(FLAC_STREAMINFO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); 65 memcpy(st->codec->extradata, streaminfo_start, FLAC_STREAMINFO_SIZE); 66 st->codec->extradata_size = FLAC_STREAMINFO_SIZE; 67 68 st->time_base.num = 1; 69 st->time_base.den = st->codec->sample_rate; 70 } else if (mdt == FLAC_METADATA_TYPE_VORBIS_COMMENT) { 71 vorbis_comment (s, os->buf + os->pstart + 4, os->psize - 4); 72 } 73 74 return 1; 75} 76 77static int 78old_flac_header (AVFormatContext * s, int idx) 79{ 80 AVStream *st = s->streams[idx]; 81 st->codec->codec_type = CODEC_TYPE_AUDIO; 82 st->codec->codec_id = CODEC_ID_FLAC; 83 84 return 0; 85} 86 87const struct ogg_codec ff_flac_codec = { 88 .magic = "\177FLAC", 89 .magicsize = 5, 90 .header = flac_header 91}; 92 93const struct ogg_codec ff_old_flac_codec = { 94 .magic = "fLaC", 95 .magicsize = 4, 96 .header = old_flac_header 97}; 98