... | ... |
@@ -200,6 +200,7 @@ External library support: |
200 | 200 |
--enable-libvo-amrwbenc enable AMR-WB encoding via libvo-amrwbenc [no] |
201 | 201 |
--enable-libvorbis enable Vorbis encoding via libvorbis [no] |
202 | 202 |
--enable-libvpx enable VP8 and VP9 de/encoding via libvpx [no] |
203 |
+ --enable-libwavpack enable wavpack encoding via libwavpack [no] |
|
203 | 204 |
--enable-libx264 enable H.264 encoding via x264 [no] |
204 | 205 |
--enable-libxavs enable AVS encoding via xavs [no] |
205 | 206 |
--enable-libxvid enable Xvid encoding via xvidcore, |
... | ... |
@@ -1060,6 +1061,7 @@ EXTERNAL_LIBRARY_LIST=" |
1060 | 1060 |
libvo_amrwbenc |
1061 | 1061 |
libvorbis |
1062 | 1062 |
libvpx |
1063 |
+ libwavpack |
|
1063 | 1064 |
libx264 |
1064 | 1065 |
libxavs |
1065 | 1066 |
libxvid |
... | ... |
@@ -1790,6 +1792,7 @@ libvpx_vp8_decoder_deps="libvpx" |
1790 | 1790 |
libvpx_vp8_encoder_deps="libvpx" |
1791 | 1791 |
libvpx_vp9_decoder_deps="libvpx" |
1792 | 1792 |
libvpx_vp9_encoder_deps="libvpx" |
1793 |
+libwavpack_encoder_deps="libwavpack" |
|
1793 | 1794 |
libx264_encoder_deps="libx264" |
1794 | 1795 |
libxavs_encoder_deps="libxavs" |
1795 | 1796 |
libxvid_encoder_deps="libxvid" |
... | ... |
@@ -3735,6 +3738,7 @@ enabled libvpx && { |
3735 | 3735 |
die "ERROR: libvpx encoder version must be >=0.9.6"; } |
3736 | 3736 |
enabled libvpx_vp9_decoder && { check_lib2 "vpx/vpx_decoder.h vpx/vp8dx.h" "vpx_codec_vp9_dx" -lvpx || disable libvpx_vp9_decoder; } |
3737 | 3737 |
enabled libvpx_vp9_encoder && { check_lib2 "vpx/vpx_encoder.h vpx/vp8cx.h" "vpx_codec_vp9_cx" -lvpx || disable libvpx_vp9_encoder; } } |
3738 |
+enabled libwavpack && require libwavpack wavpack/wavpack.h WavpackOpenFileOutput -lwavpack |
|
3738 | 3739 |
enabled libx264 && require libx264 x264.h x264_encoder_encode -lx264 && |
3739 | 3740 |
{ check_cpp_condition x264.h "X264_BUILD >= 118" || |
3740 | 3741 |
die "ERROR: libx264 version must be >= 0.118."; } |
... | ... |
@@ -412,6 +412,35 @@ Selected by Encoder (default) |
412 | 412 |
|
413 | 413 |
@end table |
414 | 414 |
|
415 |
+@section libwavpack |
|
416 |
+ |
|
417 |
+A wrapper providing WavPack encoding through libwavpack. |
|
418 |
+ |
|
419 |
+Only lossless mode using 32-bit integer samples is supported currently. |
|
420 |
+The @option{compression_level} option can be used to control speed vs. |
|
421 |
+compression tradeoff, with the values mapped to libwavpack as follows: |
|
422 |
+ |
|
423 |
+@table @option |
|
424 |
+ |
|
425 |
+@item 0 |
|
426 |
+Fast mode - corresponding to the wavpack @option{-f} option. |
|
427 |
+ |
|
428 |
+@item 1 |
|
429 |
+Normal (default) settings. |
|
430 |
+ |
|
431 |
+@item 2 |
|
432 |
+High quality - corresponding to the wavpack @option{-h} option. |
|
433 |
+ |
|
434 |
+@item 3 |
|
435 |
+Very high quality - corresponding to the wavpack @option{-hh} option. |
|
436 |
+ |
|
437 |
+@item 4-8 |
|
438 |
+Same as 3, but with extra processing enabled - corresponding to the wavpack |
|
439 |
+@option{-x} option. I.e. 4 is the same as @option{-x2} and 8 is the same as |
|
440 |
+@option{-x6}. |
|
441 |
+ |
|
442 |
+@end table |
|
443 |
+ |
|
415 | 444 |
@c man end AUDIO ENCODERS |
416 | 445 |
|
417 | 446 |
@chapter Video Encoders |
... | ... |
@@ -79,6 +79,14 @@ Go to @url{http://www.webmproject.org/} and follow the instructions for |
79 | 79 |
installing the library. Then pass @code{--enable-libvpx} to configure to |
80 | 80 |
enable it. |
81 | 81 |
|
82 |
+@section libwavpack |
|
83 |
+ |
|
84 |
+Libav can make use of the libwavpack library for WavPack encoding. |
|
85 |
+ |
|
86 |
+Go to @url{http://www.wavpack.com/} and follow the instructions for |
|
87 |
+installing the library. Then pass @code{--enable-libwavpack} to configure to |
|
88 |
+enable it. |
|
89 |
+ |
|
82 | 90 |
@section x264 |
83 | 91 |
|
84 | 92 |
Libav can make use of the x264 library for H.264 encoding. |
... | ... |
@@ -810,7 +818,8 @@ following image formats are supported: |
810 | 810 |
@item TwinVQ (VQF flavor) @tab @tab X |
811 | 811 |
@item Vorbis @tab E @tab X |
812 | 812 |
@tab A native but very primitive encoder exists. |
813 |
-@item WavPack @tab @tab X |
|
813 |
+@item WavPack @tab E @tab X |
|
814 |
+ @tab supported through external library libwavpack |
|
814 | 815 |
@item Westwood Audio (SND1) @tab @tab X |
815 | 816 |
@item Windows Media Audio 1 @tab X @tab X |
816 | 817 |
@item Windows Media Audio 2 @tab X @tab X |
... | ... |
@@ -599,6 +599,7 @@ OBJS-$(CONFIG_LIBVPX_VP8_DECODER) += libvpxdec.o |
599 | 599 |
OBJS-$(CONFIG_LIBVPX_VP8_ENCODER) += libvpxenc.o |
600 | 600 |
OBJS-$(CONFIG_LIBVPX_VP9_DECODER) += libvpxdec.o |
601 | 601 |
OBJS-$(CONFIG_LIBVPX_VP9_ENCODER) += libvpxenc.o |
602 |
+OBJS-$(CONFIG_LIBWAVPACK_ENCODER) += libwavpackenc.o |
|
602 | 603 |
OBJS-$(CONFIG_LIBX264_ENCODER) += libx264.o |
603 | 604 |
OBJS-$(CONFIG_LIBXAVS_ENCODER) += libxavs.o |
604 | 605 |
OBJS-$(CONFIG_LIBXVID_ENCODER) += libxvid.o |
... | ... |
@@ -432,6 +432,7 @@ void avcodec_register_all(void) |
432 | 432 |
REGISTER_ENCODER(LIBVORBIS, libvorbis); |
433 | 433 |
REGISTER_ENCDEC (LIBVPX_VP8, libvpx_vp8); |
434 | 434 |
REGISTER_ENCDEC (LIBVPX_VP9, libvpx_vp9); |
435 |
+ REGISTER_ENCODER(LIBWAVPACK, libwavpack); |
|
435 | 436 |
REGISTER_ENCODER(LIBX264, libx264); |
436 | 437 |
REGISTER_ENCODER(LIBXAVS, libxavs); |
437 | 438 |
REGISTER_ENCODER(LIBXVID, libxvid); |
438 | 439 |
new file mode 100644 |
... | ... |
@@ -0,0 +1,194 @@ |
0 |
+/* |
|
1 |
+ * This file is part of Libav. |
|
2 |
+ * |
|
3 |
+ * Libav is free software; you can redistribute it and/or |
|
4 |
+ * modify it under the terms of the GNU Lesser General Public |
|
5 |
+ * License as published by the Free Software Foundation; either |
|
6 |
+ * version 2.1 of the License, or (at your option) any later version. |
|
7 |
+ * |
|
8 |
+ * Libav is distributed in the hope that it will be useful, |
|
9 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
10 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
11 |
+ * Lesser General Public License for more details. |
|
12 |
+ * |
|
13 |
+ * You should have received a copy of the GNU Lesser General Public |
|
14 |
+ * License along with Libav; if not, write to the Free Software |
|
15 |
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
16 |
+ */ |
|
17 |
+ |
|
18 |
+#include <wavpack/wavpack.h> |
|
19 |
+#include <string.h> |
|
20 |
+ |
|
21 |
+#include "libavutil/attributes.h" |
|
22 |
+#include "libavutil/opt.h" |
|
23 |
+#include "libavutil/samplefmt.h" |
|
24 |
+ |
|
25 |
+#include "audio_frame_queue.h" |
|
26 |
+#include "avcodec.h" |
|
27 |
+#include "internal.h" |
|
28 |
+ |
|
29 |
+#define WV_DEFAULT_BLOCK_SIZE 32768 |
|
30 |
+ |
|
31 |
+typedef struct LibWavpackContext { |
|
32 |
+ const AVClass *class; |
|
33 |
+ WavpackContext *wv; |
|
34 |
+ AudioFrameQueue afq; |
|
35 |
+ |
|
36 |
+ AVPacket *pkt; |
|
37 |
+ int user_size; |
|
38 |
+ |
|
39 |
+ int got_output; |
|
40 |
+} LibWavpackContext; |
|
41 |
+ |
|
42 |
+static int wavpack_encode_frame(AVCodecContext *avctx, AVPacket *pkt, |
|
43 |
+ const AVFrame *frame, int *got_output) |
|
44 |
+{ |
|
45 |
+ LibWavpackContext *s = avctx->priv_data; |
|
46 |
+ int ret; |
|
47 |
+ |
|
48 |
+ s->got_output = 0; |
|
49 |
+ s->pkt = pkt; |
|
50 |
+ s->user_size = pkt->size; |
|
51 |
+ |
|
52 |
+ if (frame) { |
|
53 |
+ ret = ff_af_queue_add(&s->afq, frame); |
|
54 |
+ if (ret < 0) |
|
55 |
+ return ret; |
|
56 |
+ |
|
57 |
+ ret = WavpackPackSamples(s->wv, (int32_t*)frame->data[0], frame->nb_samples); |
|
58 |
+ if (!ret) { |
|
59 |
+ av_log(avctx, AV_LOG_ERROR, "Error encoding a frame: %s\n", |
|
60 |
+ WavpackGetErrorMessage(s->wv)); |
|
61 |
+ return AVERROR_UNKNOWN; |
|
62 |
+ } |
|
63 |
+ } |
|
64 |
+ |
|
65 |
+ if (!s->got_output && |
|
66 |
+ (!frame || frame->nb_samples < avctx->frame_size)) { |
|
67 |
+ ret = WavpackFlushSamples(s->wv); |
|
68 |
+ if (!ret) { |
|
69 |
+ av_log(avctx, AV_LOG_ERROR, "Error flushing the encoder: %s\n", |
|
70 |
+ WavpackGetErrorMessage(s->wv)); |
|
71 |
+ return AVERROR_UNKNOWN; |
|
72 |
+ } |
|
73 |
+ } |
|
74 |
+ |
|
75 |
+ if (s->got_output) { |
|
76 |
+ ff_af_queue_remove(&s->afq, avctx->frame_size, &pkt->pts, &pkt->duration); |
|
77 |
+ *got_output = 1; |
|
78 |
+ } |
|
79 |
+ |
|
80 |
+ return 0; |
|
81 |
+} |
|
82 |
+ |
|
83 |
+static int encode_callback(void *id, void *data, int32_t count) |
|
84 |
+{ |
|
85 |
+ AVCodecContext *avctx = id; |
|
86 |
+ LibWavpackContext *s = avctx->priv_data; |
|
87 |
+ int ret, offset = s->pkt->size; |
|
88 |
+ |
|
89 |
+ if (s->user_size) { |
|
90 |
+ if (s->user_size - count < s->pkt->size) { |
|
91 |
+ av_log(avctx, AV_LOG_ERROR, "Provided packet too small.\n"); |
|
92 |
+ return 0; |
|
93 |
+ } |
|
94 |
+ s->pkt->size += count; |
|
95 |
+ } else { |
|
96 |
+ ret = av_grow_packet(s->pkt, count); |
|
97 |
+ if (ret < 0) { |
|
98 |
+ av_log(avctx, AV_LOG_ERROR, "Error allocating output packet.\n"); |
|
99 |
+ return 0; |
|
100 |
+ } |
|
101 |
+ } |
|
102 |
+ |
|
103 |
+ memcpy(s->pkt->data + offset, data, count); |
|
104 |
+ |
|
105 |
+ s->got_output = 1; |
|
106 |
+ |
|
107 |
+ return 1; |
|
108 |
+} |
|
109 |
+ |
|
110 |
+static av_cold int wavpack_encode_init(AVCodecContext *avctx) |
|
111 |
+{ |
|
112 |
+ LibWavpackContext *s = avctx->priv_data; |
|
113 |
+ WavpackConfig config = { 0 }; |
|
114 |
+ int ret; |
|
115 |
+ |
|
116 |
+ s->wv = WavpackOpenFileOutput(encode_callback, avctx, NULL); |
|
117 |
+ if (!s->wv) { |
|
118 |
+ av_log(avctx, AV_LOG_ERROR, "Error allocating the encoder.\n"); |
|
119 |
+ return AVERROR(ENOMEM); |
|
120 |
+ } |
|
121 |
+ |
|
122 |
+ if (!avctx->frame_size) |
|
123 |
+ avctx->frame_size = WV_DEFAULT_BLOCK_SIZE; |
|
124 |
+ |
|
125 |
+ config.bytes_per_sample = 4; |
|
126 |
+ config.bits_per_sample = 32; |
|
127 |
+ config.block_samples = avctx->frame_size; |
|
128 |
+ config.channel_mask = avctx->channel_layout; |
|
129 |
+ config.num_channels = avctx->channels; |
|
130 |
+ config.sample_rate = avctx->sample_rate; |
|
131 |
+ |
|
132 |
+ if (avctx->compression_level != FF_COMPRESSION_DEFAULT) { |
|
133 |
+ if (avctx->compression_level >= 3) { |
|
134 |
+ config.flags |= CONFIG_VERY_HIGH_FLAG; |
|
135 |
+ |
|
136 |
+ if (avctx->compression_level >= 8) |
|
137 |
+ config.xmode = 6; |
|
138 |
+ else if (avctx->compression_level >= 7) |
|
139 |
+ config.xmode = 5; |
|
140 |
+ else if (avctx->compression_level >= 6) |
|
141 |
+ config.xmode = 4; |
|
142 |
+ else if (avctx->compression_level >= 5) |
|
143 |
+ config.xmode = 3; |
|
144 |
+ else if (avctx->compression_level >= 4) |
|
145 |
+ config.xmode = 2; |
|
146 |
+ } else if (avctx->compression_level >= 2) |
|
147 |
+ config.flags |= CONFIG_HIGH_FLAG; |
|
148 |
+ else if (avctx->compression_level < 1) |
|
149 |
+ config.flags |= CONFIG_FAST_FLAG; |
|
150 |
+ } |
|
151 |
+ |
|
152 |
+ ret = WavpackSetConfiguration(s->wv, &config, -1); |
|
153 |
+ if (!ret) |
|
154 |
+ goto fail; |
|
155 |
+ |
|
156 |
+ ret = WavpackPackInit(s->wv); |
|
157 |
+ if (!ret) |
|
158 |
+ goto fail; |
|
159 |
+ |
|
160 |
+ ff_af_queue_init(avctx, &s->afq); |
|
161 |
+ |
|
162 |
+ return 0; |
|
163 |
+ |
|
164 |
+fail: |
|
165 |
+ av_log(avctx, AV_LOG_ERROR, "Error configuring the encoder: %s.\n", |
|
166 |
+ WavpackGetErrorMessage(s->wv)); |
|
167 |
+ WavpackCloseFile(s->wv); |
|
168 |
+ return AVERROR_UNKNOWN; |
|
169 |
+} |
|
170 |
+ |
|
171 |
+static av_cold int wavpack_encode_close(AVCodecContext *avctx) |
|
172 |
+{ |
|
173 |
+ LibWavpackContext *s = avctx->priv_data; |
|
174 |
+ |
|
175 |
+ WavpackCloseFile(s->wv); |
|
176 |
+ |
|
177 |
+ ff_af_queue_close(&s->afq); |
|
178 |
+ |
|
179 |
+ return 0; |
|
180 |
+} |
|
181 |
+ |
|
182 |
+AVCodec ff_libwavpack_encoder = { |
|
183 |
+ .name = "libwavpack", |
|
184 |
+ .type = AVMEDIA_TYPE_AUDIO, |
|
185 |
+ .id = AV_CODEC_ID_WAVPACK, |
|
186 |
+ .priv_data_size = sizeof(LibWavpackContext), |
|
187 |
+ .init = wavpack_encode_init, |
|
188 |
+ .encode2 = wavpack_encode_frame, |
|
189 |
+ .close = wavpack_encode_close, |
|
190 |
+ .capabilities = CODEC_CAP_DELAY | CODEC_CAP_SMALL_LAST_FRAME, |
|
191 |
+ .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S32, |
|
192 |
+ AV_SAMPLE_FMT_NONE }, |
|
193 |
+}; |