Hi List,
I recently was assigned a task to port FLAC Encoder to our embedded
platform. Thanks to OO-like design of the libFLAC and throught
documentation, that porting went like a charm. I had some problems with
chmod/chown like routines while porting but I was able to safely remove that
piece of code without any trouble.
I have observed that the my application FLAC Encoder failes in
restartability test after about 1500 restarts. Narrowing down the problem
shows that I am having problem with multiple calls of
FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair() and/or
FLAC__metadata_object_vorbiscomment_append_comment() routines, i.e. If I
have vorbis comment in my metadata with copy flag == true, my application's
restartability is affected. To test my observation, I took the simple
encoder example available with the FLAC package and added a couple of vorbis
comments in it as follows,
#if HAVE_CONFIG_H
# include config.h
#endif
#include stdio.h
#include stdlib.h
#include string.h
#include FLAC_metadata.h
#include FLAC_stream_encoder.h
static char outFileName[256] = {encAudio.flac};
static unsigned char FLAC_tagTitle[] = {Title};
static const unsigned char FLAC_tagArtist[] = {Artist};
static const unsigned char FLAC_tagAlbum[] = {Album};
static const unsigned char FLAC_tagYear[] = {2008};
static const unsigned char FLAC_tagGenre[] = {Audio Track};
static const unsigned char defFileName[16] = {encAUDIO.flac};
static void progress_callback(const FLAC__StreamEncoder *encoder,
FLAC__uint64 bytes_written, FLAC__uint64 samples_written, unsigned
frames_written, unsigned total_frames_estimate, void *client_data);
#define READSIZE 1024
static unsigned total_samples = 0; /* can use a 32-bit number due to WAVE
size limitations */
static FLAC__byte buffer[READSIZE/*samples*/ * 2/*bytes_per_sample*/ *
2/*channels*/]; /* we read the WAVE data into here */
static FLAC__int32 pcm[READSIZE/*samples*/ * 2/*channels*/];
int main(int argc, char *argv[])
{
FLAC__bool ok = true;
FLAC__StreamEncoder *encoder = 0;
FLAC__StreamEncoderInitStatus init_status;
FLAC__StreamMetadata *metadata[2];
FLAC__StreamMetadata_VorbisComment_Entry entry;
FILE *fin;
unsigned sample_rate = 0;
unsigned channels = 0;
unsigned bps = 0;
if(argc != 3) {
fprintf(stderr, usage: %s infile.wav outfile.flac\n, argv[0]);
return 1;
}
if((fin = fopen(argv[1], rb)) == NULL) {
fprintf(stderr, ERROR: opening %s for output\n, argv[1]);
return 1;
}
/* read wav header and validate it */
if(
fread(buffer, 1, 44, fin) != 44 ||
memcmp(buffer, RIFF, 4) ||
memcmp(buffer+8, WAVEfmt \020\000\000\000\001\000\002\000, 16) ||
memcmp(buffer+32, \004\000\020\000data, 8)
) {
fprintf(stderr, ERROR: invalid/unsupported WAVE file, only 16bps
stereo WAVE in canonical form allowed\n);
fclose(fin);
return 1;
}
sample_rate = ((unsigned)buffer[27] 8) | buffer[26]) 8) |
buffer[25]) 8) | buffer[24];
printf(sampleRate:%d\n, sample_rate);
channels = 2;
bps = 16;
total_samples = (((unsigned)buffer[43] 8) | buffer[42]) 8) |
buffer[41]) 8) | buffer[40]) / 4;
/* allocate the encoder */
if((encoder = FLAC__stream_encoder_new()) == NULL) {
fprintf(stderr, ERROR: allocating encoder\n);
fclose(fin);
return 1;
}
ok = FLAC__stream_encoder_set_verify(encoder, true);
ok = FLAC__stream_encoder_set_compression_level(encoder, 5);
ok = FLAC__stream_encoder_set_channels(encoder, channels);
ok = FLAC__stream_encoder_set_bits_per_sample(encoder, bps);
ok = FLAC__stream_encoder_set_sample_rate(encoder, sample_rate);
ok = FLAC__stream_encoder_set_total_samples_estimate(encoder,
total_samples);
if( (metadata[0] =
FLAC__metadata_object_new(FLAC__METADATA_TYPE_PADDING)) == NULL ||
(metadata[1] =
FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT)) == NULL)
ok = false;
metadata[0]-length = 512; /* set the padding length */
#if BUGGY
ok =
FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(entry,
TITLE, FLAC_tagTitle);
ok = FLAC__metadata_object_vorbiscomment_append_comment(metadata[1],
entry, /*copy=*/true);
ok =
FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(entry,
ARTIST, FLAC_tagArtist);
ok = FLAC__metadata_object_vorbiscomment_append_comment(metadata[1],
entry, /*copy=*/true);
ok =
FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(entry,
ALBUM, FLAC_tagAlbum);
ok = FLAC__metadata_object_vorbiscomment_append_comment(metadata[1],
entry, /*copy=*/true);
ok =
FLAC__metadata_object_vorbiscomment_entry_from_name_value_pair(entry,
GENRE, FLAC_tagGenre);
ok = FLAC__metadata_object_vorbiscomment_append_comment(metadata[1],
entry,