write number of samples in FLAC extradata.
authorJustin Ruggles <justin.ruggles@gmail.com>
Sun, 14 Sep 2008 20:00:36 +0000 (20:00 +0000)
committerJustin Ruggles <justin.ruggles@gmail.com>
Sun, 14 Sep 2008 20:00:36 +0000 (20:00 +0000)
based on a patch by Mathieu Velten (matmaul gmail com).

Originally committed as revision 15324 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/flacenc.c
libavformat/raw.c

index 1bba6f8..d1002f3 100644 (file)
@@ -96,6 +96,7 @@ typedef struct FlacEncodeContext {
     int sr_code[2];
     int max_framesize;
     uint32_t frame_count;
+    uint64_t sample_count;
     FlacFrame frame;
     CompressionOptions options;
     AVCodecContext *avctx;
@@ -134,8 +135,10 @@ static void write_streaminfo(FlacEncodeContext *s, uint8_t *header)
     put_bits(&pb, 20, s->samplerate);
     put_bits(&pb, 3, s->channels-1);
     put_bits(&pb, 5, 15);       /* bits per sample - 1 */
+    /* write 36-bit sample count in 2 put_bits() calls */
+    put_bits(&pb, 24, (s->sample_count & 0xFFFFFF000LL) >> 12);
+    put_bits(&pb, 12,  s->sample_count & 0x000000FFFLL);
     flush_put_bits(&pb);
-    /* total samples = 0 */
     /* MD5 signature = 0 */
 }
 
@@ -1251,6 +1254,12 @@ static int flac_encode_frame(AVCodecContext *avctx, uint8_t *frame,
         return 0;
     }
 
+    /* when the last block is reached, update the header in extradata */
+    if (!data) {
+        write_streaminfo(s, avctx->extradata);
+        return 0;
+    }
+
     init_frame(s);
 
     copy_samples(s, samples);
@@ -1284,6 +1293,8 @@ write_frame:
     }
 
     s->frame_count++;
+    s->sample_count += avctx->frame_size;
+
     return out_bytes;
 }
 
@@ -1304,7 +1315,7 @@ AVCodec flac_encoder = {
     flac_encode_frame,
     flac_encode_close,
     NULL,
-    .capabilities = CODEC_CAP_SMALL_LAST_FRAME,
+    .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY,
     .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE},
     .long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),
 };
index 05c93ac..65d13aa 100644 (file)
@@ -42,6 +42,23 @@ static int flac_write_header(struct AVFormatContext *s)
     }
     return 0;
 }
+
+static int flac_write_trailer(struct AVFormatContext *s)
+{
+    ByteIOContext *pb = s->pb;
+    uint8_t *streaminfo = s->streams[0]->codec->extradata;
+    int len = s->streams[0]->codec->extradata_size;
+    offset_t file_size;
+
+    if (streaminfo && len > 0 && !url_is_streamed(s->pb)) {
+        file_size = url_ftell(pb);
+        url_fseek(pb, 8, SEEK_SET);
+        put_buffer(pb, streaminfo, len);
+        url_fseek(pb, file_size, SEEK_SET);
+        put_flush_packet(pb);
+    }
+    return 0;
+}
 #endif
 
 #ifdef CONFIG_ROQ_MUXER
@@ -705,6 +722,7 @@ AVOutputFormat flac_muxer = {
     CODEC_ID_NONE,
     flac_write_header,
     raw_write_packet,
+    flac_write_trailer,
     .flags= AVFMT_NOTIMESTAMPS,
 };
 #endif