00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "libavcodec/flac.h"
00023 #include "avformat.h"
00024 #include "flacenc.h"
00025 #include "metadata.h"
00026 #include "vorbiscomment.h"
00027 #include "libavcodec/bytestream.h"
00028
00029
00030 static int flac_write_block_padding(AVIOContext *pb, unsigned int n_padding_bytes,
00031 int last_block)
00032 {
00033 avio_w8(pb, last_block ? 0x81 : 0x01);
00034 avio_wb24(pb, n_padding_bytes);
00035 while (n_padding_bytes > 0) {
00036 avio_w8(pb, 0);
00037 n_padding_bytes--;
00038 }
00039 return 0;
00040 }
00041
00042 static int flac_write_block_comment(AVIOContext *pb, AVMetadata **m,
00043 int last_block, int bitexact)
00044 {
00045 const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT;
00046 unsigned int len, count;
00047 uint8_t *p, *p0;
00048
00049 ff_metadata_conv(m, ff_vorbiscomment_metadata_conv, NULL);
00050
00051 len = ff_vorbiscomment_length(*m, vendor, &count);
00052 p0 = av_malloc(len+4);
00053 if (!p0)
00054 return AVERROR(ENOMEM);
00055 p = p0;
00056
00057 bytestream_put_byte(&p, last_block ? 0x84 : 0x04);
00058 bytestream_put_be24(&p, len);
00059 ff_vorbiscomment_write(&p, m, vendor, count);
00060
00061 avio_write(pb, p0, len+4);
00062 av_freep(&p0);
00063 p = NULL;
00064
00065 return 0;
00066 }
00067
00068 static int flac_write_header(struct AVFormatContext *s)
00069 {
00070 int ret;
00071 AVCodecContext *codec = s->streams[0]->codec;
00072
00073 ret = ff_flac_write_header(s->pb, codec, 0);
00074 if (ret)
00075 return ret;
00076
00077 ret = flac_write_block_comment(s->pb, &s->metadata, 0,
00078 codec->flags & CODEC_FLAG_BITEXACT);
00079 if (ret)
00080 return ret;
00081
00082
00083
00084
00085
00086 flac_write_block_padding(s->pb, 8192, 1);
00087
00088 return ret;
00089 }
00090
00091 static int flac_write_trailer(struct AVFormatContext *s)
00092 {
00093 AVIOContext *pb = s->pb;
00094 uint8_t *streaminfo;
00095 enum FLACExtradataFormat format;
00096 int64_t file_size;
00097
00098 if (!ff_flac_is_extradata_valid(s->streams[0]->codec, &format, &streaminfo))
00099 return -1;
00100
00101 if (!url_is_streamed(pb)) {
00102
00103 file_size = avio_tell(pb);
00104 avio_seek(pb, 8, SEEK_SET);
00105 avio_write(pb, streaminfo, FLAC_STREAMINFO_SIZE);
00106 avio_seek(pb, file_size, SEEK_SET);
00107 put_flush_packet(pb);
00108 } else {
00109 av_log(s, AV_LOG_WARNING, "unable to rewrite FLAC header.\n");
00110 }
00111 return 0;
00112 }
00113
00114 static int flac_write_packet(struct AVFormatContext *s, AVPacket *pkt)
00115 {
00116 avio_write(s->pb, pkt->data, pkt->size);
00117 put_flush_packet(s->pb);
00118 return 0;
00119 }
00120
00121 AVOutputFormat ff_flac_muxer = {
00122 "flac",
00123 NULL_IF_CONFIG_SMALL("raw FLAC"),
00124 "audio/x-flac",
00125 "flac",
00126 0,
00127 CODEC_ID_FLAC,
00128 CODEC_ID_NONE,
00129 flac_write_header,
00130 flac_write_packet,
00131 flac_write_trailer,
00132 .flags= AVFMT_NOTIMESTAMPS,
00133 };