add support for writing SEEKTABLE block
authorJosh Coalson <jcoalson@users.sourceforce.net>
Fri, 13 Apr 2001 19:17:16 +0000 (19:17 +0000)
committerJosh Coalson <jcoalson@users.sourceforce.net>
Fri, 13 Apr 2001 19:17:16 +0000 (19:17 +0000)
include/FLAC/encoder.h
src/libFLAC/encoder.c
src/libFLAC/encoder_framing.c

index 902c279..decef04 100644 (file)
@@ -42,6 +42,7 @@ typedef enum {
        FLAC__ENCODER_BLOCK_SIZE_TOO_SMALL_FOR_LPC_ORDER,
        FLAC__ENCODER_NOT_STREAMABLE,
        FLAC__ENCODER_FRAMING_ERROR,
+       FLAC__ENCODER_INVALID_SEEK_TABLE,
        FLAC__ENCODER_FATAL_ERROR_WHILE_ENCODING,
        FLAC__ENCODER_FATAL_ERROR_WHILE_WRITING, /* that is, the write_callback returned an error */
        FLAC__ENCODER_MEMORY_ALLOCATION_ERROR
@@ -69,7 +70,8 @@ typedef struct {
        bool     do_exhaustive_model_search;  /* 0 => use estimated bits per residual for scoring, 1 => generate all, take shortest */
        unsigned rice_optimization_level;     /* 0 => estimate Rice parameter based on residual variance, 1-8 => partition residual, use parameter for each */
        uint64   total_samples_estimate;      /* may be 0 if unknown.  this will be a placeholder in the metadata block until the actual total is calculated */
-       unsigned padding;                     /* size of PADDING block to add; 0 => do not add a PADDING block */
+       const FLAC__StreamMetaData_SeekTable *seek_table; /* optional seek_table to prepend, 0 => no seek table */
+       unsigned padding;                     /* size of PADDING block to add (goes after seek table); 0 => do not add a PADDING block */
 } FLAC__Encoder;
 
 
index 3505fca..82623ac 100644 (file)
@@ -22,6 +22,7 @@
 #include <stdlib.h> /* for malloc() */
 #include <string.h> /* for memcpy() */
 #include "FLAC/encoder.h"
+#include "FLAC/seek_table.h"
 #include "private/bitbuffer.h"
 #include "private/bitmath.h"
 #include "private/crc.h"
@@ -265,6 +266,7 @@ FLAC__EncoderState FLAC__encoder_init(FLAC__Encoder *encoder, FLAC__EncoderWrite
 {
        unsigned i;
        FLAC__StreamMetaData padding;
+       FLAC__StreamMetaData seek_table;
 
        assert(sizeof(int) >= 4); /* we want to die right away if this is not true */
        assert(encoder != 0);
@@ -400,7 +402,7 @@ FLAC__EncoderState FLAC__encoder_init(FLAC__Encoder *encoder, FLAC__EncoderWrite
                return encoder->state = FLAC__ENCODER_FRAMING_ERROR;
 
        encoder->guts->metadata.type = FLAC__METADATA_TYPE_STREAMINFO;
-       encoder->guts->metadata.is_last = (encoder->padding == 0);
+       encoder->guts->metadata.is_last = (encoder->seek_table == 0 && encoder->padding == 0);
        encoder->guts->metadata.length = FLAC__STREAM_METADATA_STREAMINFO_LENGTH;
        encoder->guts->metadata.data.stream_info.min_blocksize = encoder->blocksize; /* this encoder uses the same blocksize for the whole stream */
        encoder->guts->metadata.data.stream_info.max_blocksize = encoder->blocksize;
@@ -415,6 +417,17 @@ FLAC__EncoderState FLAC__encoder_init(FLAC__Encoder *encoder, FLAC__EncoderWrite
        if(!FLAC__add_metadata_block(&encoder->guts->metadata, &encoder->guts->frame))
                return encoder->state = FLAC__ENCODER_FRAMING_ERROR;
 
+       if(0 != encoder->seek_table) {
+               if(!FLAC__seek_table_is_valid(encoder->seek_table))
+                       return encoder->state = FLAC__ENCODER_INVALID_SEEK_TABLE;
+               seek_table.type = FLAC__METADATA_TYPE_SEEKTABLE;
+               seek_table.is_last = (encoder->padding == 0);
+               seek_table.length = encoder->seek_table->num_points * FLAC__STREAM_METADATA_SEEKPOINT_LEN;
+               seek_table.data.seek_table = *encoder->seek_table;
+               if(!FLAC__add_metadata_block(&seek_table, &encoder->guts->frame))
+                       return encoder->state = FLAC__ENCODER_FRAMING_ERROR;
+       }
+
        /* add a PADDING block if requested */
        if(encoder->padding > 0) {
                padding.type = FLAC__METADATA_TYPE_PADDING;
index cf998a8..7390e89 100644 (file)
@@ -81,6 +81,16 @@ bool FLAC__add_metadata_block(const FLAC__StreamMetaData *metadata, FLAC__BitBuf
                        if(!FLAC__bitbuffer_write_zeroes(bb, metadata->length * 8))
                                return false;
                        break;
+               case FLAC__METADATA_TYPE_SEEKTABLE:
+                       for(i = 0; i < metadata->data.seek_table.num_points; i++) {
+                               if(!FLAC__bitbuffer_write_raw_uint64(bb, metadata->data.seek_table.points[i].sample_number, FLAC__STREAM_METADATA_SEEKPOINT_SAMPLE_NUMBER_LEN))
+                                       return false;
+                               if(!FLAC__bitbuffer_write_raw_uint64(bb, metadata->data.seek_table.points[i].stream_offset, FLAC__STREAM_METADATA_SEEKPOINT_STREAM_OFFSET_LEN))
+                                       return false;
+                               if(!FLAC__bitbuffer_write_raw_uint32(bb, metadata->data.seek_table.points[i].frame_samples, FLAC__STREAM_METADATA_SEEKPOINT_FRAME_SAMPLES_LEN))
+                                       return false;
+                       }
+                       break;
                default:
                        assert(0);
        }