diff --git a/ChangeLog b/ChangeLog index ee9786e0e..b61fd7826 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2006-12-28 Moritz Bunkus + + * mkvmerge: bug fix: Added a workaround for RealAudio tracks for + which the key frame flag is never set. + 2006-12-27 Moritz Bunkus * mmg: bug fix: Fixed a segfault that occured if the user had a diff --git a/src/input/r_real.cpp b/src/input/r_real.cpp index 6bae70970..619fb3808 100644 --- a/src/input/r_real.cpp +++ b/src/input/r_real.cpp @@ -212,6 +212,7 @@ real_reader_c::parse_headers() { real_demuxer_cptr dmx(new real_demuxer_t); dmx->track = track; dmx->ptzr = -1; + dmx->first_frame = true; if (track->type == RMFF_TRACK_TYPE_VIDEO) { dmx->rvp = (real_video_props_t *)track->mdpr_header.type_specific_data; @@ -419,6 +420,9 @@ real_reader_c::create_packetizer(int64_t tid) { dmx->ref_timecode = -1; } else { + if (!strcasecmp(dmx->fourcc, "COOK")) + dmx->cook_audio_fix = true; + ptzr = new ra_packetizer_c(this, dmx->samples_per_second, dmx->channels, dmx->bits_per_sample, (dmx->fourcc[0] << 24) | @@ -516,13 +520,26 @@ real_reader_c::read(generic_packetizer_c *, return FILE_STATUS_MOREDATA; } + if (dmx->cook_audio_fix && dmx->first_frame && + ((frame->flags & RMFF_FRAME_FLAG_KEYFRAME) != + RMFF_FRAME_FLAG_KEYFRAME)) + dmx->force_keyframe_flag = true; + + if (dmx->force_keyframe_flag && + ((frame->flags & RMFF_FRAME_FLAG_KEYFRAME) == + RMFF_FRAME_FLAG_KEYFRAME)) + dmx->force_keyframe_flag = false; + + if (dmx->force_keyframe_flag) + frame->flags |= RMFF_FRAME_FLAG_KEYFRAME; + if (dmx->track->type == RMFF_TRACK_TYPE_VIDEO) assemble_video_packet(dmx, frame); else if (dmx->is_aac) { // If the first AAC packet does not start at 0 then let the AAC // packetizer adjust its data accordingly. - if (dmx->ref_timecode == -1) { + if (dmx->first_frame) { dmx->ref_timecode = timecode; PTZR(dmx->ptzr)->set_displacement_maybe(timecode); } @@ -534,6 +551,8 @@ real_reader_c::read(generic_packetizer_c *, rmff_release_frame(frame); + dmx->first_frame = false; + return FILE_STATUS_MOREDATA; } @@ -589,7 +608,9 @@ real_reader_c::deliver_audio_frames(real_demuxer_cptr dmx, (uint32_t)segment->flags, duration); PTZR(dmx->ptzr)->process(new packet_t(segment->data, dmx->last_timecode, duration, - (segment->flags & 2) == 2 ? -1 : + (segment->flags & + RMFF_FRAME_FLAG_KEYFRAME) == + RMFF_FRAME_FLAG_KEYFRAME ? -1 : dmx->ref_timecode)); if ((segment->flags & 2) == 2) dmx->ref_timecode = dmx->last_timecode; diff --git a/src/input/r_real.h b/src/input/r_real.h index a0f36d0ce..8b76f2ffd 100644 --- a/src/input/r_real.h +++ b/src/input/r_real.h @@ -44,6 +44,8 @@ typedef struct { char fourcc[5]; bool is_aac; bool rv_dimensions; + bool force_keyframe_flag; + bool cook_audio_fix; float fps; real_video_props_t *rvp; @@ -53,6 +55,7 @@ typedef struct { unsigned char *private_data, *extra_data; int private_size, extra_data_size; + bool first_frame; int num_packets; int64_t last_timecode, ref_timecode; diff --git a/tests/results.txt b/tests/results.txt index ff2fc9c06..d0c493b4a 100644 --- a/tests/results.txt +++ b/tests/results.txt @@ -69,3 +69,4 @@ T_219srt_short_timecodes:a7db07ee64751fcc24993dd4af73ccf1:passed:20060926-112658 T_220ass_with_comments_at_start:51ccd0cbe4e60b21817d7547310250bb:passed:20060926-120101 T_221aac_lc_misdetected_as_sbr:6acabb7b6e1ac993c5b0d77f34e0d8f1:passed:20061103-174221 T_222stereo_mode:22eebd6bda7d848379044be8d9d8f440-38a1988c087c40e6e52025bb974f2c56-38a1988c087c40e6e52025bb974f2c56:passed:20061107-092251 +T_223ra_cook_keyframes:9586107c7cf22c7fe4e3a3513f8da68d:passed:20061228-150947 diff --git a/tests/test-223ra_cook_keyframes.rb b/tests/test-223ra_cook_keyframes.rb new file mode 100644 index 000000000..e9258060a --- /dev/null +++ b/tests/test-223ra_cook_keyframes.rb @@ -0,0 +1,13 @@ +#!/usr/bin/ruby -w + +class T_223ra_cook_keyframes < Test + def description + return "mkvmerge / RealAudio COOK with invalid key frame flags / in(RA)" + end + + def run + merge("data/rm/R2_petshopboys.ra") + return hash_tmp + end +end +