MPEG 1/2 packetizer: use rationals for calculation of aspect ratio

This commit is contained in:
Moritz Bunkus 2021-07-06 09:52:13 +02:00
parent e74c054d7c
commit 28bcaf876c
No known key found for this signature in database
GPG Key ID: 74AF00ADF2E32C85
3 changed files with 19 additions and 27 deletions

View File

@ -75,17 +75,16 @@ extract_fps_idx(unsigned char const *buffer,
\return \c true if a MPEG sequence header was found and \c false otherwise.
*/
bool
extract_ar(unsigned char const *buffer,
int buffer_size,
double &ar) {
std::optional<mtx_mp_rational_t>
extract_aspect_ratio(unsigned char const *buffer,
int buffer_size) {
uint32_t marker;
int idx;
mxdebug_if(s_debug, fmt::format("mpeg_video_ar: start search in {0} bytes\n", buffer_size));
if (buffer_size < 8) {
mxdebug_if(s_debug, "mpeg_video_ar: sequence header too small\n");
return false;
return {};
}
marker = get_uint32_be(buffer);
idx = 4;
@ -96,33 +95,24 @@ extract_ar(unsigned char const *buffer,
}
if (idx >= buffer_size) {
mxdebug_if(s_debug, "mpeg_video_ar: no sequence header start code found\n");
return false;
return {};
}
mxdebug_if(s_debug, fmt::format("mpeg_video_ar: found sequence header start code at {0}\n", idx - 4));
idx += 3; // width and height
if (idx >= buffer_size) {
mxdebug_if(s_debug, "mpeg_video_ar: sequence header too small\n");
return false;
return {};
}
switch (buffer[idx] & 0xf0) {
case AR_1_1:
ar = 1.0;
break;
case AR_4_3:
ar = 4.0 / 3.0;
break;
case AR_16_9:
ar = 16.0 / 9.0;
break;
case AR_2_21:
ar = 2.21;
break;
default:
ar = -1.0;
case AR_1_1: return mtx::rational(1, 1);
case AR_4_3: return mtx::rational(4, 3);
case AR_16_9: return mtx::rational(16, 9);
case AR_2_21: return mtx::rational(221, 100);
}
return true;
return {};
}
/** \brief Get the number of frames per second

View File

@ -16,6 +16,8 @@
#include "common/common_pch.h"
#include "common/math_fwd.h"
namespace mtx::mpeg1_2 {
// MPEG-1/-2 video start codes
@ -65,7 +67,7 @@ constexpr auto FOURCC_MPEG2 = 0x10000002u;
int extract_fps_idx(const unsigned char *buffer, int buffer_size);
double get_fps(int idx);
bool extract_ar(const unsigned char *buffer, int buffer_size, double &ar);
std::optional<mtx_mp_rational_t> extract_aspect_ratio(const unsigned char *buffer, int buffer_size);
bool is_fourcc(uint32_t fourcc);
}

View File

@ -271,15 +271,15 @@ mpeg1_2_video_packetizer_c::extract_fps(const unsigned char *buffer,
void
mpeg1_2_video_packetizer_c::extract_aspect_ratio(const unsigned char *buffer,
int size) {
double ar;
if (display_dimensions_or_aspect_ratio_set())
return;
if (!mtx::mpeg1_2::extract_ar(buffer, size, ar))
auto aspect_ratio = mtx::mpeg1_2::extract_aspect_ratio(buffer, size);
if (!aspect_ratio)
return;
set_video_display_dimensions((0 >= ar) || (1 == ar) ? m_width : (int)(m_height * ar), m_height, generic_packetizer_c::ddu_pixels, OPTION_SOURCE_BITSTREAM);
set_video_display_dimensions(1 == *aspect_ratio ? m_width : mtx::to_int(m_height * *aspect_ratio), m_height, generic_packetizer_c::ddu_pixels, OPTION_SOURCE_BITSTREAM);
rerender_track_headers();
m_aspect_ratio_extracted = true;