From 14d7db97edabe9cc1fd28aa38976bd8d0b3b5724 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Sun, 24 Feb 2013 13:33:16 +0100 Subject: [PATCH] PS input: improve video type detection for MPEG-1/2 vs. AVC/h.264 Fixes #845. --- ChangeLog | 3 ++ src/input/r_mpeg_ps.cpp | 34 ++++++++++++++----- tests/results.txt | 1 + .../test-389mpeg1_in_ps_misdetected_as_avc.rb | 5 +++ 4 files changed, 35 insertions(+), 8 deletions(-) create mode 100644 tests/test-389mpeg1_in_ps_misdetected_as_avc.rb diff --git a/ChangeLog b/ChangeLog index b480f47cd..ea5cab146 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2013-02-24 Moritz Bunkus + * mkvmerge: bug fix: Fixed mkvmerge sometimes mistakenly detecting + MPEG-1 video in MPEG program streams as AVC/h.264. Fixes #845. + * mmg: new feature: When a playlist file (e.g. MPLS Blu-ray playlist) is added mmg can optionally scan all the other files in the directory that have the same extension and present the user diff --git a/src/input/r_mpeg_ps.cpp b/src/input/r_mpeg_ps.cpp index 6ceb41d69..114d88466 100644 --- a/src/input/r_mpeg_ps.cpp +++ b/src/input/r_mpeg_ps.cpp @@ -487,6 +487,24 @@ mpeg_ps_reader_c::new_stream_v_avc_or_mpeg_1_2(mpeg_ps_id_t id, uint64_t marker = 0; int pos = 0; + while (4 > buffer.get_size()) { + if (!find_next_packet_for_id(id, PS_PROBE_SIZE)) + throw false; + + auto packet = parse_packet(id); + if (!packet) + continue; + + buffer.add(packet.m_buffer->get_buffer(), packet.m_length); + } + + marker = get_uint32_be(buffer.get_buffer()); + if (NALU_START_CODE == marker) { + m_in->restore_pos(); + new_stream_v_avc(id, buf, length, track); + return; + } + while (1) { unsigned char *ptr = buffer.get_buffer(); int buffer_size = buffer.get_size(); @@ -521,13 +539,6 @@ mpeg_ps_reader_c::new_stream_v_avc_or_mpeg_1_2(mpeg_ps_id_t id, avc_access_unit_found = true; break; } - - if (avc_seq_param_found && avc_pic_param_found && (avc_access_unit_found || avc_slice_found)) { - m_in->restore_pos(); - new_stream_v_avc(id, buf, length, track); - return; - } - } if (mpeg_is_start_code(marker)) { @@ -551,7 +562,7 @@ mpeg_ps_reader_c::new_stream_v_avc_or_mpeg_1_2(mpeg_ps_id_t id, } if (!find_next_packet_for_id(id, PS_PROBE_SIZE)) - throw false; + break; auto packet = parse_packet(id); if (!packet) @@ -559,6 +570,13 @@ mpeg_ps_reader_c::new_stream_v_avc_or_mpeg_1_2(mpeg_ps_id_t id, buffer.add(packet.m_buffer->get_buffer(), packet.m_length); } + + if (avc_seq_param_found && avc_pic_param_found && (avc_access_unit_found || avc_slice_found)) { + m_in->restore_pos(); + new_stream_v_avc(id, buf, length, track); + return; + } + } catch (...) { } diff --git a/tests/results.txt b/tests/results.txt index 2370e110d..faa8545a1 100644 --- a/tests/results.txt +++ b/tests/results.txt @@ -234,3 +234,4 @@ T_385split_parts_frames:14add8af7d016c048f0828708af04a86+c787a3d20fe2c26f7e0e031 T_386flv_vp6f:a0ab8eb0dedf2c8c472e818794c2ad64:passed:20130121-223417:0.187881106 T_387mp4_free_invalid_size:f3deb6abb3f60c0de606e166353a71b1:passed:20130216-003333:0.04107827 T_388split_parts_and_chapters:e1bc3ec155ec33bca8eec967aceab25a-389c3bd6f8eca14fea4ef663a59b2e83-04fa29b52eb8d4962edf4f010548b375:passed:20130216-203522:0.690018077 +T_389mpeg1_in_ps_misdetected_as_avc:31ba2275cda1531973423ad509013fdb:passed:20130224-132738:1.205560654 diff --git a/tests/test-389mpeg1_in_ps_misdetected_as_avc.rb b/tests/test-389mpeg1_in_ps_misdetected_as_avc.rb new file mode 100644 index 000000000..5e0af52f1 --- /dev/null +++ b/tests/test-389mpeg1_in_ps_misdetected_as_avc.rb @@ -0,0 +1,5 @@ +#!/usr/bin/ruby -w + +# T_389mpeg1_in_ps_misdetected_as_avc +describe "mkvmerge / MPEG-1 in program stream misdetected as AVC" +test_merge "data/mpeg12/mpeg1-misdetected-as-avc.mpg"