write number of samples in FLAC extradata.

based on a patch by Mathieu Velten (matmaul gmail com).

Originally committed as revision 15324 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Justin Ruggles 2008-09-14 20:00:36 +00:00
parent 8588e1484e
commit e1a12934c5
2 changed files with 31 additions and 2 deletions

View File

@ -96,6 +96,7 @@ typedef struct FlacEncodeContext {
int sr_code[2]; int sr_code[2];
int max_framesize; int max_framesize;
uint32_t frame_count; uint32_t frame_count;
uint64_t sample_count;
FlacFrame frame; FlacFrame frame;
CompressionOptions options; CompressionOptions options;
AVCodecContext *avctx; AVCodecContext *avctx;
@ -134,8 +135,10 @@ static void write_streaminfo(FlacEncodeContext *s, uint8_t *header)
put_bits(&pb, 20, s->samplerate); put_bits(&pb, 20, s->samplerate);
put_bits(&pb, 3, s->channels-1); put_bits(&pb, 3, s->channels-1);
put_bits(&pb, 5, 15); /* bits per sample - 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); flush_put_bits(&pb);
/* total samples = 0 */
/* MD5 signature = 0 */ /* MD5 signature = 0 */
} }
@ -1251,6 +1254,12 @@ static int flac_encode_frame(AVCodecContext *avctx, uint8_t *frame,
return 0; 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); init_frame(s);
copy_samples(s, samples); copy_samples(s, samples);
@ -1284,6 +1293,8 @@ write_frame:
} }
s->frame_count++; s->frame_count++;
s->sample_count += avctx->frame_size;
return out_bytes; return out_bytes;
} }
@ -1304,7 +1315,7 @@ AVCodec flac_encoder = {
flac_encode_frame, flac_encode_frame,
flac_encode_close, flac_encode_close,
NULL, 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}, .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE},
.long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"), .long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"),
}; };

View File

@ -42,6 +42,23 @@ static int flac_write_header(struct AVFormatContext *s)
} }
return 0; 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 #endif
#ifdef CONFIG_ROQ_MUXER #ifdef CONFIG_ROQ_MUXER
@ -705,6 +722,7 @@ AVOutputFormat flac_muxer = {
CODEC_ID_NONE, CODEC_ID_NONE,
flac_write_header, flac_write_header,
raw_write_packet, raw_write_packet,
flac_write_trailer,
.flags= AVFMT_NOTIMESTAMPS, .flags= AVFMT_NOTIMESTAMPS,
}; };
#endif #endif