Better max_bit_rate and *_packet_size calculation.

This commit is contained in:
Moritz Bunkus 2004-03-22 19:22:24 +00:00
parent 050303ee7e
commit 8939870ee2

View File

@ -29,6 +29,12 @@
#include "librmff.h" #include "librmff.h"
typedef struct rmff_bitrate_t {
uint32_t *timecodes;
uint32_t *frame_sizes;
uint32_t num_entries;
} rmff_bitrate_t;
typedef struct rmff_file_internal_t { typedef struct rmff_file_internal_t {
uint32_t max_bit_rate; uint32_t max_bit_rate;
uint32_t avg_bit_rate; uint32_t avg_bit_rate;
@ -42,6 +48,7 @@ typedef struct rmff_file_internal_t {
uint32_t index_offset; uint32_t index_offset;
int num_index_chunks; int num_index_chunks;
uint32_t total_bytes; uint32_t total_bytes;
rmff_bitrate_t bitrate;
} rmff_file_internal_t; } rmff_file_internal_t;
typedef struct rmff_track_internal_t { typedef struct rmff_track_internal_t {
@ -52,9 +59,8 @@ typedef struct rmff_track_internal_t {
uint32_t highest_timecode; uint32_t highest_timecode;
uint32_t num_packets; uint32_t num_packets;
int index_this; int index_this;
uint32_t last_timecode;
uint32_t bytes_since_timecode_change;
uint32_t total_bytes; uint32_t total_bytes;
rmff_bitrate_t bitrate;
} rmff_track_internal_t; } rmff_track_internal_t;
int rmff_last_error = RMFF_ERR_OK; int rmff_last_error = RMFF_ERR_OK;
@ -1160,6 +1166,53 @@ rmff_copy_track_headers(rmff_track_t *dst,
dst->type = src->type; dst->type = src->type;
} }
static uint32_t
rmff_update_max_bitrate(rmff_bitrate_t *bitrate,
uint32_t timecode,
uint32_t frame_size) {
uint32_t i, max_bit_rate, total_size;
bitrate->timecodes = (uint32_t *)saferealloc(bitrate->timecodes,
(bitrate->num_entries + 1) *
sizeof(uint32_t));
bitrate->timecodes[bitrate->num_entries] = timecode;
bitrate->frame_sizes = (uint32_t *)saferealloc(bitrate->frame_sizes,
(bitrate->num_entries + 1) *
sizeof(uint32_t));
bitrate->frame_sizes[bitrate->num_entries] = frame_size;
bitrate->num_entries++;
if ((bitrate->timecodes[bitrate->num_entries - 1] -
bitrate->timecodes[0]) < 1000)
return 0;
total_size = 0;
for (i = 0; i < bitrate->num_entries; i++)
total_size += bitrate->frame_sizes[i];
max_bit_rate = (uint32_t)
((int64_t)total_size * 8 * 1000 /
(bitrate->timecodes[bitrate->num_entries - 1] -
bitrate->timecodes[0]));
i = 0;
while ((i < bitrate->num_entries) &&
((bitrate->timecodes[bitrate->num_entries - 1] -
bitrate->timecodes[i]) >= 1000))
i++;
memmove(&bitrate->timecodes[0], &bitrate->timecodes[i],
(bitrate->num_entries - i) * sizeof(uint32_t));
bitrate->timecodes = (uint32_t *)saferealloc(bitrate->timecodes,
(bitrate->num_entries - i) *
sizeof(uint32_t));
memmove(&bitrate->frame_sizes[0], &bitrate->frame_sizes[i],
(bitrate->num_entries - i) * sizeof(uint32_t));
bitrate->frame_sizes = (uint32_t *)saferealloc(bitrate->frame_sizes,
(bitrate->num_entries - i) *
sizeof(uint32_t));
bitrate->num_entries -= i;
return max_bit_rate;
}
int int
rmff_write_frame(rmff_track_t *track, rmff_write_frame(rmff_track_t *track,
rmff_frame_t *frame) { rmff_frame_t *frame) {
@ -1196,39 +1249,33 @@ rmff_write_frame(rmff_track_t *track,
if (bw != wanted_len) if (bw != wanted_len)
return set_error(RMFF_ERR_IO, "Could not write the frame", RMFF_ERR_IO); return set_error(RMFF_ERR_IO, "Could not write the frame", RMFF_ERR_IO);
if (wanted_len > fint->max_packet_size) if (frame->size > fint->max_packet_size)
fint->max_packet_size = wanted_len; fint->max_packet_size = frame->size;
fint->avg_packet_size = (fint->avg_packet_size * fint->num_packets + fint->avg_packet_size = (fint->avg_packet_size * fint->num_packets +
wanted_len) / (fint->num_packets + 1); frame->size) / (fint->num_packets + 1);
fint->num_packets++; fint->num_packets++;
fint->total_bytes += frame->size; fint->total_bytes += frame->size;
if (frame->timecode > fint->highest_timecode) if (frame->timecode > fint->highest_timecode)
fint->highest_timecode = frame->timecode; fint->highest_timecode = frame->timecode;
fint->data_contents_size += wanted_len; fint->data_contents_size += wanted_len;
if (wanted_len > tint->max_packet_size) if (frame->size > tint->max_packet_size)
tint->max_packet_size = wanted_len; tint->max_packet_size = frame->size;
tint->avg_packet_size = (tint->avg_packet_size * tint->num_packets + tint->avg_packet_size = (tint->avg_packet_size * tint->num_packets +
wanted_len) / (tint->num_packets + 1); frame->size) / (tint->num_packets + 1);
tint->num_packets++; tint->num_packets++;
tint->total_bytes += frame->size; tint->total_bytes += frame->size;
/* Update the max_bit_rates. Crude... */
if (frame->timecode > tint->highest_timecode) if (frame->timecode > tint->highest_timecode)
tint->highest_timecode = frame->timecode; tint->highest_timecode = frame->timecode;
if (frame->timecode != tint->last_timecode) {
if (tint->last_timecode != 0) { bit_rate = rmff_update_max_bitrate(&fint->bitrate, frame->timecode,
bit_rate = (int64_t)tint->bytes_since_timecode_change * 8 * 1000 / frame->size);
(frame->timecode - tint->last_timecode); if (bit_rate > fint->max_bit_rate)
if (bit_rate > tint->max_bit_rate) fint->max_bit_rate = bit_rate;
tint->max_bit_rate = bit_rate; bit_rate = rmff_update_max_bitrate(&tint->bitrate, frame->timecode,
if (bit_rate > fint->max_bit_rate) frame->size);
fint->max_bit_rate = bit_rate; if (bit_rate > tint->max_bit_rate)
} tint->max_bit_rate = bit_rate;
tint->last_timecode = frame->timecode;
tint->bytes_since_timecode_change = frame->size;
} else
tint->bytes_since_timecode_change += frame->size;
return clear_error(); return clear_error();
} }