lavf: add AVFMT_FLAG_BITEXACT.
[libav.git] / libavformat / flacenc.c
CommitLineData
caee91f7
JR
1/*
2 * raw FLAC muxer
3 * Copyright (c) 2006-2009 Justin Ruggles
4 *
2912e87a 5 * This file is part of Libav.
caee91f7 6 *
2912e87a 7 * Libav is free software; you can redistribute it and/or
caee91f7
JR
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
2912e87a 12 * Libav is distributed in the hope that it will be useful,
caee91f7
JR
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
2912e87a 18 * License along with Libav; if not, write to the Free Software
caee91f7
JR
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
aa69cbc9 22#include "libavutil/opt.h"
59c6178a 23#include "libavcodec/flac.h"
caee91f7 24#include "avformat.h"
2578326f 25#include "flacenc.h"
66061a12
JD
26#include "vorbiscomment.h"
27#include "libavcodec/bytestream.h"
caee91f7 28
caee91f7 29
aa69cbc9
JR
30typedef struct FlacMuxerContext {
31 const AVClass *class;
32 int write_header;
33} FlacMuxerContext;
34
ae628ec1 35static int flac_write_block_padding(AVIOContext *pb, unsigned int n_padding_bytes,
66061a12
JD
36 int last_block)
37{
77eb5504
AK
38 avio_w8(pb, last_block ? 0x81 : 0x01);
39 avio_wb24(pb, n_padding_bytes);
66061a12 40 while (n_padding_bytes > 0) {
77eb5504 41 avio_w8(pb, 0);
66061a12
JD
42 n_padding_bytes--;
43 }
44 return 0;
45}
46
d2d67e42 47static int flac_write_block_comment(AVIOContext *pb, AVDictionary **m,
66061a12
JD
48 int last_block, int bitexact)
49{
c6cd0e17 50 const char *vendor = bitexact ? "Libav" : LIBAVFORMAT_IDENT;
66061a12
JD
51 unsigned int len, count;
52 uint8_t *p, *p0;
53
042ca05f
AK
54 ff_metadata_conv(m, ff_vorbiscomment_metadata_conv, NULL);
55
81e5ff7a 56 len = ff_vorbiscomment_length(*m, vendor, &count);
66061a12
JD
57 p0 = av_malloc(len+4);
58 if (!p0)
59 return AVERROR(ENOMEM);
60 p = p0;
61
62 bytestream_put_byte(&p, last_block ? 0x84 : 0x04);
63 bytestream_put_be24(&p, len);
64 ff_vorbiscomment_write(&p, m, vendor, count);
65
77eb5504 66 avio_write(pb, p0, len+4);
66061a12
JD
67 av_freep(&p0);
68 p = NULL;
69
70 return 0;
71}
72
2578326f
JR
73static int flac_write_header(struct AVFormatContext *s)
74{
66061a12
JD
75 int ret;
76 AVCodecContext *codec = s->streams[0]->codec;
aa69cbc9
JR
77 FlacMuxerContext *c = s->priv_data;
78
79 if (!c->write_header)
80 return 0;
66061a12
JD
81
82 ret = ff_flac_write_header(s->pb, codec, 0);
83 if (ret)
84 return ret;
85
81e5ff7a 86 ret = flac_write_block_comment(s->pb, &s->metadata, 0,
0c1959b0 87 s->flags & AVFMT_FLAG_BITEXACT);
66061a12
JD
88 if (ret)
89 return ret;
90
91 /* The command line flac encoder defaults to placing a seekpoint
92 * every 10s. So one might add padding to allow that later
93 * but there seems to be no simple way to get the duration here.
94 * So let's try the flac default of 8192 bytes */
95 flac_write_block_padding(s->pb, 8192, 1);
96
97 return ret;
2578326f
JR
98}
99
caee91f7
JR
100static int flac_write_trailer(struct AVFormatContext *s)
101{
ae628ec1 102 AVIOContext *pb = s->pb;
59c6178a
JR
103 uint8_t *streaminfo;
104 enum FLACExtradataFormat format;
caee91f7 105 int64_t file_size;
aa69cbc9
JR
106 FlacMuxerContext *c = s->priv_data;
107
108 if (!c->write_header)
109 return 0;
caee91f7 110
d9cca9fc 111 if (!avpriv_flac_is_extradata_valid(s->streams[0]->codec, &format, &streaminfo))
59c6178a
JR
112 return -1;
113
8978feda 114 if (pb->seekable) {
59c6178a 115 /* rewrite the STREAMINFO header block data */
a2704c97 116 file_size = avio_tell(pb);
6b4aa5da 117 avio_seek(pb, 8, SEEK_SET);
77eb5504 118 avio_write(pb, streaminfo, FLAC_STREAMINFO_SIZE);
6b4aa5da 119 avio_seek(pb, file_size, SEEK_SET);
b7f2fdde 120 avio_flush(pb);
59c6178a
JR
121 } else {
122 av_log(s, AV_LOG_WARNING, "unable to rewrite FLAC header.\n");
caee91f7
JR
123 }
124 return 0;
125}
126
127static int flac_write_packet(struct AVFormatContext *s, AVPacket *pkt)
128{
77eb5504 129 avio_write(s->pb, pkt->data, pkt->size);
caee91f7
JR
130 return 0;
131}
132
aa69cbc9
JR
133static const AVOption flacenc_options[] = {
134 { "write_header", "Write the file header", offsetof(FlacMuxerContext, write_header), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM },
135 { NULL },
136};
137
138static const AVClass flac_muxer_class = {
139 .class_name = "flac muxer",
140 .item_name = av_default_item_name,
141 .option = flacenc_options,
142 .version = LIBAVUTIL_VERSION_INT,
143};
144
c6610a21 145AVOutputFormat ff_flac_muxer = {
dfc2c4d9
AK
146 .name = "flac",
147 .long_name = NULL_IF_CONFIG_SMALL("raw FLAC"),
aa69cbc9 148 .priv_data_size = sizeof(FlacMuxerContext),
dfc2c4d9
AK
149 .mime_type = "audio/x-flac",
150 .extensions = "flac",
36ef5369
AK
151 .audio_codec = AV_CODEC_ID_FLAC,
152 .video_codec = AV_CODEC_ID_NONE,
dfc2c4d9
AK
153 .write_header = flac_write_header,
154 .write_packet = flac_write_packet,
155 .write_trailer = flac_write_trailer,
20234a4b 156 .flags = AVFMT_NOTIMESTAMPS,
aa69cbc9 157 .priv_class = &flac_muxer_class,
caee91f7 158};