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