Libav 0.7.1
|
00001 /* 00002 * raw FLAC muxer 00003 * Copyright (c) 2006-2009 Justin Ruggles 00004 * 00005 * This file is part of Libav. 00006 * 00007 * Libav is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * Libav is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with Libav; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00022 #include "libavcodec/flac.h" 00023 #include "avformat.h" 00024 #include "flacenc.h" 00025 #include "vorbiscomment.h" 00026 #include "libavcodec/bytestream.h" 00027 00028 00029 static int flac_write_block_padding(AVIOContext *pb, unsigned int n_padding_bytes, 00030 int last_block) 00031 { 00032 avio_w8(pb, last_block ? 0x81 : 0x01); 00033 avio_wb24(pb, n_padding_bytes); 00034 while (n_padding_bytes > 0) { 00035 avio_w8(pb, 0); 00036 n_padding_bytes--; 00037 } 00038 return 0; 00039 } 00040 00041 static int flac_write_block_comment(AVIOContext *pb, AVDictionary **m, 00042 int last_block, int bitexact) 00043 { 00044 const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT; 00045 unsigned int len, count; 00046 uint8_t *p, *p0; 00047 00048 ff_metadata_conv(m, ff_vorbiscomment_metadata_conv, NULL); 00049 00050 len = ff_vorbiscomment_length(*m, vendor, &count); 00051 p0 = av_malloc(len+4); 00052 if (!p0) 00053 return AVERROR(ENOMEM); 00054 p = p0; 00055 00056 bytestream_put_byte(&p, last_block ? 0x84 : 0x04); 00057 bytestream_put_be24(&p, len); 00058 ff_vorbiscomment_write(&p, m, vendor, count); 00059 00060 avio_write(pb, p0, len+4); 00061 av_freep(&p0); 00062 p = NULL; 00063 00064 return 0; 00065 } 00066 00067 static int flac_write_header(struct AVFormatContext *s) 00068 { 00069 int ret; 00070 AVCodecContext *codec = s->streams[0]->codec; 00071 00072 ret = ff_flac_write_header(s->pb, codec, 0); 00073 if (ret) 00074 return ret; 00075 00076 ret = flac_write_block_comment(s->pb, &s->metadata, 0, 00077 codec->flags & CODEC_FLAG_BITEXACT); 00078 if (ret) 00079 return ret; 00080 00081 /* The command line flac encoder defaults to placing a seekpoint 00082 * every 10s. So one might add padding to allow that later 00083 * but there seems to be no simple way to get the duration here. 00084 * So let's try the flac default of 8192 bytes */ 00085 flac_write_block_padding(s->pb, 8192, 1); 00086 00087 return ret; 00088 } 00089 00090 static int flac_write_trailer(struct AVFormatContext *s) 00091 { 00092 AVIOContext *pb = s->pb; 00093 uint8_t *streaminfo; 00094 enum FLACExtradataFormat format; 00095 int64_t file_size; 00096 00097 if (!ff_flac_is_extradata_valid(s->streams[0]->codec, &format, &streaminfo)) 00098 return -1; 00099 00100 if (pb->seekable) { 00101 /* rewrite the STREAMINFO header block data */ 00102 file_size = avio_tell(pb); 00103 avio_seek(pb, 8, SEEK_SET); 00104 avio_write(pb, streaminfo, FLAC_STREAMINFO_SIZE); 00105 avio_seek(pb, file_size, SEEK_SET); 00106 avio_flush(pb); 00107 } else { 00108 av_log(s, AV_LOG_WARNING, "unable to rewrite FLAC header.\n"); 00109 } 00110 return 0; 00111 } 00112 00113 static int flac_write_packet(struct AVFormatContext *s, AVPacket *pkt) 00114 { 00115 avio_write(s->pb, pkt->data, pkt->size); 00116 avio_flush(s->pb); 00117 return 0; 00118 } 00119 00120 AVOutputFormat ff_flac_muxer = { 00121 "flac", 00122 NULL_IF_CONFIG_SMALL("raw FLAC"), 00123 "audio/x-flac", 00124 "flac", 00125 0, 00126 CODEC_ID_FLAC, 00127 CODEC_ID_NONE, 00128 flac_write_header, 00129 flac_write_packet, 00130 flac_write_trailer, 00131 .flags= AVFMT_NOTIMESTAMPS, 00132 };