From ff115d70615e40948299e4221c58047570599486 Mon Sep 17 00:00:00 2001 From: Denis Pauk Date: Sat, 7 Sep 2024 16:25:33 +0300 Subject: [PATCH] client: update mpeg video decoder https://github.com/phoboslab/pl_mpeg/blob/3198122a19c1685f041d0b6ef7dd2918a4959352/pl_mpeg.h --- src/client/cinema/pl_mpeg.h | 46 +++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/src/client/cinema/pl_mpeg.h b/src/client/cinema/pl_mpeg.h index 8b56a1f2..50cc9b21 100644 --- a/src/client/cinema/pl_mpeg.h +++ b/src/client/cinema/pl_mpeg.h @@ -346,6 +346,7 @@ int plm_get_num_video_streams(plm_t *self); int plm_get_width(plm_t *self); int plm_get_height(plm_t *self); +double plm_get_pixel_aspect_ratio(plm_t *self); // Get the framerate of the video stream in frames per second. @@ -583,7 +584,7 @@ static const int PLM_DEMUX_PACKET_PRIVATE = 0xBD; static const int PLM_DEMUX_PACKET_AUDIO_1 = 0xC0; static const int PLM_DEMUX_PACKET_AUDIO_2 = 0xC1; static const int PLM_DEMUX_PACKET_AUDIO_3 = 0xC2; -static const int PLM_DEMUX_PACKET_AUDIO_4 = 0xC2; +static const int PLM_DEMUX_PACKET_AUDIO_4 = 0xC3; static const int PLM_DEMUX_PACKET_VIDEO_1 = 0xE0; @@ -685,6 +686,7 @@ int plm_video_has_header(plm_video_t *self); // Get the framerate in frames per second. double plm_video_get_framerate(plm_video_t *self); +double plm_video_get_pixel_aspect_ratio(plm_video_t *self); // Get the display width/height. @@ -1044,6 +1046,12 @@ double plm_get_framerate(plm_t *self) { : 0; } +double plm_get_pixel_aspect_ratio(plm_t *self) { + return (plm_init_decoders(self) && self->video_decoder) + ? plm_video_get_pixel_aspect_ratio(self->video_decoder) + : 0; +} + int plm_get_num_audio_streams(plm_t *self) { return plm_demux_get_num_audio_streams(self->demux); } @@ -2227,6 +2235,14 @@ static const int PLM_START_USER_DATA = 0xB2; #define PLM_START_IS_SLICE(c) \ (c >= PLM_START_SLICE_FIRST && c <= PLM_START_SLICE_LAST) +static const float PLM_VIDEO_PIXEL_ASPECT_RATIO[] = { + 1.0000, /* square pixels */ + 0.6735, /* 3:4? */ + 0.7031, /* MPEG-1 / MPEG-2 video encoding divergence? */ + 0.7615, 0.8055, 0.8437, 0.8935, 0.9157, 0.9815, + 1.0255, 1.0695, 1.0950, 1.1575, 1.2051, +}; + static const double PLM_VIDEO_PICTURE_RATE[] = { 0.000, 23.976, 24.000, 25.000, 29.970, 30.000, 50.000, 59.940, 60.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000 @@ -2620,6 +2636,7 @@ typedef struct { struct plm_video_t { double framerate; + double pixel_aspect_ratio; double time; int frames_decoded; int width; @@ -2728,6 +2745,12 @@ double plm_video_get_framerate(plm_video_t *self) { : 0; } +double plm_video_get_pixel_aspect_ratio(plm_video_t *self) { + return plm_video_has_header(self) + ? self->pixel_aspect_ratio + : 0; +} + int plm_video_get_width(plm_video_t *self) { return plm_video_has_header(self) ? self->width @@ -2863,9 +2886,22 @@ int plm_video_decode_sequence_header(plm_video_t *self) { return FALSE; } - // Skip pixel aspect ratio - plm_buffer_skip(self->buffer, 4); + // Get pixel aspect ratio + int pixel_aspect_ratio_code; + pixel_aspect_ratio_code = plm_buffer_read(self->buffer, 4); + pixel_aspect_ratio_code -= 1; + if (pixel_aspect_ratio_code < 0) { + pixel_aspect_ratio_code = 0; + } + int par_last = (sizeof(PLM_VIDEO_PIXEL_ASPECT_RATIO) / + sizeof(PLM_VIDEO_PIXEL_ASPECT_RATIO[0]) - 1); + if (pixel_aspect_ratio_code > par_last) { + pixel_aspect_ratio_code = par_last; + } + self->pixel_aspect_ratio = + PLM_VIDEO_PIXEL_ASPECT_RATIO[pixel_aspect_ratio_code]; + // Get frame rate self->framerate = PLM_VIDEO_PICTURE_RATE[plm_buffer_read(self->buffer, 4)]; // Skip bit_rate, marker, buffer_size and constrained bit @@ -3176,7 +3212,7 @@ int plm_video_decode_motion_vector(plm_video_t *self, int r_size, int motion) { if (motion > (fscale << 4) - 1) { motion -= fscale << 5; } - else if (motion < ((-fscale) << 4)) { + else if (motion < (int)((unsigned)(-fscale) << 4)) { motion += fscale << 5; } @@ -3364,7 +3400,7 @@ void plm_video_decode_block(plm_video_t *self, int block) { n++; // Dequantize, oddify, clip - level <<= 1; + level = (unsigned)level << 1; if (!self->macroblock_intra) { level += (level < 0 ? -1 : 1); }