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 "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
00082
00083
00084
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 (!avpriv_flac_is_extradata_valid(s->streams[0]->codec, &format, &streaminfo))
00098 return -1;
00099
00100 if (pb->seekable) {
00101
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 .name = "flac",
00122 .long_name = NULL_IF_CONFIG_SMALL("raw FLAC"),
00123 .mime_type = "audio/x-flac",
00124 .extensions = "flac",
00125 .audio_codec = AV_CODEC_ID_FLAC,
00126 .video_codec = AV_CODEC_ID_NONE,
00127 .write_header = flac_write_header,
00128 .write_packet = flac_write_packet,
00129 .write_trailer = flac_write_trailer,
00130 .flags = AVFMT_NOTIMESTAMPS,
00131 };