1 /** MPEG video helper functions (MPEG 1, 2 and 4)
2
3 mkvmerge -- utility for splicing together matroska files
4 from component media subtypes
5
6 Distributed under the GPL v2
7 see the file COPYING for details
8 or visit https://www.gnu.org/licenses/old-licenses/gpl-2.0.html
9
10 \file
11
12 \author Written by Moritz Bunkus <moritz@bunkus.org>.
13 */
14
15 #include "common/common_pch.h"
16
17 #include "common/bit_reader.h"
18 #include "common/debugging.h"
19 #include "common/endian.h"
20 #include "common/memory_slice_cursor.h"
21 #include "common/strings/formatting.h"
22 #include "common/vc1.h"
23
24 namespace mtx::vc1 {
25
26 namespace {
27 debugging_option_c s_debug{"vc1"};
28 }
29
sequence_header_t()30 sequence_header_t::sequence_header_t() {
31 memset(this, 0, sizeof(sequence_header_t));
32 }
33
entrypoint_t()34 entrypoint_t::entrypoint_t() {
35 memset(this, 0, sizeof(entrypoint_t));
36 }
37
frame_header_t()38 frame_header_t::frame_header_t() {
39 init();
40 }
41
42 void
init()43 frame_header_t::init() {
44 memset(this, 0, sizeof(frame_header_t));
45 }
46
frame_t(frame_header_t const & p_header)47 frame_t::frame_t(frame_header_t const &p_header)
48 : header{p_header}
49 {
50 init();
51 }
52
53 void
init()54 frame_t::init() {
55 data.reset();
56 timestamp = -1;
57 duration = 0;
58 contains_field = false;
59 contains_entry_point = false;
60 }
61
62 bool
is_key() const63 frame_t::is_key()
64 const {
65 return contains_entry_point || (header.frame_type == FRAME_TYPE_I);
66 }
67
68 bool
parse_sequence_header(const unsigned char * buf,int size,sequence_header_t & seqhdr)69 parse_sequence_header(const unsigned char *buf,
70 int size,
71 sequence_header_t &seqhdr) {
72 try {
73 static const struct { int n, d; } s_aspect_ratios[13] = {
74 { 1, 1 },
75 { 12, 11 },
76 { 10, 11 },
77 { 16, 11 },
78 { 40, 33 },
79 { 24, 11 },
80 { 20, 11 },
81 { 32, 11 },
82 { 80, 33 },
83 { 18, 11 },
84 { 15, 11 },
85 { 64, 33 },
86 { 160, 99 }
87 };
88
89 static const int s_framerate_nr[5] = { 24, 25, 30, 50, 60 };
90 static const int s_framerate_dr[2] = { 1000, 1001 };
91
92 mtx::bits::reader_c bc(buf, size);
93 sequence_header_t hdr;
94
95 bc.skip_bits(32); // Marker
96 hdr.profile = bc.get_bits(2);
97
98 if (PROFILE_ADVANCED != hdr.profile)
99 return false;
100
101 hdr.level = bc.get_bits(3);
102 hdr.chroma_format = bc.get_bits(2);
103 hdr.frame_rtq_postproc = bc.get_bits(3);
104 hdr.bit_rtq_postproc = bc.get_bits(5);
105 hdr.postproc_flag = bc.get_bit();
106 hdr.pixel_width = (bc.get_bits(12) + 1) << 1;
107 hdr.pixel_height = (bc.get_bits(12) + 1) << 1;
108 hdr.pulldown_flag = bc.get_bit();
109 hdr.interlace_flag = bc.get_bit();
110 hdr.tf_counter_flag = bc.get_bit();
111 hdr.f_inter_p_flag = bc.get_bit();
112 bc.skip_bits(1); // reserved
113 hdr.psf_mode_flag = bc.get_bit();
114 hdr.display_info_flag = bc.get_bit();
115
116 if (hdr.display_info_flag) {
117 hdr.display_width = bc.get_bits(14) + 1;
118 hdr.display_height = bc.get_bits(14) + 1;
119 hdr.aspect_ratio_flag = bc.get_bit();
120
121 if (hdr.aspect_ratio_flag) {
122 int aspect_ratio_idx = bc.get_bits(4);
123
124 if ((0 < aspect_ratio_idx) && (14 > aspect_ratio_idx)) {
125 hdr.aspect_ratio_width = s_aspect_ratios[aspect_ratio_idx - 1].n;
126 hdr.aspect_ratio_height = s_aspect_ratios[aspect_ratio_idx - 1].d;
127
128 } else if (15 == aspect_ratio_idx) {
129 hdr.aspect_ratio_width = bc.get_bits(8);
130 hdr.aspect_ratio_height = bc.get_bits(8);
131
132 if ((0 == hdr.aspect_ratio_width) || (0 == hdr.aspect_ratio_height))
133 hdr.aspect_ratio_flag = false;
134
135 } else
136 hdr.aspect_ratio_flag = false;
137 }
138
139 hdr.framerate_flag = bc.get_bit();
140 if (hdr.framerate_flag) {
141 if (bc.get_bit()) {
142 hdr.framerate_num = 32;
143 hdr.framerate_den = bc.get_bits(16) + 1;
144
145 } else {
146 int nr = bc.get_bits(8);
147 int dr = bc.get_bits(4);
148
149 if ((0 != nr) && (8 > nr) && (0 != dr) && (3 > dr)) {
150 hdr.framerate_num = s_framerate_dr[dr - 1];
151 hdr.framerate_den = s_framerate_nr[nr - 1] * 1000;
152
153 } else
154 hdr.framerate_flag = false;
155 }
156 }
157
158 if (bc.get_bit()) {
159 hdr.color_prim = bc.get_bits(8);
160 hdr.transfer_char = bc.get_bits(8);
161 hdr.matrix_coef = bc.get_bits(8);
162 }
163 }
164
165 hdr.hrd_param_flag = bc.get_bit();
166 if (hdr.hrd_param_flag) {
167 hdr.hrd_num_leaky_buckets = bc.get_bits(5);
168 bc.skip_bits(4 + 4); // bitrate exponent, buffer size exponent
169 bc.skip_bits(hdr.hrd_num_leaky_buckets * (16 + 16)); // hrd_rate, hrd_buffer
170 }
171
172 memcpy(&seqhdr, &hdr, sizeof(sequence_header_t));
173
174 return true;
175 } catch (...) {
176 return false;
177 }
178 }
179
180 bool
parse_entrypoint(const unsigned char * buf,int size,entrypoint_t & entrypoint,sequence_header_t & seqhdr)181 parse_entrypoint(const unsigned char *buf,
182 int size,
183 entrypoint_t &entrypoint,
184 sequence_header_t &seqhdr) {
185 try {
186 mtx::bits::reader_c bc(buf, size);
187 entrypoint_t ep;
188
189 bc.skip_bits(32); // marker
190 ep.broken_link_flag = bc.get_bit();
191 ep.closed_entry_flag = bc.get_bit();
192 ep.pan_scan_flag = bc.get_bit();
193 ep.refdist_flag = bc.get_bit();
194 ep.loop_filter_flag = bc.get_bit();
195 ep.fast_uvmc_flag = bc.get_bit();
196 ep.extended_mv_flag = bc.get_bit();
197 ep.dquant = bc.get_bits(2);
198 ep.vs_transform_flag = bc.get_bit();
199 ep.overlap_flag = bc.get_bit();
200 ep.quantizer_mode = bc.get_bits(2);
201
202 if (seqhdr.hrd_param_flag)
203 bc.skip_bits(seqhdr.hrd_num_leaky_buckets * 8);
204
205 ep.coded_dimensions_flag = bc.get_bit();
206 if (ep.coded_dimensions_flag) {
207 ep.coded_width = (bc.get_bits(12) + 1) << 1;
208 ep.coded_height = (bc.get_bits(12) + 1) << 1;
209 }
210
211 if (ep.extended_mv_flag)
212 ep.extended_dmv_flag = bc.get_bit();
213
214 ep.luma_scaling_flag = bc.get_bit();
215 if (ep.luma_scaling_flag)
216 ep.luma_scaling = bc.get_bits(3);
217
218 ep.chroma_scaling_flag = bc.get_bit();
219 if (ep.chroma_scaling_flag)
220 ep.chroma_scaling = bc.get_bits(3);
221
222 memcpy(&entrypoint, &ep, sizeof(entrypoint_t));
223
224 return true;
225 } catch (...) {
226 return false;
227 }
228 }
229
230 bool
parse_frame_header(const unsigned char * buf,int size,frame_header_t & frame_header,sequence_header_t & seqhdr)231 parse_frame_header(const unsigned char *buf,
232 int size,
233 frame_header_t &frame_header,
234 sequence_header_t &seqhdr) {
235 try {
236 mtx::bits::reader_c bc(buf, size);
237 frame_header_t fh;
238
239 bc.skip_bits(32); // marker
240
241 auto field_mode = false;
242
243 if (seqhdr.interlace_flag) {
244 fh.fcm = bc.get_012();
245 field_mode = fh.fcm == FCM_ILACE_FIELD;
246 }
247
248 if (field_mode) {
249 // Only set frame type to I for actual I/I fields. This is only
250 // used for key frame determination, so gloss over the actual
251 // field type differences.
252 auto type = bc.get_bits(3);
253 fh.frame_type = 0 == type ? FRAME_TYPE_I : FRAME_TYPE_P;
254
255 } else {
256 auto type = bc.get_unary(false, 4);
257 if (type >= 4) {
258 fh.frame_type = FRAME_TYPE_P_SKIPPED;
259 memcpy(&frame_header, &fh, sizeof(frame_header_t));
260
261 return true;
262 }
263
264 static frame_type_e s_type_map[4] = { FRAME_TYPE_P, FRAME_TYPE_B, FRAME_TYPE_I, FRAME_TYPE_BI };
265 fh.frame_type = s_type_map[type];
266 }
267
268 if (seqhdr.tf_counter_flag)
269 fh.tf_counter = bc.get_bits(8);
270
271 if (seqhdr.pulldown_flag) {
272 if (!seqhdr.interlace_flag || seqhdr.psf_mode_flag)
273 fh.repeat_frame = bc.get_bits(2);
274 else {
275 fh.top_field_first_flag = bc.get_bit();
276 fh.repeat_first_field_flag = bc.get_bit();
277 }
278 }
279
280 memcpy(&frame_header, &fh, sizeof(frame_header_t));
281
282 return true;
283 } catch (...) {
284 return false;
285 }
286 }
287
288 //
289 // -------------------------------------------------
290 //
291
es_parser_c()292 es_parser_c::es_parser_c()
293 : m_stream_pos(0)
294 , m_seqhdr_found(false)
295 , m_seqhdr_changed{false}
296 , m_previous_timestamp(0)
297 , m_num_timestamps(0)
298 , m_num_repeated_fields(0)
299 , m_default_duration_forced(false)
300 , m_default_duration(1000000000ll / 25)
301 {
302 }
303
304 void
add_bytes(unsigned char * buffer,int size)305 es_parser_c::add_bytes(unsigned char *buffer,
306 int size) {
307 mtx::mem::slice_cursor_c cursor;
308
309 int previous_pos = -1;
310 int64_t previous_stream_pos = m_stream_pos;
311
312 if (m_unparsed_buffer && (0 != m_unparsed_buffer->get_size()))
313 cursor.add_slice(m_unparsed_buffer);
314 cursor.add_slice(buffer, size);
315
316 if (3 <= cursor.get_remaining_size()) {
317 uint32_t marker = (1 << 24) | ((unsigned int)cursor.get_char() << 16) | ((unsigned int)cursor.get_char() << 8) | (unsigned int)cursor.get_char();
318
319 while (true) {
320 if (is_marker(marker)) {
321 if (-1 != previous_pos) {
322 int new_size = cursor.get_position() - 4 - previous_pos;
323
324 memory_cptr packet(memory_c::alloc(new_size));
325 cursor.copy(packet->get_buffer(), previous_pos, new_size);
326
327 handle_packet(packet);
328 }
329
330 previous_pos = cursor.get_position() - 4;
331 m_stream_pos = previous_stream_pos + previous_pos;
332 }
333
334 if (!cursor.char_available())
335 break;
336
337 marker <<= 8;
338 marker |= (unsigned int)cursor.get_char();
339 }
340 }
341
342 if (-1 == previous_pos)
343 previous_pos = 0;
344
345 int new_size = cursor.get_size() - previous_pos;
346 if (0 != new_size) {
347 memory_cptr new_unparsed_buffer = memory_c::alloc(new_size);
348 cursor.copy(new_unparsed_buffer->get_buffer(), previous_pos, new_size);
349 m_unparsed_buffer = new_unparsed_buffer;
350
351 } else
352 m_unparsed_buffer.reset();
353 }
354
355 void
flush()356 es_parser_c::flush() {
357 if (m_unparsed_buffer && (4 <= m_unparsed_buffer->get_size())) {
358 uint32_t marker = get_uint32_be(m_unparsed_buffer->get_buffer());
359 if (is_marker(marker))
360 handle_packet(memory_c::clone(m_unparsed_buffer->get_buffer(), m_unparsed_buffer->get_size()));
361 }
362
363 m_unparsed_buffer.reset();
364
365 flush_frame();
366 }
367
368 void
handle_packet(memory_cptr packet)369 es_parser_c::handle_packet(memory_cptr packet) {
370 uint32_t marker = get_uint32_be(packet->get_buffer());
371
372 switch (marker) {
373 case MARKER_SEQHDR:
374 handle_sequence_header_packet(packet);
375 break;
376
377 case MARKER_ENTRYPOINT:
378 handle_entrypoint_packet(packet);
379 break;
380
381 case MARKER_FRAME:
382 handle_frame_packet(packet);
383 break;
384
385 case MARKER_SLICE:
386 handle_slice_packet(packet);
387 break;
388
389 case MARKER_FIELD:
390 handle_field_packet(packet);
391 break;
392
393 case MARKER_ENDOFSEQ:
394 handle_end_of_sequence_packet(packet);
395 break;
396
397 default:
398 handle_unknown_packet(marker, packet);
399 break;
400 }
401 }
402
403 void
handle_end_of_sequence_packet(memory_cptr)404 es_parser_c::handle_end_of_sequence_packet(memory_cptr) {
405 }
406
407 void
handle_entrypoint_packet(memory_cptr packet)408 es_parser_c::handle_entrypoint_packet(memory_cptr packet) {
409 if (!postpone_processing(packet))
410 add_pre_frame_extra_data(packet);
411
412 if (!m_raw_entrypoint)
413 m_raw_entrypoint = memory_cptr(packet->clone());
414 }
415
416 void
handle_field_packet(memory_cptr packet)417 es_parser_c::handle_field_packet(memory_cptr packet) {
418 if (postpone_processing(packet))
419 return;
420
421 add_post_frame_extra_data(packet);
422 }
423
424 void
handle_frame_packet(memory_cptr packet)425 es_parser_c::handle_frame_packet(memory_cptr packet) {
426 if (postpone_processing(packet))
427 return;
428
429 flush_frame();
430
431 frame_header_t frame_header;
432 if (!parse_frame_header(packet->get_buffer(), packet->get_size(), frame_header, m_seqhdr))
433 return;
434
435 m_current_frame = std::make_shared<frame_t>(frame_header);
436 m_current_frame->data = packet;
437 m_current_frame->data->take_ownership();
438
439 if (!m_timestamps.empty())
440 mxdebug_if(s_debug, fmt::format("es_parser_c::handle_frame_packet: next provided timestamp {0} next calculated timestamp {1}\n", mtx::string::format_timestamp(m_timestamps.front()), mtx::string::format_timestamp(peek_next_calculated_timestamp())));
441
442 }
443
444 void
handle_sequence_header_packet(memory_cptr packet)445 es_parser_c::handle_sequence_header_packet(memory_cptr packet) {
446 flush_frame();
447
448 add_pre_frame_extra_data(packet);
449
450 sequence_header_t seqhdr;
451 if (!parse_sequence_header(packet->get_buffer(), packet->get_size(), seqhdr))
452 return;
453
454 m_seqhdr_changed = !m_seqhdr_found || (packet->get_size() != m_raw_seqhdr->get_size()) || memcmp(packet->get_buffer(), m_raw_seqhdr->get_buffer(), packet->get_size());
455
456 memcpy(&m_seqhdr, &seqhdr, sizeof(sequence_header_t));
457 m_raw_seqhdr = memory_cptr(packet->clone());
458 m_seqhdr_found = true;
459
460 if (!m_default_duration_forced && m_seqhdr.framerate_flag && (0 != m_seqhdr.framerate_num) && (0 != m_seqhdr.framerate_den))
461 m_default_duration = 1000000000ll * m_seqhdr.framerate_num / m_seqhdr.framerate_den;
462
463 process_unparsed_packets();
464 }
465
466 void
handle_slice_packet(memory_cptr packet)467 es_parser_c::handle_slice_packet(memory_cptr packet) {
468 if (postpone_processing(packet))
469 return;
470
471 add_post_frame_extra_data(packet);
472 }
473
474 void
handle_unknown_packet(uint32_t,memory_cptr packet)475 es_parser_c::handle_unknown_packet(uint32_t,
476 memory_cptr packet) {
477 if (postpone_processing(packet))
478 return;
479
480 add_post_frame_extra_data(packet);
481 }
482
483 void
flush_frame()484 es_parser_c::flush_frame() {
485 if (!m_current_frame)
486 return;
487
488 if (!m_pre_frame_extra_data.empty() || !m_post_frame_extra_data.empty())
489 combine_extra_data_with_packet();
490
491 m_current_frame->timestamp = get_next_timestamp();
492 m_current_frame->duration = get_default_duration();
493
494 m_frames.push_back(m_current_frame);
495
496 m_current_frame.reset();
497 }
498
499 bool
postpone_processing(memory_cptr & packet)500 es_parser_c::postpone_processing(memory_cptr &packet) {
501 if (m_seqhdr_found)
502 return false;
503
504 packet->take_ownership();
505 m_unparsed_packets.push_back(packet);
506 return true;
507 }
508
509 void
process_unparsed_packets()510 es_parser_c::process_unparsed_packets() {
511 for (auto &packet : m_unparsed_packets)
512 handle_frame_packet(packet);
513
514 m_unparsed_packets.clear();
515 }
516
517 void
combine_extra_data_with_packet()518 es_parser_c::combine_extra_data_with_packet() {
519 auto sum_fn = [](size_t size, const memory_cptr &buffer) { return size + buffer->get_size(); };
520 auto extra_size = std::accumulate(m_pre_frame_extra_data.begin(), m_pre_frame_extra_data.end(), 0, sum_fn) + std::accumulate(m_post_frame_extra_data.begin(), m_post_frame_extra_data.end(), 0, sum_fn);
521
522 auto new_packet = memory_c::alloc(extra_size + m_current_frame->data->get_size());
523 auto ptr = new_packet->get_buffer();
524
525 for (const auto &mem : m_pre_frame_extra_data) {
526 memcpy(ptr, mem->get_buffer(), mem->get_size());
527 ptr += mem->get_size();
528
529 if (get_uint32_be(mem->get_buffer()) == MARKER_ENTRYPOINT)
530 m_current_frame->contains_entry_point = true;
531 }
532
533 memcpy(ptr, m_current_frame->data->get_buffer(), m_current_frame->data->get_size());
534 ptr += m_current_frame->data->get_size();
535
536 for (const auto &mem : m_post_frame_extra_data) {
537 memcpy(ptr, mem->get_buffer(), mem->get_size());
538 ptr += mem->get_size();
539
540 if (MARKER_FIELD == get_uint32_be(mem->get_buffer()))
541 m_current_frame->contains_field = true;
542 }
543
544 m_pre_frame_extra_data.clear();
545 m_post_frame_extra_data.clear();
546
547 m_current_frame->data = new_packet;
548 }
549
550 int64_t
get_next_timestamp()551 es_parser_c::get_next_timestamp() {
552 int64_t next_timestamp = m_previous_timestamp
553 + (m_num_timestamps + m_num_repeated_fields) * m_default_duration
554 - m_num_repeated_fields * m_default_duration / 2;
555
556 if (is_timestamp_available()) {
557 mxdebug_if(s_debug, fmt::format("\nes_parser_c::get_next_timestamp(): provided timestamp available; original next {0}, provided {1}\n", mtx::string::format_timestamp(next_timestamp), mtx::string::format_timestamp(m_timestamps.front())));
558
559 next_timestamp = m_timestamps.front();
560 m_previous_timestamp = m_timestamps.front();
561 m_num_timestamps = 0;
562 m_num_repeated_fields = 0;
563
564 m_timestamps.pop_front();
565 m_timestamp_positions.pop_front();
566 }
567
568 m_num_timestamps += 1 + m_current_frame->header.repeat_frame;
569 if (m_seqhdr.interlace_flag && m_current_frame->header.repeat_first_field_flag && !m_current_frame->contains_field)
570 ++m_num_repeated_fields;
571
572 return next_timestamp;
573 }
574
575 int64_t
peek_next_calculated_timestamp() const576 es_parser_c::peek_next_calculated_timestamp()
577 const {
578 return m_previous_timestamp
579 + (m_num_timestamps + m_num_repeated_fields) * m_default_duration
580 - m_num_repeated_fields * m_default_duration / 2;
581 }
582
583 void
add_pre_frame_extra_data(memory_cptr packet)584 es_parser_c::add_pre_frame_extra_data(memory_cptr packet) {
585 add_extra_data_if_not_present(m_pre_frame_extra_data, packet);
586 }
587
588 void
add_post_frame_extra_data(memory_cptr packet)589 es_parser_c::add_post_frame_extra_data(memory_cptr packet) {
590 add_extra_data_if_not_present(m_post_frame_extra_data, packet);
591 }
592
593 void
add_extra_data_if_not_present(std::deque<memory_cptr> & extra_data,memory_cptr const & packet)594 es_parser_c::add_extra_data_if_not_present(std::deque<memory_cptr> &extra_data,
595 memory_cptr const &packet) {
596 for (auto const &existing_packet : extra_data)
597 if (*existing_packet == *packet)
598 return;
599
600 extra_data.push_back(packet->clone());
601 }
602
603 void
add_timestamp(int64_t timestamp,int64_t position)604 es_parser_c::add_timestamp(int64_t timestamp,
605 int64_t position) {
606 position += m_stream_pos;
607 if (m_unparsed_buffer)
608 position += m_unparsed_buffer->get_size();
609
610 m_timestamps.push_back(timestamp);
611 m_timestamp_positions.push_back(position);
612 }
613
614 bool
is_timestamp_available() const615 es_parser_c::is_timestamp_available()
616 const {
617 return !m_timestamps.empty() && (m_timestamp_positions.front() <= m_stream_pos);
618 }
619
620 }
621