Libav
|
00001 /* 00002 * Copyright (C) 2005 Matthieu CASTET 00003 * 00004 * This file is part of FFmpeg. 00005 * 00006 * FFmpeg is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU Lesser General Public 00008 * License as published by the Free Software Foundation; either 00009 * version 2.1 of the License, or (at your option) any later version. 00010 * 00011 * FFmpeg is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 * Lesser General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU Lesser General Public 00017 * License along with FFmpeg; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00020 00021 #include <stdlib.h> 00022 #include "libavcodec/get_bits.h" 00023 #include "libavcodec/flac.h" 00024 #include "avformat.h" 00025 #include "oggdec.h" 00026 00027 #define OGG_FLAC_METADATA_TYPE_STREAMINFO 0x7F 00028 00029 static int 00030 flac_header (AVFormatContext * s, int idx) 00031 { 00032 struct ogg *ogg = s->priv_data; 00033 struct ogg_stream *os = ogg->streams + idx; 00034 AVStream *st = s->streams[idx]; 00035 GetBitContext gb; 00036 FLACStreaminfo si; 00037 int mdt; 00038 00039 if (os->buf[os->pstart] == 0xff) 00040 return 0; 00041 00042 init_get_bits(&gb, os->buf + os->pstart, os->psize*8); 00043 skip_bits1(&gb); /* metadata_last */ 00044 mdt = get_bits(&gb, 7); 00045 00046 if (mdt == OGG_FLAC_METADATA_TYPE_STREAMINFO) { 00047 uint8_t *streaminfo_start = os->buf + os->pstart + 5 + 4 + 4 + 4; 00048 skip_bits_long(&gb, 4*8); /* "FLAC" */ 00049 if(get_bits(&gb, 8) != 1) /* unsupported major version */ 00050 return -1; 00051 skip_bits_long(&gb, 8 + 16); /* minor version + header count */ 00052 skip_bits_long(&gb, 4*8); /* "fLaC" */ 00053 00054 /* METADATA_BLOCK_HEADER */ 00055 if (get_bits_long(&gb, 32) != FLAC_STREAMINFO_SIZE) 00056 return -1; 00057 00058 ff_flac_parse_streaminfo(st->codec, &si, streaminfo_start); 00059 00060 st->codec->codec_type = AVMEDIA_TYPE_AUDIO; 00061 st->codec->codec_id = CODEC_ID_FLAC; 00062 00063 st->codec->extradata = 00064 av_malloc(FLAC_STREAMINFO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); 00065 memcpy(st->codec->extradata, streaminfo_start, FLAC_STREAMINFO_SIZE); 00066 st->codec->extradata_size = FLAC_STREAMINFO_SIZE; 00067 00068 st->time_base.num = 1; 00069 st->time_base.den = st->codec->sample_rate; 00070 } else if (mdt == FLAC_METADATA_TYPE_VORBIS_COMMENT) { 00071 ff_vorbis_comment (s, &st->metadata, os->buf + os->pstart + 4, os->psize - 4); 00072 } 00073 00074 return 1; 00075 } 00076 00077 static int 00078 old_flac_header (AVFormatContext * s, int idx) 00079 { 00080 AVStream *st = s->streams[idx]; 00081 st->codec->codec_type = AVMEDIA_TYPE_AUDIO; 00082 st->codec->codec_id = CODEC_ID_FLAC; 00083 00084 return 0; 00085 } 00086 00087 const struct ogg_codec ff_flac_codec = { 00088 .magic = "\177FLAC", 00089 .magicsize = 5, 00090 .header = flac_header 00091 }; 00092 00093 const struct ogg_codec ff_old_flac_codec = { 00094 .magic = "fLaC", 00095 .magicsize = 4, 00096 .header = old_flac_header 00097 };