Merged 1595.

This commit is contained in:
Moritz Bunkus 2004-03-21 10:04:19 +00:00
parent 50ce6e08f8
commit a4abb1de79
2 changed files with 46 additions and 3 deletions

View File

@ -223,7 +223,7 @@ typedef struct __attribute__((__packed__)) real_audio_v4_props_t {
uint16_t version1; /* 4 or 5 */ uint16_t version1; /* 4 or 5 */
uint16_t unknown1; /* 00 00 */ uint16_t unknown1; /* 00 00 */
uint32_t fourcc2; /* .ra4 or .ra5 */ uint32_t fourcc2; /* .ra4 or .ra5 */
uint32_t unknown2; /* ??? */ uint32_t stream_length; /* ??? */
uint16_t version2; /* 4 or 5 */ uint16_t version2; /* 4 or 5 */
uint32_t header_size; /* == 0x4e */ uint32_t header_size; /* == 0x4e */
uint16_t flavor; /* codec flavor id */ uint16_t flavor; /* codec flavor id */
@ -246,7 +246,7 @@ typedef struct __attribute__((__packed__)) real_audio_v5_props_t {
uint16_t version1; /* 4 or 5 */ uint16_t version1; /* 4 or 5 */
uint16_t unknown1; /* 00 00 */ uint16_t unknown1; /* 00 00 */
uint32_t fourcc2; /* .ra4 or .ra5 */ uint32_t fourcc2; /* .ra4 or .ra5 */
uint32_t unknown2; /* ??? */ uint32_t stream_length; /* ??? */
uint16_t version2; /* 4 or 5 */ uint16_t version2; /* 4 or 5 */
uint32_t header_size; /* == 0x4e */ uint32_t header_size; /* == 0x4e */
uint16_t flavor; /* codec flavor id */ uint16_t flavor; /* codec flavor id */

View File

@ -41,6 +41,7 @@ typedef struct rmff_file_internal_t {
uint32_t data_contents_size; uint32_t data_contents_size;
uint32_t index_offset; uint32_t index_offset;
int num_index_chunks; int num_index_chunks;
uint32_t total_bytes;
} rmff_file_internal_t; } rmff_file_internal_t;
typedef struct rmff_track_internal_t { typedef struct rmff_track_internal_t {
@ -51,6 +52,9 @@ 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;
} rmff_track_internal_t; } rmff_track_internal_t;
int rmff_last_error = RMFF_ERR_OK; int rmff_last_error = RMFF_ERR_OK;
@ -358,6 +362,9 @@ open_file_for_writing(const char *path,
file->open_mode = RMFF_OPEN_MODE_WRITING; file->open_mode = RMFF_OPEN_MODE_WRITING;
file->internal = safecalloc(sizeof(rmff_file_internal_t)); file->internal = safecalloc(sizeof(rmff_file_internal_t));
/* save allowed & perfect play */
rmff_put_uint16_be(&file->prop_header.flags, 1 | 2);
clear_error(); clear_error();
return file; return file;
} }
@ -844,6 +851,17 @@ rmff_add_track(rmff_file_t *file,
void void
rmff_set_std_audio_v4_values(real_audio_v4_props_t *props) { rmff_set_std_audio_v4_values(real_audio_v4_props_t *props) {
if (props == NULL)
return;
memset(props, 0, sizeof(real_audio_v4_props_t));
rmff_put_uint32_be(&props->fourcc1, rmffFOURCC('.', 'r', 'a', 0xfd));
rmff_put_uint16_be(&props->version1, 4);
rmff_put_uint32_be(&props->fourcc2, rmffFOURCC('.', 'r', 'a', '4'));
rmff_put_uint32_be(&props->stream_length, 0x10000000);
rmff_put_uint16_be(&props->version2, 4);
rmff_put_uint16_be(&props->header_size, 0x4e);
} }
void void
@ -1085,6 +1103,10 @@ rmff_fix_headers(rmff_file_t *file) {
fint = (rmff_file_internal_t *)file->internal; fint = (rmff_file_internal_t *)file->internal;
if (fint->highest_timecode > 0)
fint->avg_bit_rate = (int64_t)fint->total_bytes * 8 * 1000 /
fint->highest_timecode;
prop = &file->prop_header; prop = &file->prop_header;
rmff_put_uint32_be(&prop->max_bit_rate, fint->max_bit_rate); rmff_put_uint32_be(&prop->max_bit_rate, fint->max_bit_rate);
rmff_put_uint32_be(&prop->avg_bit_rate, fint->avg_bit_rate); rmff_put_uint32_be(&prop->avg_bit_rate, fint->avg_bit_rate);
@ -1101,6 +1123,10 @@ rmff_fix_headers(rmff_file_t *file) {
mdpr = &track->mdpr_header; mdpr = &track->mdpr_header;
tint = (rmff_track_internal_t *)track->internal; tint = (rmff_track_internal_t *)track->internal;
if (tint->highest_timecode > 0)
tint->avg_bit_rate = (int64_t)tint->total_bytes * 8 * 1000 /
tint->highest_timecode;
rmff_put_uint16_be(&mdpr->id, track->id); rmff_put_uint16_be(&mdpr->id, track->id);
rmff_put_uint32_be(&mdpr->max_bit_rate, tint->max_bit_rate); rmff_put_uint32_be(&mdpr->max_bit_rate, tint->max_bit_rate);
rmff_put_uint32_be(&mdpr->avg_bit_rate, tint->avg_bit_rate); rmff_put_uint32_be(&mdpr->avg_bit_rate, tint->avg_bit_rate);
@ -1138,6 +1164,7 @@ rmff_write_frame(rmff_track_t *track,
rmff_file_internal_t *fint; rmff_file_internal_t *fint;
rmff_track_internal_t *tint; rmff_track_internal_t *tint;
int bw, wanted_len; int bw, wanted_len;
uint32_t bit_rate;
int64_t pos; int64_t pos;
if ((track == NULL) || (frame == NULL) || (frame->data == NULL) || if ((track == NULL) || (frame == NULL) || (frame->data == NULL) ||
@ -1165,12 +1192,12 @@ 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);
/* TODO: Update the max_bit_rate and avg_bit_rate. */
if (wanted_len > fint->max_packet_size) if (wanted_len > fint->max_packet_size)
fint->max_packet_size = wanted_len; fint->max_packet_size = wanted_len;
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); wanted_len) / (fint->num_packets + 1);
fint->num_packets++; fint->num_packets++;
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;
@ -1180,8 +1207,24 @@ rmff_write_frame(rmff_track_t *track,
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); wanted_len) / (tint->num_packets + 1);
tint->num_packets++; tint->num_packets++;
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 = (int64_t)tint->bytes_since_timecode_change * 8 * 1000 /
(frame->timecode - tint->last_timecode);
if (bit_rate > tint->max_bit_rate)
tint->max_bit_rate = bit_rate;
if (bit_rate > fint->max_bit_rate)
fint->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();
} }