merge down from merged-API-layer branch: cvs -q up -dP -j API_LAYER_MERGING_BASELINE...
[platform/upstream/flac.git] / src / test_libFLAC++ / encoders.cpp
1 /* test_libFLAC++ - Unit tester for libFLAC++
2  * Copyright (C) 2002,2003,2004,2005,2006  Josh Coalson
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17  */
18
19 #include "encoders.h"
20 #include "FLAC/assert.h"
21 #include "FLAC++/encoder.h"
22 extern "C" {
23 #include "test_libs_common/file_utils_flac.h"
24 #include "test_libs_common/metadata_utils.h"
25 }
26 #include <errno.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 typedef enum {
32         LAYER_STREAM = 0, /* FLAC__stream_encoder_init_stream() without seeking */
33         LAYER_SEEKABLE_STREAM, /* FLAC__stream_encoder_init_stream() with seeking */
34         LAYER_FILE, /* FLAC__stream_encoder_init_FILE() */
35         LAYER_FILENAME /* FLAC__stream_encoder_init_file() */
36 } Layer;
37
38 static const char * const LayerString[] = {
39         "Stream",
40         "Seekable Stream",
41         "FILE*",
42         "Filename"
43 };
44
45 static ::FLAC__StreamMetadata streaminfo_, padding_, seektable_, application1_, application2_, vorbiscomment_, cuesheet_, unknown_;
46 static ::FLAC__StreamMetadata *metadata_sequence_[] = { &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &unknown_ };
47 static const unsigned num_metadata_ = sizeof(metadata_sequence_) / sizeof(metadata_sequence_[0]);
48 static const char *flacfilename_ = "metadata.flac";
49
50 static FLAC__bool die_(const char *msg)
51 {
52         printf("ERROR: %s\n", msg);
53         return false;
54 }
55
56 static bool die_s_(const char *msg, const FLAC::Encoder::Stream *encoder)
57 {
58         FLAC::Encoder::Stream::State state = encoder->get_state();
59
60         if(msg)
61                 printf("FAILED, %s", msg);
62         else
63                 printf("FAILED");
64
65         printf(", state = %u (%s)\n", (unsigned)((::FLAC__StreamEncoderState)state), state.as_cstring());
66         if(state == ::FLAC__STREAM_ENCODER_VERIFY_DECODER_ERROR) {
67                 FLAC::Decoder::Stream::State dstate = encoder->get_verify_decoder_state();
68                 printf("      verify decoder state = %u (%s)\n", (unsigned)((::FLAC__StreamDecoderState)dstate), dstate.as_cstring());
69         }
70
71         return false;
72 }
73
74 static void init_metadata_blocks_()
75 {
76         mutils__init_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &unknown_);
77 }
78
79 static void free_metadata_blocks_()
80 {
81         mutils__free_metadata_blocks(&streaminfo_, &padding_, &seektable_, &application1_, &application2_, &vorbiscomment_, &cuesheet_, &unknown_);
82 }
83
84 class StreamEncoder : public FLAC::Encoder::Stream {
85 public:
86         Layer layer_;
87
88         StreamEncoder(Layer layer): FLAC::Encoder::Stream(), layer_(layer) { }
89         ~StreamEncoder() { }
90
91         // from FLAC::Encoder::Stream
92         ::FLAC__StreamEncoderWriteStatus write_callback(const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame);
93         ::FLAC__StreamEncoderSeekStatus seek_callback(FLAC__uint64 absolute_byte_offset);
94         ::FLAC__StreamEncoderTellStatus tell_callback(FLAC__uint64 *absolute_byte_offset);
95         void metadata_callback(const ::FLAC__StreamMetadata *metadata);
96 };
97
98 ::FLAC__StreamEncoderWriteStatus StreamEncoder::write_callback(const FLAC__byte buffer[], unsigned bytes, unsigned samples, unsigned current_frame)
99 {
100         (void)buffer, (void)bytes, (void)samples, (void)current_frame;
101
102         return ::FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
103 }
104
105 ::FLAC__StreamEncoderSeekStatus StreamEncoder::seek_callback(FLAC__uint64 absolute_byte_offset)
106 {
107         (void)absolute_byte_offset;
108
109         return layer_==LAYER_STREAM? ::FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED : ::FLAC__STREAM_ENCODER_SEEK_STATUS_OK;
110 }
111
112 ::FLAC__StreamEncoderTellStatus StreamEncoder::tell_callback(FLAC__uint64 *absolute_byte_offset)
113 {
114         *absolute_byte_offset = 0;
115
116         return layer_==LAYER_STREAM? ::FLAC__STREAM_ENCODER_TELL_STATUS_UNSUPPORTED : ::FLAC__STREAM_ENCODER_TELL_STATUS_OK;
117 }
118
119 void StreamEncoder::metadata_callback(const ::FLAC__StreamMetadata *metadata)
120 {
121         (void)metadata;
122 }
123
124 class FileEncoder : public FLAC::Encoder::File {
125 public:
126         Layer layer_;
127
128         FileEncoder(Layer layer): FLAC::Encoder::File(), layer_(layer) { }
129         ~FileEncoder() { }
130
131         // from FLAC::Encoder::File
132         void progress_callback(FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate);
133 };
134
135 void FileEncoder::progress_callback(FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned frames_written, unsigned total_frames_estimate)
136 {
137         (void)bytes_written, (void)samples_written, (void)frames_written, (void)total_frames_estimate;
138 }
139
140 static FLAC::Encoder::Stream *new_by_layer(Layer layer)
141 {
142         if(layer < LAYER_FILE)
143                 return new StreamEncoder(layer);
144         else
145                 return new FileEncoder(layer);
146 }
147
148 static bool test_stream_encoder(Layer layer)
149 {
150         FLAC::Encoder::Stream *encoder;
151         FILE *file = 0;
152         FLAC__int32 samples[1024];
153         FLAC__int32 *samples_array[1] = { samples };
154         unsigned i;
155
156         printf("\n+++ libFLAC++ unit test: FLAC::Encoder::%s (layer: %s)\n\n", layer<LAYER_FILE? "Stream":"File", LayerString[layer]);
157
158         printf("allocating encoder instance... ");
159         encoder = new_by_layer(layer);
160         if(0 == encoder) {
161                 printf("FAILED, new returned NULL\n");
162                 return false;
163         }
164         printf("OK\n");
165
166         printf("testing is_valid()... ");
167         if(!encoder->is_valid()) {
168                 printf("FAILED, returned false\n");
169                 return false;
170         }
171         printf("OK\n");
172
173         printf("testing set_verify()... ");
174         if(!encoder->set_verify(true))
175                 return die_s_("returned false", encoder);
176         printf("OK\n");
177
178         printf("testing set_streamable_subset()... ");
179         if(!encoder->set_streamable_subset(true))
180                 return die_s_("returned false", encoder);
181         printf("OK\n");
182
183         printf("testing set_do_mid_side_stereo()... ");
184         if(!encoder->set_do_mid_side_stereo(false))
185                 return die_s_("returned false", encoder);
186         printf("OK\n");
187
188         printf("testing set_loose_mid_side_stereo()... ");
189         if(!encoder->set_loose_mid_side_stereo(false))
190                 return die_s_("returned false", encoder);
191         printf("OK\n");
192
193         printf("testing set_channels()... ");
194         if(!encoder->set_channels(streaminfo_.data.stream_info.channels))
195                 return die_s_("returned false", encoder);
196         printf("OK\n");
197
198         printf("testing set_bits_per_sample()... ");
199         if(!encoder->set_bits_per_sample(streaminfo_.data.stream_info.bits_per_sample))
200                 return die_s_("returned false", encoder);
201         printf("OK\n");
202
203         printf("testing set_sample_rate()... ");
204         if(!encoder->set_sample_rate(streaminfo_.data.stream_info.sample_rate))
205                 return die_s_("returned false", encoder);
206         printf("OK\n");
207
208         printf("testing set_blocksize()... ");
209         if(!encoder->set_blocksize(streaminfo_.data.stream_info.min_blocksize))
210                 return die_s_("returned false", encoder);
211         printf("OK\n");
212
213         printf("testing set_max_lpc_order()... ");
214         if(!encoder->set_max_lpc_order(0))
215                 return die_s_("returned false", encoder);
216         printf("OK\n");
217
218         printf("testing set_qlp_coeff_precision()... ");
219         if(!encoder->set_qlp_coeff_precision(0))
220                 return die_s_("returned false", encoder);
221         printf("OK\n");
222
223         printf("testing set_do_qlp_coeff_prec_search()... ");
224         if(!encoder->set_do_qlp_coeff_prec_search(false))
225                 return die_s_("returned false", encoder);
226         printf("OK\n");
227
228         printf("testing set_do_escape_coding()... ");
229         if(!encoder->set_do_escape_coding(false))
230                 return die_s_("returned false", encoder);
231         printf("OK\n");
232
233         printf("testing set_do_exhaustive_model_search()... ");
234         if(!encoder->set_do_exhaustive_model_search(false))
235                 return die_s_("returned false", encoder);
236         printf("OK\n");
237
238         printf("testing set_min_residual_partition_order()... ");
239         if(!encoder->set_min_residual_partition_order(0))
240                 return die_s_("returned false", encoder);
241         printf("OK\n");
242
243         printf("testing set_max_residual_partition_order()... ");
244         if(!encoder->set_max_residual_partition_order(0))
245                 return die_s_("returned false", encoder);
246         printf("OK\n");
247
248         printf("testing set_rice_parameter_search_dist()... ");
249         if(!encoder->set_rice_parameter_search_dist(0))
250                 return die_s_("returned false", encoder);
251         printf("OK\n");
252
253         printf("testing set_total_samples_estimate()... ");
254         if(!encoder->set_total_samples_estimate(streaminfo_.data.stream_info.total_samples))
255                 return die_s_("returned false", encoder);
256         printf("OK\n");
257
258         printf("testing set_metadata()... ");
259         if(!encoder->set_metadata(metadata_sequence_, num_metadata_))
260                 return die_s_("returned false", encoder);
261         printf("OK\n");
262
263         switch(layer) {
264                 case LAYER_STREAM:
265                 case LAYER_SEEKABLE_STREAM:
266                         printf("testing init()... ");
267                         if(encoder->init() != ::FLAC__STREAM_ENCODER_INIT_STATUS_OK)
268                                 return die_s_(0, encoder);
269                         break;
270                 case LAYER_FILE:
271                         printf("opening file for FLAC output... ");
272                         file = ::fopen(flacfilename_, "w+b");
273                         if(0 == file) {
274                                 printf("ERROR (%s)\n", strerror(errno));
275                                 return false;
276                         }
277                         printf("OK\n");
278
279                         printf("testing init()... ");
280                         if(dynamic_cast<FLAC::Encoder::File*>(encoder)->init(file) != ::FLAC__STREAM_ENCODER_INIT_STATUS_OK)
281                                 return die_s_(0, encoder);
282                         break;
283                 case LAYER_FILENAME:
284                         printf("testing init()... ");
285                         if(dynamic_cast<FLAC::Encoder::File*>(encoder)->init(flacfilename_) != ::FLAC__STREAM_ENCODER_INIT_STATUS_OK)
286                                 return die_s_(0, encoder);
287                         break;
288                 default:
289                         die_("internal error 001");
290                         return false;
291         }
292         printf("OK\n");
293
294         printf("testing get_state()... ");
295         FLAC::Encoder::Stream::State state = encoder->get_state();
296         printf("returned state = %u (%s)... OK\n", (unsigned)((::FLAC__StreamEncoderState)state), state.as_cstring());
297
298         printf("testing get_verify_decoder_state()... ");
299         FLAC::Decoder::Stream::State dstate = encoder->get_verify_decoder_state();
300         printf("returned state = %u (%s)... OK\n", (unsigned)((::FLAC__StreamDecoderState)dstate), dstate.as_cstring());
301
302         {
303                 FLAC__uint64 absolute_sample;
304                 unsigned frame_number;
305                 unsigned channel;
306                 unsigned sample;
307                 FLAC__int32 expected;
308                 FLAC__int32 got;
309
310                 printf("testing get_verify_decoder_error_stats()... ");
311                 encoder->get_verify_decoder_error_stats(&absolute_sample, &frame_number, &channel, &sample, &expected, &got);
312                 printf("OK\n");
313         }
314
315         printf("testing get_verify()... ");
316         if(encoder->get_verify() != true) {
317                 printf("FAILED, expected true, got false\n");
318                 return false;
319         }
320         printf("OK\n");
321
322         printf("testing get_streamable_subset()... ");
323         if(encoder->get_streamable_subset() != true) {
324                 printf("FAILED, expected true, got false\n");
325                 return false;
326         }
327         printf("OK\n");
328
329         printf("testing get_do_mid_side_stereo()... ");
330         if(encoder->get_do_mid_side_stereo() != false) {
331                 printf("FAILED, expected false, got true\n");
332                 return false;
333         }
334         printf("OK\n");
335
336         printf("testing get_loose_mid_side_stereo()... ");
337         if(encoder->get_loose_mid_side_stereo() != false) {
338                 printf("FAILED, expected false, got true\n");
339                 return false;
340         }
341         printf("OK\n");
342
343         printf("testing get_channels()... ");
344         if(encoder->get_channels() != streaminfo_.data.stream_info.channels) {
345                 printf("FAILED, expected %u, got %u\n", streaminfo_.data.stream_info.channels, encoder->get_channels());
346                 return false;
347         }
348         printf("OK\n");
349
350         printf("testing get_bits_per_sample()... ");
351         if(encoder->get_bits_per_sample() != streaminfo_.data.stream_info.bits_per_sample) {
352                 printf("FAILED, expected %u, got %u\n", streaminfo_.data.stream_info.bits_per_sample, encoder->get_bits_per_sample());
353                 return false;
354         }
355         printf("OK\n");
356
357         printf("testing get_sample_rate()... ");
358         if(encoder->get_sample_rate() != streaminfo_.data.stream_info.sample_rate) {
359                 printf("FAILED, expected %u, got %u\n", streaminfo_.data.stream_info.sample_rate, encoder->get_sample_rate());
360                 return false;
361         }
362         printf("OK\n");
363
364         printf("testing get_blocksize()... ");
365         if(encoder->get_blocksize() != streaminfo_.data.stream_info.min_blocksize) {
366                 printf("FAILED, expected %u, got %u\n", streaminfo_.data.stream_info.min_blocksize, encoder->get_blocksize());
367                 return false;
368         }
369         printf("OK\n");
370
371         printf("testing get_max_lpc_order()... ");
372         if(encoder->get_max_lpc_order() != 0) {
373                 printf("FAILED, expected %u, got %u\n", 0, encoder->get_max_lpc_order());
374                 return false;
375         }
376         printf("OK\n");
377
378         printf("testing get_qlp_coeff_precision()... ");
379         (void)encoder->get_qlp_coeff_precision();
380         /* we asked the encoder to auto select this so we accept anything */
381         printf("OK\n");
382
383         printf("testing get_do_qlp_coeff_prec_search()... ");
384         if(encoder->get_do_qlp_coeff_prec_search() != false) {
385                 printf("FAILED, expected false, got true\n");
386                 return false;
387         }
388         printf("OK\n");
389
390         printf("testing get_do_escape_coding()... ");
391         if(encoder->get_do_escape_coding() != false) {
392                 printf("FAILED, expected false, got true\n");
393                 return false;
394         }
395         printf("OK\n");
396
397         printf("testing get_do_exhaustive_model_search()... ");
398         if(encoder->get_do_exhaustive_model_search() != false) {
399                 printf("FAILED, expected false, got true\n");
400                 return false;
401         }
402         printf("OK\n");
403
404         printf("testing get_min_residual_partition_order()... ");
405         if(encoder->get_min_residual_partition_order() != 0) {
406                 printf("FAILED, expected %u, got %u\n", 0, encoder->get_min_residual_partition_order());
407                 return false;
408         }
409         printf("OK\n");
410
411         printf("testing get_max_residual_partition_order()... ");
412         if(encoder->get_max_residual_partition_order() != 0) {
413                 printf("FAILED, expected %u, got %u\n", 0, encoder->get_max_residual_partition_order());
414                 return false;
415         }
416         printf("OK\n");
417
418         printf("testing get_rice_parameter_search_dist()... ");
419         if(encoder->get_rice_parameter_search_dist() != 0) {
420                 printf("FAILED, expected %u, got %u\n", 0, encoder->get_rice_parameter_search_dist());
421                 return false;
422         }
423         printf("OK\n");
424
425         printf("testing get_total_samples_estimate()... ");
426         if(encoder->get_total_samples_estimate() != streaminfo_.data.stream_info.total_samples) {
427                 printf("FAILED, expected %llu, got %llu\n", streaminfo_.data.stream_info.total_samples, encoder->get_total_samples_estimate());
428                 return false;
429         }
430         printf("OK\n");
431
432         /* init the dummy sample buffer */
433         for(i = 0; i < sizeof(samples) / sizeof(FLAC__int32); i++)
434                 samples[i] = i & 7;
435
436         printf("testing process()... ");
437         if(!encoder->process(samples_array, sizeof(samples) / sizeof(FLAC__int32)))
438                 return die_s_("returned false", encoder);
439         printf("OK\n");
440
441         printf("testing process_interleaved()... ");
442         if(!encoder->process_interleaved(samples, sizeof(samples) / sizeof(FLAC__int32)))
443                 return die_s_("returned false", encoder);
444         printf("OK\n");
445
446         printf("testing finish()... ");
447         encoder->finish();
448         printf("OK\n");
449
450         printf("freeing encoder instance... ");
451         delete encoder;
452         printf("OK\n");
453
454         printf("\nPASSED!\n");
455
456         return true;
457 }
458
459 bool test_encoders()
460 {
461         init_metadata_blocks_();
462
463         if(!test_stream_encoder(LAYER_STREAM))
464                 return false;
465
466         if(!test_stream_encoder(LAYER_SEEKABLE_STREAM))
467                 return false;
468
469         if(!test_stream_encoder(LAYER_FILE))
470                 return false;
471
472         if(!test_stream_encoder(LAYER_FILENAME))
473                 return false;
474
475         free_metadata_blocks_();
476
477         return true;
478 }