mirror of
https://gitlab.com/mbunkus/mkvtoolnix.git
synced 2024-12-24 11:54:01 +00:00
Extract the aspect ratio information from MPEG4 streams and set the display dimensions accordingly.
This commit is contained in:
parent
7a51e41c67
commit
f2c3c75ab0
@ -1,3 +1,10 @@
|
||||
2004-03-27 Moritz Bunkus <moritz@bunkus.org>
|
||||
|
||||
* mkvmerge: new feature: If using MPEG4 video and no aspect
|
||||
ratio or display dimensions are given mkvmerge will extract the
|
||||
aspect ratio information from the stream and automatically set the
|
||||
display dimensions accordingly.
|
||||
|
||||
2004-03-22 Moritz Bunkus <moritz@bunkus.org>
|
||||
|
||||
* mkvmerge: bug fix: Using audio sync on AC3 tracks read from
|
||||
|
@ -60,6 +60,7 @@ video_packetizer_c::video_packetizer_c(generic_reader_c *nreader,
|
||||
duration_shift = 0;
|
||||
bref_frame.type = '?';
|
||||
fref_frame.type = '?';
|
||||
aspect_ratio_extracted = false;
|
||||
|
||||
set_track_type(track_video);
|
||||
}
|
||||
@ -198,6 +199,9 @@ video_packetizer_c::process(memory_c &mem,
|
||||
return EMOREDATA;
|
||||
}
|
||||
|
||||
if (is_mpeg4 && !aspect_ratio_extracted)
|
||||
extract_mpeg4_aspect_ratio(mem);
|
||||
|
||||
if (old_timecode == -1)
|
||||
timecode = (int64_t)(1000000000.0 * frames_output / fps) + duration_shift;
|
||||
else
|
||||
@ -243,6 +247,76 @@ video_packetizer_c::flush() {
|
||||
flush_frames(true);
|
||||
}
|
||||
|
||||
void
|
||||
video_packetizer_c::extract_mpeg4_aspect_ratio(memory_c &mem) {
|
||||
const uint32_t ar_nums[16] = {0, 1, 12, 10, 16, 40, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0};
|
||||
const uint32_t ar_dens[16] = {1, 1, 11, 11, 11, 33, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1};
|
||||
uint32_t marker, aspect_ratio_info, num, den;
|
||||
bool b;
|
||||
bit_cursor_c bits(mem.data, mem.size);
|
||||
|
||||
aspect_ratio_extracted = true;
|
||||
if (ti->aspect_ratio_given || ti->display_dimensions_given)
|
||||
return;
|
||||
|
||||
while (!bits.eof()) {
|
||||
if (!bits.peek_bits(32, marker))
|
||||
break;
|
||||
|
||||
if ((marker & 0xffffff00) != 0x00000100) {
|
||||
bits.skip_bits(8);
|
||||
continue;
|
||||
}
|
||||
|
||||
marker &= 0xff;
|
||||
if ((marker < 0x20) || (marker > 0x2f)) {
|
||||
bits.skip_bits(8);
|
||||
continue;
|
||||
}
|
||||
|
||||
mxverb(2, "mpeg4 AR: found VOL header at %u\n",
|
||||
bits.get_bit_position() / 8);
|
||||
bits.skip_bits(32);
|
||||
|
||||
// VOL header
|
||||
bits.skip_bits(1); // random access
|
||||
bits.skip_bits(8); // vo_type
|
||||
bits.get_bit(b);
|
||||
if (b != 0) { // is_old_id
|
||||
bits.skip_bits(4); // vo_ver_id
|
||||
bits.skip_bits(3); // vo_priority
|
||||
}
|
||||
|
||||
if (bits.get_bits(4, aspect_ratio_info)) {
|
||||
mxverb(2, "mpeg4 AR: aspect_ratio_info: %u\n", aspect_ratio_info);
|
||||
if (aspect_ratio_info == 15) { // ASPECT_EXTENDED
|
||||
bits.get_bits(8, num);
|
||||
bits.get_bits(8, den);
|
||||
} else {
|
||||
num = ar_nums[aspect_ratio_info];
|
||||
den = ar_dens[aspect_ratio_info];
|
||||
}
|
||||
mxverb(2, "mpeg4 AR: %u den: %u\n", num, den);
|
||||
|
||||
if ((num != 0) && (den != 0) && ((num != 1) || (den != 1)) &&
|
||||
(((float)num / (float)den) != 1.0)) {
|
||||
ti->aspect_ratio_given = true;
|
||||
ti->aspect_ratio = (float)hvideo_pixel_width /
|
||||
(float)hvideo_pixel_height * (float)num / (float)den;
|
||||
generic_packetizer_c::set_headers();
|
||||
rerender_track_headers();
|
||||
mxinfo("Track %lld of '%s': Extracted the aspect ratio information "
|
||||
"from the MPEG4 data and set the display dimensions to "
|
||||
"%u/%u.\n", ti->id, ti->fname, ti->display_width,
|
||||
ti->display_height);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
video_packetizer_c::find_mpeg4_frame_types(unsigned char *buf,
|
||||
int size,
|
||||
|
@ -43,6 +43,7 @@ private:
|
||||
int width, height, bpp, frames_output;
|
||||
int64_t ref_timecode, duration_shift;
|
||||
bool avi_compat_mode, bframes, pass_through, is_mpeg4;
|
||||
bool aspect_ratio_extracted;
|
||||
char *codec_id;
|
||||
vector<video_frame_t> queued_frames;
|
||||
video_frame_t bref_frame, fref_frame;
|
||||
@ -66,6 +67,7 @@ protected:
|
||||
virtual void find_mpeg4_frame_types(unsigned char *buf, int size,
|
||||
vector<video_frame_t> &frames);
|
||||
virtual void flush_frames(char next_frame = '?', bool flush_all = false);
|
||||
virtual void extract_mpeg4_aspect_ratio(memory_c &mem);
|
||||
};
|
||||
|
||||
#endif // __P_VIDEO_H
|
||||
|
@ -586,11 +586,13 @@ void generic_packetizer_c::set_headers() {
|
||||
GetChild<KaxVideoDisplayWidth>(video);
|
||||
*(static_cast<EbmlUInteger *>(&dwidth)) = disp_width;
|
||||
dwidth.SetDefaultSize(4);
|
||||
ti->display_width = disp_width;
|
||||
|
||||
KaxVideoDisplayHeight &dheight =
|
||||
GetChild<KaxVideoDisplayHeight>(video);
|
||||
*(static_cast<EbmlUInteger *>(&dheight)) = disp_height;
|
||||
dheight.SetDefaultSize(4);
|
||||
ti->display_height = disp_height;
|
||||
}
|
||||
|
||||
} else if (htrack_type == track_audio) {
|
||||
|
Loading…
Reference in New Issue
Block a user