1 /*
2 mkvmerge -- utility for splicing together matroska files
3 from component media subtypes
4
5 Distributed under the GPL v2
6 see the file COPYING for details
7 or visit https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
8
9 MPEG 4 part 10 ES video output module
10
11 Written by Moritz Bunkus <moritz@bunkus.org>.
12 */
13
14 #include "common/common_pch.h"
15
16 #include <matroska/KaxTracks.h>
17
18 #include "merge/generic_reader.h"
19 #include "merge/output_control.h"
20 #include "output/p_avc_hevc_es.h"
21
22 avc_hevc_es_video_packetizer_c::
avc_hevc_es_video_packetizer_c(generic_reader_c * p_reader,track_info_c & p_ti,std::string const & p_debug_type,std::unique_ptr<mtx::avc_hevc::es_parser_c> && parser_base)23 avc_hevc_es_video_packetizer_c(generic_reader_c *p_reader,
24 track_info_c &p_ti,
25 std::string const &p_debug_type,
26 std::unique_ptr<mtx::avc_hevc::es_parser_c> &&parser_base)
27 : generic_packetizer_c{p_reader, p_ti}
28 , m_parser_base{std::move(parser_base)}
29 , m_debug_timestamps{ fmt::format("{0}_es|{0}_es_timestamps", p_debug_type)}
30 , m_debug_aspect_ratio{fmt::format("{0}_es|{0}_es_aspect_ratio", p_debug_type)}
31 {
32 m_relaxed_timestamp_checking = true;
33
34 set_track_type(track_video);
35
36 // If no external timestamp file has been specified then mkvmerge
37 // might have created a factory due to the --default-duration
38 // command line argument. This factory must be disabled for the AVC
39 // packetizer because it takes care of handling the default
40 // duration/FPS itself.
41 if (m_ti.m_ext_timestamps.empty())
42 m_timestamp_factory.reset();
43
44 int64_t factory_default_duration;
45 if (m_timestamp_factory && (-1 != (factory_default_duration = m_timestamp_factory->get_default_duration(-1)))) {
46 set_track_default_duration(factory_default_duration);
47 m_parser_default_duration_to_force = factory_default_duration;
48 m_default_duration_forced = true;
49 mxdebug_if(m_debug_timestamps, fmt::format("Forcing default duration due to timestamp factory to {0}\n", m_htrack_default_duration));
50
51 } else if (m_default_duration_forced && (-1 != m_htrack_default_duration)) {
52 m_default_duration_for_interlaced_content = m_htrack_default_duration / 2;
53 m_parser_default_duration_to_force = m_default_duration_for_interlaced_content;
54 mxdebug_if(m_debug_timestamps, fmt::format("Forcing default duration due to --default-duration to {0}\n", m_htrack_default_duration));
55 }
56
57 m_parser_base->set_keep_ar_info(false);
58
59 if (m_parser_default_duration_to_force)
60 m_parser_base->force_default_duration(*m_parser_default_duration_to_force);
61 }
62
63 void
set_headers()64 avc_hevc_es_video_packetizer_c::set_headers() {
65 generic_packetizer_c::set_headers();
66
67 m_track_entry->EnableLacing(false);
68 }
69
70 void
set_container_default_field_duration(int64_t default_duration)71 avc_hevc_es_video_packetizer_c::set_container_default_field_duration(int64_t default_duration) {
72 m_parser_base->set_container_default_duration(default_duration);
73 }
74
75 unsigned int
get_nalu_size_length() const76 avc_hevc_es_video_packetizer_c::get_nalu_size_length()
77 const {
78 return m_parser_base->get_nalu_size_length();
79 }
80
81 void
add_extra_data(memory_cptr const & data)82 avc_hevc_es_video_packetizer_c::add_extra_data(memory_cptr const &data) {
83 m_parser_base->add_bytes(data->get_buffer(), data->get_size());
84 }
85
86 void
process_impl(packet_cptr const & packet)87 avc_hevc_es_video_packetizer_c::process_impl(packet_cptr const &packet) {
88 try {
89 if (packet->has_timestamp())
90 m_parser_base->add_timestamp(packet->timestamp);
91 m_parser_base->add_bytes(packet->data->get_buffer(), packet->data->get_size());
92 flush_frames();
93
94 } catch (mtx::exception &error) {
95 mxerror_tid(m_ti.m_fname, m_ti.m_id,
96 fmt::format("{0} {1}\n{2}\n",
97 Y("mkvmerge encountered broken or unparsable data in this video track."),
98 Y("The error message was:"),
99 error.error()));
100 }
101 }
102
103 void
flush_impl()104 avc_hevc_es_video_packetizer_c::flush_impl() {
105 m_parser_base->flush();
106 flush_frames();
107 }
108
109 void
flush_frames()110 avc_hevc_es_video_packetizer_c::flush_frames() {
111 while (m_parser_base->frame_available()) {
112 if (m_first_frame) {
113 handle_delayed_headers();
114 m_first_frame = false;
115 }
116
117 auto frame = m_parser_base->get_frame();
118 auto duration = frame.m_end > frame.m_start ? frame.m_end - frame.m_start : m_htrack_default_duration;
119 auto packet = std::make_shared<packet_t>(frame.m_data, frame.m_start, duration,
120 frame.is_key_frame() ? -1 : frame.m_start + frame.m_ref1,
121 !frame.is_b_frame() ? -1 : frame.m_start + frame.m_ref2);
122
123 packet->key_flag = frame.is_key_frame();
124 packet->discardable_flag = frame.is_discardable();
125
126 add_packet(packet);
127 }
128 }
129
130 void
check_if_default_duration_available() const131 avc_hevc_es_video_packetizer_c::check_if_default_duration_available()
132 const {
133 // No default implementation, but not required either.
134 }
135
136 void
handle_delayed_headers()137 avc_hevc_es_video_packetizer_c::handle_delayed_headers() {
138 if (0 < m_parser_base->get_num_skipped_frames())
139 mxwarn_tid(m_ti.m_fname, m_ti.m_id, fmt::format(Y("This AVC/H.264 track does not start with a key frame. The first {0} frames have been skipped.\n"), m_parser_base->get_num_skipped_frames()));
140
141 set_codec_private(m_parser_base->get_configuration_record());
142
143 check_if_default_duration_available();
144
145 handle_aspect_ratio();
146 handle_actual_default_duration();
147
148 rerender_track_headers();
149 }
150
151 void
handle_aspect_ratio()152 avc_hevc_es_video_packetizer_c::handle_aspect_ratio() {
153 mxdebug_if(m_debug_aspect_ratio, fmt::format("already set? {0} has par been found? {1}\n", display_dimensions_or_aspect_ratio_set(), m_parser_base->has_par_been_found()));
154
155 if (display_dimensions_or_aspect_ratio_set() || !m_parser_base->has_par_been_found())
156 return;
157
158 auto dimensions = m_parser_base->get_display_dimensions(m_hvideo_pixel_width, m_hvideo_pixel_height);
159 set_video_display_dimensions(dimensions.first, dimensions.second, generic_packetizer_c::ddu_pixels, OPTION_SOURCE_BITSTREAM);
160
161 mxinfo_tid(m_ti.m_fname, m_ti.m_id,
162 fmt::format(Y("Extracted the aspect ratio information from the video bitstream and set the display dimensions to {0}/{1}.\n"),
163 m_ti.m_display_width, m_ti.m_display_height));
164
165 mxdebug_if(m_debug_aspect_ratio,
166 fmt::format("PAR {0} pixel_width/hgith {1}/{2} display_width/height {3}/{4}\n",
167 m_parser_base->get_par(), m_hvideo_pixel_width, m_hvideo_pixel_height, m_ti.m_display_width, m_ti.m_display_height));
168 }
169
170 void
handle_actual_default_duration()171 avc_hevc_es_video_packetizer_c::handle_actual_default_duration() {
172 int64_t actual_default_duration = m_parser_base->get_most_often_used_duration();
173 mxdebug_if(m_debug_timestamps, fmt::format("Most often used duration: {0} forced? {1} current default duration: {2}\n", actual_default_duration, m_default_duration_forced, m_htrack_default_duration));
174
175 if ( !m_default_duration_forced
176 && (0 < actual_default_duration)
177 && (m_htrack_default_duration != actual_default_duration))
178 set_track_default_duration(actual_default_duration);
179
180 else if ( m_default_duration_forced
181 && (0 < m_default_duration_for_interlaced_content)
182 && (std::abs(actual_default_duration - m_default_duration_for_interlaced_content) <= 20000)) {
183 m_default_duration_forced = false;
184 set_track_default_duration(m_default_duration_for_interlaced_content);
185 }
186 }
187
188 void
connect(generic_packetizer_c * src,int64_t p_append_timestamp_offset)189 avc_hevc_es_video_packetizer_c::connect(generic_packetizer_c *src,
190 int64_t p_append_timestamp_offset) {
191 generic_packetizer_c::connect(src, p_append_timestamp_offset);
192
193 if (2 != m_connected_to)
194 return;
195
196 auto real_src = dynamic_cast<avc_hevc_es_video_packetizer_c *>(src);
197 assert(real_src);
198
199 m_htrack_default_duration = real_src->m_htrack_default_duration;
200 m_default_duration_forced = real_src->m_default_duration_forced;
201
202 if (m_default_duration_forced && (-1 != m_htrack_default_duration)) {
203 m_default_duration_for_interlaced_content = m_htrack_default_duration / 2;
204 m_parser_base->force_default_duration(m_default_duration_for_interlaced_content);
205 }
206 }
207