na_mpeg2_decoder/video/
decoder.rs

1use std::sync::Arc;
2
3use super::bitreader::GetBits;
4use super::error::{DecodeError, Result};
5use super::frame::{Frame, PixelFormat};
6use super::idct::{simple_idct_add, simple_idct_put};
7use super::motion::{MotionCompensator, MotionOp};
8use super::tables::{
9    FF_ALTERNATE_VERTICAL_SCAN, FF_MPEG1_DEFAULT_INTRA_MATRIX, FF_MPEG1_DEFAULT_NON_INTRA_MATRIX,
10    FF_MPEG2_NON_LINEAR_QSCALE, FF_ZIGZAG_DIRECT,
11};
12use super::vlc::{get_rl_vlc, get_vlc2};
13use super::vlctables::{
14    get_vlcs, has_cbp, is_intra, is_quant, mb_type_mv_2_mv_dir, MB_TYPE_16x16, MB_TYPE_16x8,
15    MB_TYPE_BACKWARD_MV, MB_TYPE_BIDIR_MV, MB_TYPE_CBP, MB_TYPE_FORWARD_MV, MB_TYPE_INTRA,
16    MB_TYPE_INTERLACED, MB_TYPE_QUANT, MB_TYPE_SKIP, MB_TYPE_ZERO_MV, MV_DIR_BACKWARD,
17    MV_DIR_FORWARD,
18};
19
20const PICT_TOP_FIELD: i32 = 1;
21const PICT_BOTTOM_FIELD: i32 = 2;
22const PICT_FRAME: i32 = 3;
23
24const PICT_TYPE_I: i32 = 1;
25const PICT_TYPE_P: i32 = 2;
26const PICT_TYPE_B: i32 = 3;
27
28const MV_TYPE_16X16: i32 = 0;
29const MV_TYPE_16X8: i32 = 1;
30const MV_TYPE_FIELD: i32 = 2;
31const MV_TYPE_DMV: i32 = 3;
32
33const MT_FIELD: i32 = 1;
34const MT_FRAME: i32 = 2;
35const MT_DMV: i32 = 3;
36
37#[inline]
38fn clip_coeff12(v: i32) -> i16 {
39    // MPEG-1/2 IDCT input is 12-bit signed ([-2048, 2047]).
40    if v < -2048 {
41        -2048i16
42    } else if v > 2047 {
43        2047i16
44    } else {
45        v as i16
46    }
47}
48
49#[derive(Clone, Copy, Debug, PartialEq, Eq)]
50enum CodecKind {
51    Mpeg1,
52    Mpeg2,
53}
54
55#[derive(Clone, Debug)]
56struct PictureParams {
57    pict_type: i32,
58    _temporal_reference: u16,
59}
60
61#[derive(Debug)]
62pub struct Decoder {
63    es_buf: Vec<u8>,
64
65    codec: CodecKind,
66    width: usize,
67    height: usize,
68    mb_width: usize,
69    mb_height: usize,
70    chroma_format: i32,
71    pix_fmt: PixelFormat,
72    progressive_sequence: bool,
73    low_delay: bool,
74
75    intra_matrix: [u16; 64],
76    inter_matrix: [u16; 64],
77    chroma_intra_matrix: [u16; 64],
78    chroma_inter_matrix: [u16; 64],
79
80    intra_dc_precision: i32,
81    picture_structure: i32,
82    top_field_first: bool,
83    frame_pred_frame_dct: bool,
84    concealment_motion_vectors: bool,
85    q_scale_type: i32,
86    intra_vlc_format: bool,
87    alternate_scan: bool,
88    repeat_first_field: bool,
89    chroma_420_type: bool,
90    progressive_frame: bool,
91
92    mpeg_f_code: [[i32; 2]; 2],
93    full_pel: [bool; 2],
94
95    pic: Option<PictureParams>,
96    cur: Option<Frame>,
97    cur_mb_type: i16,
98    mb_types: Vec<i16>,
99    mb_x: usize,
100    mb_y: usize,
101    qscale: i32,
102    mb_intra: bool,
103    mb_skipped: bool,
104    mv_dir: i32,
105    mv_type: i32,
106    field_select: [[i32; 2]; 2],
107    last_dc: [i32; 3],
108    last_mv: [[[i32; 2]; 2]; 2],
109    mv: [[[i32; 2]; 4]; 2],
110    interlaced_dct: bool,
111
112    blocks: [[i16; 64]; 12],
113    block_last_index: [i32; 12],
114
115    ref_prev: Option<Arc<Frame>>,
116    ref_cur: Option<Arc<Frame>>,
117
118    mc: MotionCompensator,
119}
120
121impl Default for Decoder {
122    fn default() -> Self {
123        let mut dec = Self {
124            es_buf: Vec::new(),
125            codec: CodecKind::Mpeg2,
126            width: 0,
127            height: 0,
128            mb_width: 0,
129            mb_height: 0,
130            chroma_format: 1,
131            pix_fmt: PixelFormat::Yuv420p,
132            progressive_sequence: true,
133            low_delay: false,
134            intra_matrix: [0u16; 64],
135            inter_matrix: [0u16; 64],
136            chroma_intra_matrix: [0u16; 64],
137            chroma_inter_matrix: [0u16; 64],
138            intra_dc_precision: 0,
139            picture_structure: PICT_FRAME,
140            top_field_first: false,
141            frame_pred_frame_dct: true,
142            concealment_motion_vectors: false,
143            q_scale_type: 0,
144            intra_vlc_format: false,
145            alternate_scan: false,
146            repeat_first_field: false,
147            chroma_420_type: false,
148            progressive_frame: true,
149            mpeg_f_code: [[1, 1], [1, 1]],
150            full_pel: [false, false],
151            pic: None,
152            cur: None,
153            cur_mb_type: 0,
154            mb_types: Vec::new(),
155            mb_x: 0,
156            mb_y: 0,
157            qscale: 0,
158            mb_intra: false,
159            mb_skipped: false,
160            mv_dir: 0,
161            mv_type: MV_TYPE_16X16,
162            field_select: [[0, 0], [0, 0]],
163            last_dc: [0, 0, 0],
164            last_mv: [[[0, 0], [0, 0]], [[0, 0], [0, 0]]],
165            mv: [[[0, 0]; 4]; 2],
166            interlaced_dct: false,
167            blocks: [[0i16; 64]; 12],
168            block_last_index: [-1; 12],
169            ref_prev: None,
170            ref_cur: None,
171            mc: MotionCompensator::new(),
172        };
173        dec.load_default_matrices();
174        dec
175    }
176}
177
178impl Decoder {
179    pub fn new() -> Self {
180        Self::default()
181    }
182
183    pub fn decode_shared(&mut self, data: &[u8], pts_90k: Option<i64>) -> Result<Vec<Arc<Frame>>> {
184        if pts_90k.is_some() {
185            if let Some(cur) = self.cur.as_mut() {
186                if cur.pts_90k.is_none() {
187                    cur.pts_90k = pts_90k;
188                }
189            }
190        }
191
192        self.es_buf.extend_from_slice(data);
193        let mut out: Vec<Arc<Frame>> = Vec::new();
194
195        loop {
196            let Some((unit_start, code)) = find_next_start_code(&self.es_buf, 0) else {
197                if self.es_buf.len() > 3 {
198                    let keep = self.es_buf.split_off(self.es_buf.len() - 3);
199                    self.es_buf = keep;
200                }
201                break;
202            };
203
204            if unit_start > 0 {
205                self.es_buf.drain(0..unit_start);
206            }
207            if self.es_buf.len() < 4 {
208                break;
209            }
210
211            let payload_start = 4usize;
212            let Some((next_start, _)) = find_next_start_code(&self.es_buf, payload_start) else {
213                break;
214            };
215
216            let payload = self.es_buf[payload_start..next_start].to_vec();
217            self.process_unit(code, &payload, pts_90k, &mut out)?;
218            self.es_buf.drain(0..next_start);
219        }
220
221        Ok(out)
222    }
223
224    pub fn flush_shared(&mut self) -> Result<Vec<Arc<Frame>>> {
225        let mut out = Vec::new();
226        self.finish_picture(&mut out)?;
227        if !self.low_delay {
228            if let Some(r) = self.ref_cur.take() {
229                out.push(r);
230            }
231            self.ref_prev = None;
232        } else {
233            self.ref_prev = None;
234            self.ref_cur = None;
235        }
236        Ok(out)
237    }
238
239    pub fn decode(&mut self, data: &[u8], pts_90k: Option<i64>) -> Result<Vec<Frame>> {
240        Ok(self
241            .decode_shared(data, pts_90k)?
242            .into_iter()
243            .map(|f| (*f).clone())
244            .collect())
245    }
246
247    pub fn flush(&mut self) -> Result<Vec<Frame>> {
248        Ok(self
249            .flush_shared()?
250            .into_iter()
251            .map(|f| (*f).clone())
252            .collect())
253    }
254
255    fn process_unit(&mut self, code: u8, payload: &[u8], pts_90k: Option<i64>, out: &mut Vec<Arc<Frame>>) -> Result<()> {
256        match code {
257            0x00 => {
258                self.finish_picture(out)?;
259                self.decode_picture_header(payload, pts_90k)?;
260            }
261            0xB3 => {
262                self.finish_picture(out)?;
263                self.decode_sequence_header(payload)?;
264            }
265            0xB5 => {
266                self.decode_extension(payload)?;
267            }
268            0xB7 => {
269                self.finish_picture(out)?;
270            }
271            0xB8 | 0xB2 => {}
272            0x01..=0xAF => {
273                if self.cur.is_none() || self.pic.is_none() {
274                    return Ok(());
275                }
276                // Slice start code: 0x01..=0xAF => slice_vertical_position.
277                // For field pictures, slice rows address every other macroblock row.
278                let mut mb_y = (code as usize).wrapping_sub(1);
279                if self.picture_structure != PICT_FRAME {
280                    mb_y = mb_y
281                        .saturating_mul(2)
282                        .saturating_add(((self.picture_structure - 1) & 1) as usize);
283                }
284                if mb_y >= self.mb_height {
285                    return Err(DecodeError::InvalidData("slice mb_y overflow"));
286                }
287                if let Err(e) = self.decode_slice(mb_y, payload) {
288                    // Be tolerant to slice-local bitstream damage or container junk.
289                    // This mirrors the typical "error concealment" behavior: skip the
290                    // remainder of the slice and continue with the next one.
291                    if let DecodeError::InvalidData(tag) = e {
292                        let pict_type = self.pic.as_ref().map(|p| p.pict_type).unwrap_or(0);
293                        log::warn!("Video slice decode error (row={} pict_type={}): {}", mb_y, pict_type, tag);
294                        return Ok(());
295                    }
296                    return Err(e);
297                }
298            }
299            _ => {}
300        }
301        Ok(())
302    }
303
304    fn finish_picture(&mut self, out: &mut Vec<Arc<Frame>>) -> Result<()> {
305        let Some(pic) = self.pic.take() else {
306            self.cur = None;
307            return Ok(());
308        };
309        let Some(cur) = self.cur.take() else {
310            return Ok(());
311        };
312
313        let cur_arc = Arc::new(cur);
314        match pic.pict_type {
315            PICT_TYPE_B => out.push(cur_arc),
316            PICT_TYPE_I | PICT_TYPE_P => {
317                if self.low_delay {
318                    out.push(cur_arc.clone());
319                    self.ref_cur = Some(cur_arc);
320                    self.ref_prev = None;
321                } else {
322                    if let Some(prev) = self.ref_cur.take() {
323                        self.ref_prev = Some(prev.clone());
324                        out.push(prev);
325                    }
326                    self.ref_cur = Some(cur_arc);
327                }
328            }
329            _ => out.push(cur_arc),
330        }
331        Ok(())
332    }
333
334    fn decode_sequence_header(&mut self, payload: &[u8]) -> Result<()> {
335        let mut gb = GetBits::init(payload);
336        let w = gb.get_bits(12) as usize;
337        let h = gb.get_bits(12) as usize;
338        if w == 0 || h == 0 {
339            return Err(DecodeError::InvalidData("sequence size"));
340        }
341        let _ = gb.get_bits(4);
342        let _ = gb.get_bits(4);
343        let _ = gb.get_bits(18);
344        if gb.get_bits1() == 0 {
345            return Err(DecodeError::InvalidData("sequence marker"));
346        }
347        let _ = gb.get_bits(10);
348        let _ = gb.get_bits1();
349
350        if gb.get_bits1() != 0 {
351            self.load_matrix_from_stream(&mut gb, true)?;
352        } else {
353            self.load_default_intra_matrix();
354        }
355        if gb.get_bits1() != 0 {
356            self.load_matrix_from_stream(&mut gb, false)?;
357        } else {
358            self.load_default_inter_matrix();
359        }
360
361        self.width = w;
362        self.height = h;
363        self.codec = CodecKind::Mpeg1;
364        self.progressive_sequence = true;
365        self.progressive_frame = true;
366        self.picture_structure = PICT_FRAME;
367        self.frame_pred_frame_dct = true;
368        self.chroma_format = 1;
369        self.pix_fmt = PixelFormat::Yuv420p;
370        self.low_delay = false;
371        self.recompute_frame_layout()?;
372        Ok(())
373    }
374
375    fn decode_picture_header(&mut self, payload: &[u8], pts_90k: Option<i64>) -> Result<()> {
376        if self.width == 0 || self.height == 0 {
377            return Err(DecodeError::InvalidData("picture before sequence"));
378        }
379        let mut gb = GetBits::init(payload);
380        let temporal_reference = gb.get_bits(10) as u16;
381        let pict_type = gb.get_bits(3) as i32;
382        let _ = gb.get_bits(16);
383        if pict_type != PICT_TYPE_I && pict_type != PICT_TYPE_P && pict_type != PICT_TYPE_B {
384            return Err(DecodeError::Unsupported("picture type"));
385        }
386
387        if self.codec == CodecKind::Mpeg1 {
388            match pict_type {
389                PICT_TYPE_P => {
390                    self.full_pel[0] = gb.get_bits1() != 0;
391                    self.mpeg_f_code[0][0] = gb.get_bits(3) as i32;
392                    self.mpeg_f_code[0][1] = self.mpeg_f_code[0][0];
393                }
394                PICT_TYPE_B => {
395                    self.full_pel[0] = gb.get_bits1() != 0;
396                    self.mpeg_f_code[0][0] = gb.get_bits(3) as i32;
397                    self.mpeg_f_code[0][1] = self.mpeg_f_code[0][0];
398                    self.full_pel[1] = gb.get_bits1() != 0;
399                    self.mpeg_f_code[1][0] = gb.get_bits(3) as i32;
400                    self.mpeg_f_code[1][1] = self.mpeg_f_code[1][0];
401                }
402                _ => {}
403            }
404        }
405
406        gb.skip_1stop_8data_bits()?;
407
408        self.intra_dc_precision = 0;
409        self.picture_structure = PICT_FRAME;
410        self.top_field_first = false;
411        self.frame_pred_frame_dct = true;
412        self.concealment_motion_vectors = false;
413        self.q_scale_type = 0;
414        self.intra_vlc_format = false;
415        self.alternate_scan = false;
416        self.repeat_first_field = false;
417        self.chroma_420_type = false;
418        self.progressive_frame = self.progressive_sequence;
419
420        let mut f = Frame::new(self.mb_width * 16, self.mb_height * 16, self.pix_fmt);
421        f.pts_90k = pts_90k;
422
423        self.pic = Some(PictureParams { pict_type, _temporal_reference: temporal_reference });
424        self.cur = Some(f);
425        self.mb_types.clear();
426        self.mb_types.resize(self.mb_width * self.mb_height, 0);
427        Ok(())
428    }
429
430    fn decode_extension(&mut self, payload: &[u8]) -> Result<()> {
431        let mut gb = GetBits::init(payload);
432        if gb.bits_left() < 4 {
433            return Err(DecodeError::InvalidData("extension id"));
434        }
435        match gb.get_bits(4) {
436            1 => self.decode_sequence_extension(&mut gb)?,
437            3 => self.decode_quant_matrix_extension(&mut gb)?,
438            8 => self.decode_picture_coding_extension(&mut gb)?,
439            _ => {}
440        }
441        Ok(())
442    }
443
444    fn decode_sequence_extension(&mut self, gb: &mut GetBits<'_>) -> Result<()> {
445        gb.skip_bits(1);
446        let _ = gb.get_bits(3);
447        let _ = gb.get_bits(4);
448        self.progressive_sequence = gb.get_bits1() != 0;
449        self.chroma_format = gb.get_bits(2) as i32;
450        if self.chroma_format == 0 {
451            self.chroma_format = 1;
452        }
453        let h_ext = gb.get_bits(2) as usize;
454        let v_ext = gb.get_bits(2) as usize;
455        self.width |= h_ext << 12;
456        self.height |= v_ext << 12;
457        let _ = gb.get_bits(12);
458        if gb.get_bits1() == 0 {
459            return Err(DecodeError::InvalidData("seqext marker"));
460        }
461        let _ = gb.get_bits(8);
462        self.low_delay = gb.get_bits1() != 0;
463        let _ = gb.get_bits(2);
464        let _ = gb.get_bits(5);
465
466        self.codec = CodecKind::Mpeg2;
467        self.pix_fmt = match self.chroma_format {
468            1 => PixelFormat::Yuv420p,
469            2 => PixelFormat::Yuv422p,
470            3 => PixelFormat::Yuv444p,
471            _ => PixelFormat::Yuv420p,
472        };
473        self.recompute_frame_layout()?;
474        Ok(())
475    }
476
477    fn decode_quant_matrix_extension(&mut self, gb: &mut GetBits<'_>) -> Result<()> {
478        if gb.get_bits1() != 0 {
479            self.load_matrix_from_stream(gb, true)?;
480        }
481        if gb.get_bits1() != 0 {
482            self.load_matrix_from_stream(gb, false)?;
483        }
484        if gb.get_bits1() != 0 {
485            self.load_matrix_chroma_only(gb, true)?;
486        }
487        if gb.get_bits1() != 0 {
488            self.load_matrix_chroma_only(gb, false)?;
489        }
490        Ok(())
491    }
492
493    // Fixed: no extra skip_bits1; bit layout must be read sequentially.
494    fn decode_picture_coding_extension(&mut self, gb: &mut GetBits<'_>) -> Result<()> {
495        self.full_pel = [false, false];
496        self.mpeg_f_code[0][0] = gb.get_bits(4) as i32;
497        self.mpeg_f_code[0][1] = gb.get_bits(4) as i32;
498        self.mpeg_f_code[1][0] = gb.get_bits(4) as i32;
499        self.mpeg_f_code[1][1] = gb.get_bits(4) as i32;
500        for d in 0..2 {
501            for c in 0..2 {
502                if self.mpeg_f_code[d][c] == 0 {
503                    self.mpeg_f_code[d][c] = 1;
504                }
505            }
506        }
507        self.intra_dc_precision = gb.get_bits(2) as i32;
508        self.picture_structure = gb.get_bits(2) as i32;
509        self.top_field_first = gb.get_bits1() != 0;
510        self.frame_pred_frame_dct = gb.get_bits1() != 0;
511        self.concealment_motion_vectors = gb.get_bits1() != 0;
512        self.q_scale_type = gb.get_bits1() as i32;
513        self.intra_vlc_format = gb.get_bits1() != 0;
514        self.alternate_scan = gb.get_bits1() != 0;
515        self.repeat_first_field = gb.get_bits1() != 0;
516        self.chroma_420_type = gb.get_bits1() != 0;
517        self.progressive_frame = gb.get_bits1() != 0;
518        Ok(())
519    }
520
521    fn recompute_frame_layout(&mut self) -> Result<()> {
522        if self.width == 0 || self.height == 0 {
523            return Ok(());
524        }
525        self.mb_width = (self.width + 15) >> 4;
526        self.mb_height = (self.height + 15) >> 4;
527        Ok(())
528    }
529
530    // ---------------- slice / macroblock decode ----------------
531
532    fn decode_slice(&mut self, mb_y_start: usize, payload: &[u8]) -> Result<()> {
533        let vlcs = get_vlcs();
534        let mut gb = GetBits::init(payload);
535
536        self.interlaced_dct = false;
537        self.qscale = mpeg_get_qscale(&mut gb, self.q_scale_type);
538        if self.qscale == 0 {
539            return Err(DecodeError::InvalidData("qscale==0"));
540        }
541
542        gb.skip_1stop_8data_bits()?;
543
544        // Initial macroblock address increment.
545        let mut mb_x = 0usize;
546        while gb.bits_left() > 0 {
547            let code = get_vlc2(&mut gb, &vlcs.mbincr.table, vlcs.mbincr.bits, 2);
548            if code < 0 {
549                return Err(DecodeError::InvalidData("first mb_incr"));
550            }
551            if code >= 33 {
552                if code == 33 {
553                    mb_x = mb_x.saturating_add(33);
554                }
555                // stuffing/end: ignore
556            } else {
557                mb_x = mb_x.saturating_add(code as usize);
558                break;
559            }
560        }
561
562        if mb_x >= self.mb_width {
563            return Err(DecodeError::InvalidData("initial mb_x overflow"));
564        }
565
566        // Reset DC and MV predictors at slice start.
567        self.last_dc[0] = 128 << self.intra_dc_precision;
568        self.last_dc[1] = self.last_dc[0];
569        self.last_dc[2] = self.last_dc[0];
570        self.last_mv = [[[0, 0], [0, 0]], [[0, 0], [0, 0]]];
571
572        self.mb_x = mb_x;
573        self.mb_y = mb_y_start;
574
575        // Number of skipped macroblocks before the next coded one.
576        let mut mb_skip_run: i32 = 0;
577        loop {
578            if self.mb_y >= self.mb_height {
579                break;
580            }
581            self.mb_skipped = false;
582
583            self.decode_mb(&mut gb, &mut mb_skip_run)?;
584            self.reconstruct_mb()?;
585
586            // Advance macroblock position.
587            self.mb_x += 1;
588            if self.mb_x >= self.mb_width {
589                self.mb_x = 0;
590                let field_pic = self.picture_structure != PICT_FRAME;
591                self.mb_y += if field_pic { 2 } else { 1 };
592                if self.mb_y >= self.mb_height {
593                    break;
594                }
595            }
596
597            // Read next macroblock_address_increment when not inside a skip run.
598            if mb_skip_run == -1 {
599                mb_skip_run = 0;
600                loop {
601                    let code = get_vlc2(&mut gb, &vlcs.mbincr.table, vlcs.mbincr.bits, 2);
602                    if code < 0 {
603                        return Err(DecodeError::InvalidData("mb_incr"));
604                    }
605                    if code >= 33 {
606                        if code == 33 {
607                            mb_skip_run += 33;
608                        } else if code == 35 {
609                            // end of slice
610                            if mb_skip_run != 0 || gb.show_bits(15) != 0 {
611                                return Err(DecodeError::InvalidData("slice mismatch"));
612                            }
613                            return Ok(());
614                        }
615                        // stuffing: ignore
616                    } else {
617                        mb_skip_run += code;
618                        break;
619                    }
620                }
621
622                if mb_skip_run != 0 {
623                    let pict_type = self.pic.as_ref().map(|p| p.pict_type).unwrap_or(0);
624                    if pict_type == PICT_TYPE_I {
625                        return Err(DecodeError::InvalidData("skipped MB in I-picture"));
626                    }
627
628                    self.mb_intra = false;
629                    for v in &mut self.block_last_index {
630                        *v = -1;
631                    }
632                    self.last_dc[0] = 128 << self.intra_dc_precision;
633                    self.last_dc[1] = self.last_dc[0];
634                    self.last_dc[2] = self.last_dc[0];
635
636                    if self.picture_structure == PICT_FRAME {
637                        self.mv_type = MV_TYPE_16X16;
638                    } else {
639                        self.mv_type = MV_TYPE_FIELD;
640                    }
641
642                    if pict_type == PICT_TYPE_P {
643                        self.mv_dir = MV_DIR_FORWARD;
644                        self.mv[0][0] = [0, 0];
645                        self.last_mv[0][0] = [0, 0];
646                        self.last_mv[0][1] = [0, 0];
647                        self.field_select[0][0] = (self.picture_structure - 1) & 1;
648                    } else {
649                        self.mv[0][0] = self.last_mv[0][0];
650                        self.mv[1][0] = self.last_mv[1][0];
651                        self.field_select[0][0] = (self.picture_structure - 1) & 1;
652                        self.field_select[1][0] = (self.picture_structure - 1) & 1;
653                    }
654                }
655            }
656        }
657
658        Ok(())
659    }
660
661    fn decode_mb(&mut self, gb: &mut GetBits<'_>, mb_skip_run: &mut i32) -> Result<()> {
662        let vlcs = get_vlcs();
663        let pict_type = self.pic.as_ref().map(|p| p.pict_type).unwrap_or(0);
664
665        self.mb_skipped = false;
666
667        // Skip-run fast path.
668        if *mb_skip_run != 0 {
669            *mb_skip_run -= 1;
670            if pict_type == PICT_TYPE_P {
671                self.mb_skipped = true;
672                self.mb_intra = false;
673                self.mv_dir = MV_DIR_FORWARD;
674                self.mv_type = MV_TYPE_16X16;
675                self.cur_mb_type = MB_TYPE_SKIP | MB_TYPE_FORWARD_MV | MB_TYPE_16x16;
676            } else {
677                let prev_mb_type = if self.mb_x > 0 {
678                    self.mb_types[self.mb_x - 1 + self.mb_y * self.mb_width]
679                } else if self.mb_y > 0 {
680                    self.mb_types[self.mb_width - 1 + (self.mb_y - 1) * self.mb_width]
681                } else {
682                    0
683                };
684                if is_intra(prev_mb_type) {
685                    return Err(DecodeError::InvalidData("skip with prev intra"));
686                }
687                self.cur_mb_type = prev_mb_type | MB_TYPE_SKIP;
688
689                let z = self.mv[0][0][0] | self.mv[0][0][1] | self.mv[1][0][0] | self.mv[1][0][1];
690                if z == 0 {
691                    self.mb_skipped = true;
692                }
693                self.mb_intra = false;
694            }
695
696            self.store_mb_type();
697            return Ok(());
698        }
699
700        // Decode mb_type.
701        let mut mb_type: i16 = match pict_type {
702            PICT_TYPE_I => {
703                if gb.get_bits1() == 0 {
704                    if gb.get_bits1() == 0 {
705                        return Err(DecodeError::InvalidData("I mb_type"));
706                    }
707                    MB_TYPE_QUANT | MB_TYPE_INTRA
708                } else {
709                    MB_TYPE_INTRA
710                }
711            }
712            PICT_TYPE_P => {
713                let v = get_vlc2(gb, &vlcs.mb_ptype.table, vlcs.mb_ptype.bits, 1);
714                if v < 0 {
715                    return Err(DecodeError::InvalidData("P mb_type"));
716                }
717                v as i16
718            }
719            PICT_TYPE_B => {
720                let v = get_vlc2(gb, &vlcs.mb_btype.table, vlcs.mb_btype.bits, 1);
721                if v < 0 {
722                    return Err(DecodeError::InvalidData("B mb_type"));
723                }
724                v as i16
725            }
726            _ => return Err(DecodeError::InvalidData("pict_type")),
727        };
728
729        self.cur_mb_type = mb_type;
730        let mb_block_count = 4 + (1usize << (self.chroma_format as usize));
731
732        if is_intra(mb_type) {
733            for i in 0..mb_block_count {
734                self.blocks[i] = [0i16; 64];
735                self.block_last_index[i] = -1;
736            }
737            if self.picture_structure == PICT_FRAME && !self.frame_pred_frame_dct {
738                self.interlaced_dct = gb.get_bits1() != 0;
739            } else {
740                self.interlaced_dct = false;
741            }
742            if is_quant(mb_type) {
743                self.qscale = mpeg_get_qscale(gb, self.q_scale_type);
744            }
745
746            if self.concealment_motion_vectors {
747                if self.picture_structure != PICT_FRAME {
748                    gb.skip_bits1();
749                }
750                let mx = mpeg_decode_motion(gb, &vlcs.mv, self.mpeg_f_code[0][0], self.last_mv[0][0][0])?;
751                let my = mpeg_decode_motion(gb, &vlcs.mv, self.mpeg_f_code[0][1], self.last_mv[0][0][1])?;
752                self.mv[0][0][0] = mx;
753                self.mv[0][0][1] = my;
754                self.last_mv[0][0][0] = mx;
755                self.last_mv[0][0][1] = my;
756                self.last_mv[0][1][0] = mx;
757                self.last_mv[0][1][1] = my;
758                if gb.get_bits1() == 0 {
759                    return Err(DecodeError::InvalidData("cmv marker"));
760                }
761            } else {
762                self.last_mv = [[[0, 0], [0, 0]], [[0, 0], [0, 0]]];
763            }
764
765            self.mb_intra = true;
766            if self.codec == CodecKind::Mpeg2 {
767                for i in 0..mb_block_count {
768                    self.mpeg2_decode_block_intra(gb, i)?;
769                }
770            } else {
771                for i in 0..6 {
772                    self.mpeg1_decode_block_intra(gb, i, self.qscale)?;
773                }
774            }
775        } else {
776            if (mb_type & MB_TYPE_ZERO_MV) != 0 {
777                if (mb_type & MB_TYPE_CBP) == 0 {
778                    return Err(DecodeError::InvalidData("zero_mv without cbp"));
779                }
780                self.mv_dir = MV_DIR_FORWARD;
781                if self.picture_structure == PICT_FRAME {
782                    if !self.frame_pred_frame_dct {
783                        self.interlaced_dct = gb.get_bits1() != 0;
784                    } else {
785                        self.interlaced_dct = false;
786                    }
787                    self.mv_type = MV_TYPE_16X16;
788                } else {
789                    self.mv_type = MV_TYPE_FIELD;
790                    mb_type |= MB_TYPE_INTERLACED;
791                    self.field_select[0][0] = self.picture_structure - 1;
792                }
793                if is_quant(mb_type) {
794                    self.qscale = mpeg_get_qscale(gb, self.q_scale_type);
795                }
796                self.last_mv[0][0] = [0, 0];
797                self.last_mv[0][1] = [0, 0];
798                self.mv[0][0] = [0, 0];
799            } else {
800                let motion_type = if self.picture_structure == PICT_FRAME && self.frame_pred_frame_dct {
801                    MT_FRAME
802                } else {
803                    let mt = gb.get_bits(2) as i32;
804                    if self.picture_structure == PICT_FRAME && has_cbp(mb_type) {
805                        self.interlaced_dct = gb.get_bits1() != 0;
806                    }
807                    mt
808                };
809                if is_quant(mb_type) {
810                    self.qscale = mpeg_get_qscale(gb, self.q_scale_type);
811                }
812
813                self.mv_dir = mb_type_mv_2_mv_dir(mb_type);
814                match motion_type {
815                    MT_FRAME => {
816                        if self.picture_structure == PICT_FRAME {
817                            mb_type |= MB_TYPE_16x16;
818                            self.mv_type = MV_TYPE_16X16;
819                            for dir in 0..2 {
820                                if has_mv_dir(mb_type, dir) {
821                                    let mx = mpeg_decode_motion(
822                                        gb,
823                                        &vlcs.mv,
824                                        self.mpeg_f_code[dir][0],
825                                        self.last_mv[dir][0][0],
826                                    )?;
827                                    let my = mpeg_decode_motion(
828                                        gb,
829                                        &vlcs.mv,
830                                        self.mpeg_f_code[dir][1],
831                                        self.last_mv[dir][0][1],
832                                    )?;
833                                    self.last_mv[dir][0][0] = mx;
834                                    self.last_mv[dir][0][1] = my;
835                                    self.last_mv[dir][1][0] = mx;
836                                    self.last_mv[dir][1][1] = my;
837                                    self.mv[dir][0][0] = if self.full_pel[dir] { mx * 2 } else { mx };
838                                    self.mv[dir][0][1] = if self.full_pel[dir] { my * 2 } else { my };
839                                }
840                            }
841                        } else {
842                            mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED;
843                            self.mv_type = MV_TYPE_16X8;
844                            for dir in 0..2 {
845                                if has_mv_dir(mb_type, dir) {
846                                    for j in 0..2 {
847                                        self.field_select[dir][j] = gb.get_bits1() as i32;
848                                        for k in 0..2 {
849                                            let val = mpeg_decode_motion(
850                                                gb,
851                                                &vlcs.mv,
852                                                self.mpeg_f_code[dir][k],
853                                                self.last_mv[dir][j][k],
854                                            )?;
855                                            self.last_mv[dir][j][k] = val;
856                                            self.mv[dir][j][k] = val;
857                                        }
858                                    }
859                                }
860                            }
861                        }
862                    }
863                    MT_FIELD => {
864                        self.mv_type = MV_TYPE_FIELD;
865                        if self.picture_structure == PICT_FRAME {
866                            mb_type |= MB_TYPE_16x8 | MB_TYPE_INTERLACED;
867                            for dir in 0..2 {
868                                if has_mv_dir(mb_type, dir) {
869                                    for j in 0..2 {
870                                        self.field_select[dir][j] = gb.get_bits1() as i32;
871                                        let mx = mpeg_decode_motion(
872                                            gb,
873                                            &vlcs.mv,
874                                            self.mpeg_f_code[dir][0],
875                                            self.last_mv[dir][j][0],
876                                        )?;
877                                        self.last_mv[dir][j][0] = mx;
878                                        self.mv[dir][j][0] = mx;
879                                        let my = mpeg_decode_motion(
880                                            gb,
881                                            &vlcs.mv,
882                                            self.mpeg_f_code[dir][1],
883                                            self.last_mv[dir][j][1] >> 1,
884                                        )?;
885                                        self.last_mv[dir][j][1] = 2 * my;
886                                        self.mv[dir][j][1] = my;
887                                    }
888                                }
889                            }
890                        } else {
891                            mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED;
892                            for dir in 0..2 {
893                                if has_mv_dir(mb_type, dir) {
894                                    self.field_select[dir][0] = gb.get_bits1() as i32;
895                                    for k in 0..2 {
896                                        let val = mpeg_decode_motion(
897                                            gb,
898                                            &vlcs.mv,
899                                            self.mpeg_f_code[dir][k],
900                                            self.last_mv[dir][0][k],
901                                        )?;
902                                        self.last_mv[dir][0][k] = val;
903                                        self.last_mv[dir][1][k] = val;
904                                        self.mv[dir][0][k] = val;
905                                    }
906                                }
907                            }
908                        }
909                    }
910                    MT_DMV => {
911                        if self.progressive_sequence {
912                            return Err(DecodeError::InvalidData("MT_DMV in progressive"));
913                        }
914                        self.mv_type = MV_TYPE_DMV;
915                        for dir in 0..2 {
916                            if has_mv_dir(mb_type, dir) {
917                                let my_shift = if self.picture_structure == PICT_FRAME { 1 } else { 0 };
918                                let mx = mpeg_decode_motion(
919                                    gb,
920                                    &vlcs.mv,
921                                    self.mpeg_f_code[dir][0],
922                                    self.last_mv[dir][0][0],
923                                )?;
924                                self.last_mv[dir][0][0] = mx;
925                                self.last_mv[dir][1][0] = mx;
926                                let dmx = get_dmv(gb);
927                                let my = mpeg_decode_motion(
928                                    gb,
929                                    &vlcs.mv,
930                                    self.mpeg_f_code[dir][1],
931                                    self.last_mv[dir][0][1] >> my_shift,
932                                )?;
933                                let dmy = get_dmv(gb);
934                                self.last_mv[dir][0][1] = my * (1 << my_shift);
935                                self.last_mv[dir][1][1] = my * (1 << my_shift);
936                                self.mv[dir][0][0] = mx;
937                                self.mv[dir][0][1] = my;
938                                self.mv[dir][1][0] = mx;
939                                self.mv[dir][1][1] = my;
940                                if self.picture_structure == PICT_FRAME {
941                                    mb_type |= MB_TYPE_16x16 | MB_TYPE_INTERLACED;
942                                    let mut m = if self.top_field_first { 1 } else { 3 };
943                                    self.mv[dir][2][0] = ((mx * m + if mx > 0 { 1 } else { 0 }) >> 1) + dmx;
944                                    self.mv[dir][2][1] = ((my * m + if my > 0 { 1 } else { 0 }) >> 1) + dmy - 1;
945                                    m = 4 - m;
946                                    self.mv[dir][3][0] = ((mx * m + if mx > 0 { 1 } else { 0 }) >> 1) + dmx;
947                                    self.mv[dir][3][1] = ((my * m + if my > 0 { 1 } else { 0 }) >> 1) + dmy + 1;
948                                } else {
949                                    mb_type |= MB_TYPE_16x16;
950                                    self.mv[dir][2][0] = ((mx + if mx > 0 { 1 } else { 0 }) >> 1) + dmx;
951                                    self.mv[dir][2][1] = ((my + if my > 0 { 1 } else { 0 }) >> 1) + dmy;
952                                    if self.picture_structure == PICT_TOP_FIELD {
953                                        self.mv[dir][2][1] -= 1;
954                                    } else {
955                                        self.mv[dir][2][1] += 1;
956                                    }
957                                }
958                            }
959                        }
960                    }
961                    _ => return Err(DecodeError::InvalidData("motion_type")),
962                }
963            }
964
965            self.mb_intra = false;
966            self.last_dc[0] = 128 << self.intra_dc_precision;
967            self.last_dc[1] = self.last_dc[0];
968            self.last_dc[2] = self.last_dc[0];
969
970            if (mb_type & MB_TYPE_CBP) != 0 {
971                for i in 0..mb_block_count {
972                    self.blocks[i] = [0i16; 64];
973                }
974                let cbp = get_vlc2(gb, &vlcs.mb_pat.table, vlcs.mb_pat.bits, 1);
975                if cbp <= 0 {
976                    return Err(DecodeError::InvalidData("cbp"));
977                }
978                let mut cbp_u = cbp as u32;
979                if mb_block_count > 6 {
980                    cbp_u <<= (mb_block_count - 6) as u32;
981                    cbp_u |= gb.get_bits(mb_block_count - 6) as u32;
982                }
983                if self.codec == CodecKind::Mpeg2 {
984                    let shift = 12usize.saturating_sub(mb_block_count);
985                    cbp_u <<= shift as u32;
986                    for i in 0..mb_block_count {
987                        if (cbp_u & (1 << 11)) != 0 {
988                            self.mpeg2_decode_block_non_intra(gb, i)?;
989                        } else {
990                            self.block_last_index[i] = -1;
991                        }
992                        cbp_u <<= 1;
993                    }
994                } else {
995                    for i in 0..6 {
996                        if (cbp_u & 32) != 0 {
997                            self.mpeg1_decode_block_inter(gb, i)?;
998                        } else {
999                            self.block_last_index[i] = -1;
1000                        }
1001                        cbp_u <<= 1;
1002                    }
1003                }
1004            } else {
1005                for i in 0..12 {
1006                    self.block_last_index[i] = -1;
1007                }
1008            }
1009        }
1010
1011        self.cur_mb_type = mb_type;
1012        self.store_mb_type();
1013        // Signal the caller to read the next increment after a coded MB.
1014        *mb_skip_run -= 1;
1015        Ok(())
1016    }
1017
1018    fn store_mb_type(&mut self) {
1019        if self.mb_y < self.mb_height && self.mb_x < self.mb_width {
1020            let idx = self.mb_x + self.mb_y * self.mb_width;
1021            if idx < self.mb_types.len() {
1022                self.mb_types[idx] = self.cur_mb_type;
1023            }
1024        }
1025    }
1026
1027    fn reconstruct_mb(&mut self) -> Result<()> {
1028        let pict_type = self.pic.as_ref().map(|p| p.pict_type).unwrap_or(0);
1029        // Take the current frame out temporarily to avoid holding a mutable borrow
1030        // of `self.cur` while calling other `&mut self` helpers.
1031        let mut cur = self
1032            .cur
1033            .take()
1034            .ok_or(DecodeError::Internal("no current frame"))?;
1035
1036        if self.mb_intra {
1037            self.put_intra_blocks(&mut cur);
1038            self.cur = Some(cur);
1039            return Ok(());
1040        }
1041
1042        match pict_type {
1043            PICT_TYPE_P => {
1044                let Some(ref_frame) = self.ref_cur.as_ref() else {
1045                    // No reference picture yet: keep the (partially) decoded frame.
1046                    self.cur = Some(cur);
1047                    return Ok(());
1048                };
1049                self.mc.mpv_motion(
1050                    &mut cur,
1051                    ref_frame,
1052                    0,
1053                    MotionOp::Put,
1054                    self.mv_type,
1055                    self.picture_structure,
1056                    self.mb_x,
1057                    self.mb_y,
1058                    &self.mv,
1059                    &self.field_select,
1060                    false,
1061                );
1062            }
1063            PICT_TYPE_B => {
1064                let mut did_any = false;
1065                if (self.mv_dir & MV_DIR_FORWARD) != 0 {
1066                    if let Some(ref_frame) = self.ref_prev.as_ref() {
1067                        self.mc.mpv_motion(
1068                            &mut cur,
1069                            ref_frame,
1070                            0,
1071                            MotionOp::Put,
1072                            self.mv_type,
1073                            self.picture_structure,
1074                            self.mb_x,
1075                            self.mb_y,
1076                            &self.mv,
1077                            &self.field_select,
1078                            false,
1079                        );
1080                        did_any = true;
1081                    }
1082                }
1083                if (self.mv_dir & MV_DIR_BACKWARD) != 0 {
1084                    if let Some(ref_frame) = self.ref_cur.as_ref() {
1085                        self.mc.mpv_motion(
1086                            &mut cur,
1087                            ref_frame,
1088                            1,
1089                            if did_any { MotionOp::Avg } else { MotionOp::Put },
1090                            self.mv_type,
1091                            self.picture_structure,
1092                            self.mb_x,
1093                            self.mb_y,
1094                            &self.mv,
1095                            &self.field_select,
1096                            false,
1097                        );
1098                        did_any = true;
1099                    }
1100                }
1101                let _ = did_any;
1102            }
1103            _ => {}
1104        }
1105
1106        self.add_inter_blocks(&mut cur);
1107        self.cur = Some(cur);
1108        Ok(())
1109    }
1110
1111    fn put_intra_blocks(&mut self, cur: &mut Frame) {
1112        let base_x = self.mb_x * 16;
1113        let base_y = self.mb_y * 16;
1114
1115        for by in 0..2 {
1116            for bx in 0..2 {
1117                let bi = by * 2 + bx;
1118                let x = base_x + bx * 8;
1119                let y = base_y + by * 8;
1120                if x + 8 <= cur.width && y + 8 <= cur.height {
1121                    let off = y * cur.linesize_y + x;
1122                    simple_idct_put(&mut cur.data_y[off..], cur.linesize_y, &mut self.blocks[bi]);
1123                }
1124            }
1125        }
1126
1127        match cur.format {
1128            PixelFormat::Yuv420p => {
1129                let x = self.mb_x * 8;
1130                let y = self.mb_y * 8;
1131                let off_u = y * cur.linesize_u + x;
1132                let off_v = y * cur.linesize_v + x;
1133                simple_idct_put(&mut cur.data_u[off_u..], cur.linesize_u, &mut self.blocks[4]);
1134                simple_idct_put(&mut cur.data_v[off_v..], cur.linesize_v, &mut self.blocks[5]);
1135            }
1136            PixelFormat::Yuv422p => {
1137                let x = self.mb_x * 8;
1138                let y = self.mb_y * 16;
1139                for by in 0..2 {
1140                    let off_u = (y + by * 8) * cur.linesize_u + x;
1141                    simple_idct_put(&mut cur.data_u[off_u..], cur.linesize_u, &mut self.blocks[4 + by]);
1142                }
1143                for by in 0..2 {
1144                    let off_v = (y + by * 8) * cur.linesize_v + x;
1145                    simple_idct_put(&mut cur.data_v[off_v..], cur.linesize_v, &mut self.blocks[6 + by]);
1146                }
1147            }
1148            PixelFormat::Yuv444p => {
1149                for plane in 0..2 {
1150                    for by in 0..2 {
1151                        for bx in 0..2 {
1152                            let b = by * 2 + bx;
1153                            let x = base_x + bx * 8;
1154                            let y = base_y + by * 8;
1155                            let (dst, stride, idx) = if plane == 0 {
1156                                (&mut cur.data_u, cur.linesize_u, 4 + b)
1157                            } else {
1158                                (&mut cur.data_v, cur.linesize_v, 8 + b)
1159                            };
1160                            let off = y * stride + x;
1161                            simple_idct_put(&mut dst[off..], stride, &mut self.blocks[idx]);
1162                        }
1163                    }
1164                }
1165            }
1166        }
1167    }
1168
1169    fn add_inter_blocks(&mut self, cur: &mut Frame) {
1170        let base_x = self.mb_x * 16;
1171        let base_y = self.mb_y * 16;
1172
1173        for by in 0..2 {
1174            for bx in 0..2 {
1175                let bi = by * 2 + bx;
1176                if self.block_last_index[bi] < 0 {
1177                    continue;
1178                }
1179                let x = base_x + bx * 8;
1180                let y = base_y + by * 8;
1181                let off = y * cur.linesize_y + x;
1182                simple_idct_add(&mut cur.data_y[off..], cur.linesize_y, &mut self.blocks[bi]);
1183            }
1184        }
1185
1186        match cur.format {
1187            PixelFormat::Yuv420p => {
1188                if self.block_last_index[4] >= 0 {
1189                    let x = self.mb_x * 8;
1190                    let y = self.mb_y * 8;
1191                    let off_u = y * cur.linesize_u + x;
1192                    simple_idct_add(&mut cur.data_u[off_u..], cur.linesize_u, &mut self.blocks[4]);
1193                }
1194                if self.block_last_index[5] >= 0 {
1195                    let x = self.mb_x * 8;
1196                    let y = self.mb_y * 8;
1197                    let off_v = y * cur.linesize_v + x;
1198                    simple_idct_add(&mut cur.data_v[off_v..], cur.linesize_v, &mut self.blocks[5]);
1199                }
1200            }
1201            PixelFormat::Yuv422p => {
1202                let x = self.mb_x * 8;
1203                let y = self.mb_y * 16;
1204                for by in 0..2 {
1205                    let idx_u = 4 + by;
1206                    if self.block_last_index[idx_u] >= 0 {
1207                        let off_u = (y + by * 8) * cur.linesize_u + x;
1208                        simple_idct_add(&mut cur.data_u[off_u..], cur.linesize_u, &mut self.blocks[idx_u]);
1209                    }
1210                    let idx_v = 6 + by;
1211                    if self.block_last_index[idx_v] >= 0 {
1212                        let off_v = (y + by * 8) * cur.linesize_v + x;
1213                        simple_idct_add(&mut cur.data_v[off_v..], cur.linesize_v, &mut self.blocks[idx_v]);
1214                    }
1215                }
1216            }
1217            PixelFormat::Yuv444p => {
1218                for plane in 0..2 {
1219                    for by in 0..2 {
1220                        for bx in 0..2 {
1221                            let b = by * 2 + bx;
1222                            let x = base_x + bx * 8;
1223                            let y = base_y + by * 8;
1224                            let (dst, stride, idx) = if plane == 0 {
1225                                (&mut cur.data_u, cur.linesize_u, 4 + b)
1226                            } else {
1227                                (&mut cur.data_v, cur.linesize_v, 8 + b)
1228                            };
1229                            if self.block_last_index[idx] < 0 {
1230                                continue;
1231                            }
1232                            let off = y * stride + x;
1233                            simple_idct_add(&mut dst[off..], stride, &mut self.blocks[idx]);
1234                        }
1235                    }
1236                }
1237            }
1238        }
1239    }
1240
1241    fn mpeg2_decode_block_intra(&mut self, gb: &mut GetBits<'_>, n: usize) -> Result<()> {
1242        let vlcs = get_vlcs();
1243        let component = self.block_component(n);
1244        let quant_matrix = if component == 0 { &self.intra_matrix } else { &self.chroma_intra_matrix };
1245        let alt = self.alternate_scan;
1246        let scantable: &'static [u8; 64] = if alt {
1247            &FF_ALTERNATE_VERTICAL_SCAN
1248        } else {
1249            &FF_ZIGZAG_DIRECT
1250        };
1251        let qscale = self.qscale;
1252
1253        let diff = self.decode_dc(gb, component)?;
1254        let dc = self.last_dc[component] + diff;
1255        self.last_dc[component] = dc;
1256        self.blocks[n][0] = clip_coeff12(dc * (1 << (3 - self.intra_dc_precision)));
1257
1258        let mut mismatch: i32 = (self.blocks[n][0] as i32) ^ 1;
1259        let mut i: i32 = 0;
1260        let rl = if self.intra_vlc_format { &vlcs.rl_mpeg2 } else { &vlcs.rl_mpeg1 };
1261
1262        loop {
1263            let (level, run) = get_rl_vlc(gb, rl, super::vlctables::TEX_VLC_BITS, 2);
1264            if level == 127 {
1265                break;
1266            }
1267            if level != 0 {
1268                i += run as i32;
1269                if i > 63 {
1270                    return Err(DecodeError::InvalidData("ac"));
1271                }
1272                let j = scantable[i as usize] as usize;
1273                let mut lv = (level as i32 * qscale * quant_matrix[j] as i32) >> 4;
1274                if gb.get_bits1() != 0 {
1275                    lv = -lv;
1276                }
1277                let lv_c = clip_coeff12(lv) as i32;
1278                self.blocks[n][j] = lv_c as i16;
1279                mismatch ^= lv_c;
1280            } else {
1281                let run2 = gb.get_bits(6) as i32 + 1;
1282                let lv0 = gb.get_sbits(12);
1283                i += run2;
1284                if i > 63 {
1285                    return Err(DecodeError::InvalidData("ac"));
1286                }
1287                let j = scantable[i as usize] as usize;
1288                let mut lv = lv0 as i32;
1289                if lv < 0 {
1290                    lv = -(((-lv) * qscale * quant_matrix[j] as i32) >> 4);
1291                } else {
1292                    lv = (lv * qscale * quant_matrix[j] as i32) >> 4;
1293                }
1294                let lv_c = clip_coeff12(lv) as i32;
1295                self.blocks[n][j] = lv_c as i16;
1296                mismatch ^= lv_c;
1297            }
1298        }
1299
1300        self.blocks[n][63] ^= (mismatch & 1) as i16;
1301        self.block_last_index[n] = i;
1302        Ok(())
1303    }
1304
1305    fn mpeg2_decode_block_non_intra(&mut self, gb: &mut GetBits<'_>, n: usize) -> Result<()> {
1306        let vlcs = get_vlcs();
1307        let component = self.block_component(n);
1308        let quant_matrix = if component == 0 { &self.inter_matrix } else { &self.chroma_inter_matrix };
1309        let alt = self.alternate_scan;
1310        let scantable: &'static [u8; 64] = if alt {
1311            &FF_ALTERNATE_VERTICAL_SCAN
1312        } else {
1313            &FF_ZIGZAG_DIRECT
1314        };
1315        let qscale = self.qscale;
1316
1317        let mut mismatch: i32 = 1;
1318        let mut i: i32 = -1;
1319
1320        if gb.show_bits(1) != 0 {
1321            gb.skip_bits1();
1322            let sign = gb.get_bits1();
1323            let mut level = ((3 * qscale * quant_matrix[0] as i32) >> 5) as i32;
1324            if sign != 0 {
1325                level = -level;
1326            }
1327            let lv_c = clip_coeff12(level) as i32;
1328            self.blocks[n][0] = lv_c as i16;
1329            mismatch ^= lv_c;
1330            i += 1;
1331        }
1332
1333        while gb.bits_left() > 0 {
1334            if gb.show_bits(2) == 2 {
1335                gb.skip_bits(2);
1336                break;
1337            }
1338
1339            let (level0, run) = get_rl_vlc(gb, &vlcs.rl_mpeg1, super::vlctables::TEX_VLC_BITS, 2);
1340            if level0 != 0 {
1341                i += run as i32;
1342                if i > 63 {
1343                    return Err(DecodeError::InvalidData("ac"));
1344                }
1345                let j = scantable[i as usize] as usize;
1346                let mut lv = (((level0 as i32) * 2 + 1) * qscale * quant_matrix[j] as i32) >> 5;
1347                if gb.get_bits1() != 0 {
1348                    lv = -lv;
1349                }
1350                let lv_c = clip_coeff12(lv) as i32;
1351                self.blocks[n][j] = lv_c as i16;
1352                mismatch ^= lv_c;
1353            } else {
1354                let run2 = gb.get_bits(6) as i32 + 1;
1355                let lv0 = gb.get_sbits(12);
1356                i += run2;
1357                if i > 63 {
1358                    return Err(DecodeError::InvalidData("ac"));
1359                }
1360                let j = scantable[i as usize] as usize;
1361                let mut lv = lv0;
1362                if lv < 0 {
1363                    lv = -((((-lv) * 2 + 1) * qscale * quant_matrix[j] as i32) >> 5);
1364                } else {
1365                    lv = (((lv) * 2 + 1) * qscale * quant_matrix[j] as i32) >> 5;
1366                }
1367                let lv_c = clip_coeff12(lv) as i32;
1368                self.blocks[n][j] = lv_c as i16;
1369                mismatch ^= lv_c;
1370            }
1371        }
1372
1373        self.blocks[n][63] ^= (mismatch & 1) as i16;
1374        self.block_last_index[n] = i;
1375        Ok(())
1376    }
1377
1378    fn mpeg1_decode_block_intra(&mut self, gb: &mut GetBits<'_>, n: usize, qscale: i32) -> Result<()> {
1379        let component = if n <= 3 { 0 } else { (n - 4) + 1 };
1380        let diff = self.decode_dc(gb, component)?;
1381        let dc = self.last_dc[component] + diff;
1382        self.last_dc[component] = dc;
1383        self.blocks[n][0] = clip_coeff12(dc * self.intra_matrix[0] as i32);
1384
1385        let alt = self.alternate_scan;
1386        let scantable: &'static [u8; 64] = if alt {
1387            &FF_ALTERNATE_VERTICAL_SCAN
1388        } else {
1389            &FF_ZIGZAG_DIRECT
1390        };
1391        let vlcs = get_vlcs();
1392        let mut i: i32 = 0;
1393
1394        while gb.bits_left() > 0 {
1395            if gb.show_bits(2) == 2 {
1396                gb.skip_bits(2);
1397                break;
1398            }
1399
1400            let (level0, run) = get_rl_vlc(gb, &vlcs.rl_mpeg1, super::vlctables::TEX_VLC_BITS, 2);
1401            let mut level: i32;
1402            let run_i = run as i32;
1403            if level0 != 0 {
1404                i += run_i;
1405                if i > 63 {
1406                    return Err(DecodeError::InvalidData("ac"));
1407                }
1408                let j = scantable[i as usize] as usize;
1409                level = (level0 as i32 * qscale * self.intra_matrix[j] as i32) >> 4;
1410                level = (level - 1) | 1;
1411                if gb.get_bits1() != 0 {
1412                    level = -level;
1413                }
1414                self.blocks[n][j] = clip_coeff12(level);
1415            } else {
1416                let run2 = gb.get_bits(6) as i32 + 1;
1417                let mut lv = gb.get_sbits(8);
1418                if lv == -128 {
1419                    lv = gb.get_bits(8) as i32 - 256;
1420                } else if lv == 0 {
1421                    lv = gb.get_bits(8) as i32;
1422                }
1423                i += run2;
1424                if i > 63 {
1425                    return Err(DecodeError::InvalidData("ac"));
1426                }
1427                let j = scantable[i as usize] as usize;
1428                if lv < 0 {
1429                    lv = -lv;
1430                    level = (lv * qscale * self.intra_matrix[j] as i32) >> 4;
1431                    level = (level - 1) | 1;
1432                    level = -level;
1433                } else {
1434                    level = (lv * qscale * self.intra_matrix[j] as i32) >> 4;
1435                    level = (level - 1) | 1;
1436                }
1437                self.blocks[n][j] = clip_coeff12(level);
1438            }
1439        }
1440
1441        self.block_last_index[n] = i;
1442        Ok(())
1443    }
1444
1445    fn mpeg1_decode_block_inter(&mut self, gb: &mut GetBits<'_>, n: usize) -> Result<()> {
1446        let vlcs = get_vlcs();
1447        let alt = self.alternate_scan;
1448        let scantable: &'static [u8; 64] = if alt {
1449            &FF_ALTERNATE_VERTICAL_SCAN
1450        } else {
1451            &FF_ZIGZAG_DIRECT
1452        };
1453        let qscale = self.qscale;
1454        let quant_matrix = &self.inter_matrix;
1455
1456        let mut i: i32 = -1;
1457
1458        if gb.show_bits(1) != 0 {
1459            gb.skip_bits1();
1460            let sign = gb.get_bits1();
1461            let mut level = ((3 * qscale * quant_matrix[0] as i32) >> 5) as i32;
1462            level = (level - 1) | 1;
1463            if sign != 0 {
1464                level = -level;
1465            }
1466            self.blocks[n][0] = clip_coeff12(level);
1467            i += 1;
1468        }
1469
1470        while gb.bits_left() > 0 {
1471            if gb.show_bits(2) == 2 {
1472                gb.skip_bits(2);
1473                break;
1474            }
1475
1476            let (level0, run) = get_rl_vlc(gb, &vlcs.rl_mpeg1, super::vlctables::TEX_VLC_BITS, 2);
1477            let mut level: i32;
1478            if level0 != 0 {
1479                i += run as i32;
1480                if i > 63 {
1481                    return Err(DecodeError::InvalidData("ac"));
1482                }
1483                let j = scantable[i as usize] as usize;
1484                level = (((level0 as i32) * 2 + 1) * qscale * quant_matrix[j] as i32) >> 5;
1485                level = (level - 1) | 1;
1486                if gb.get_bits1() != 0 {
1487                    level = -level;
1488                }
1489                self.blocks[n][j] = clip_coeff12(level);
1490            } else {
1491                let run2 = gb.get_bits(6) as i32 + 1;
1492                let mut lv = gb.get_sbits(8);
1493                if lv == -128 {
1494                    lv = gb.get_bits(8) as i32 - 256;
1495                } else if lv == 0 {
1496                    lv = gb.get_bits(8) as i32;
1497                }
1498                i += run2;
1499                if i > 63 {
1500                    return Err(DecodeError::InvalidData("ac"));
1501                }
1502                let j = scantable[i as usize] as usize;
1503                if lv < 0 {
1504                    lv = -lv;
1505                    level = (((lv) * 2 + 1) * qscale * quant_matrix[j] as i32) >> 5;
1506                    level = (level - 1) | 1;
1507                    level = -level;
1508                } else {
1509                    level = (((lv) * 2 + 1) * qscale * quant_matrix[j] as i32) >> 5;
1510                    level = (level - 1) | 1;
1511                }
1512                self.blocks[n][j] = clip_coeff12(level);
1513            }
1514        }
1515
1516        self.block_last_index[n] = i;
1517        Ok(())
1518    }
1519
1520    fn decode_dc(&self, gb: &mut GetBits<'_>, component: usize) -> Result<i32> {
1521        let vlcs = get_vlcs();
1522        let code = if component == 0 {
1523            get_vlc2(gb, &vlcs.dc_lum.table, vlcs.dc_lum.bits, 2)
1524        } else {
1525            get_vlc2(gb, &vlcs.dc_chroma.table, vlcs.dc_chroma.bits, 2)
1526        };
1527        if code < 0 {
1528            return Err(DecodeError::InvalidData("dc"));
1529        }
1530        if code == 0 {
1531            Ok(0)
1532        } else {
1533            Ok(gb.get_xbits(code as usize))
1534        }
1535    }
1536
1537    fn scan_table(&self) -> &[u8; 64] {
1538        if self.alternate_scan {
1539            &FF_ALTERNATE_VERTICAL_SCAN
1540        } else {
1541            &FF_ZIGZAG_DIRECT
1542        }
1543    }
1544
1545    fn block_component(&self, n: usize) -> usize {
1546        match self.pix_fmt {
1547            PixelFormat::Yuv420p => {
1548                if n < 4 { 0 } else if n == 4 { 1 } else { 2 }
1549            }
1550            PixelFormat::Yuv422p => {
1551                if n < 4 { 0 } else if n < 6 { 1 } else { 2 }
1552            }
1553            PixelFormat::Yuv444p => {
1554                if n < 4 { 0 } else if n < 8 { 1 } else { 2 }
1555            }
1556        }
1557    }
1558
1559    fn load_default_matrices(&mut self) {
1560        self.load_default_intra_matrix();
1561        self.load_default_inter_matrix();
1562    }
1563
1564    fn load_default_intra_matrix(&mut self) {
1565        for i in 0..64 {
1566            let j = FF_ZIGZAG_DIRECT[i] as usize;
1567            let v = FF_MPEG1_DEFAULT_INTRA_MATRIX[i];
1568            self.intra_matrix[j] = v;
1569            self.chroma_intra_matrix[j] = v;
1570        }
1571    }
1572
1573    fn load_default_inter_matrix(&mut self) {
1574        for i in 0..64 {
1575            let j = FF_ZIGZAG_DIRECT[i] as usize;
1576            let v = FF_MPEG1_DEFAULT_NON_INTRA_MATRIX[i];
1577            self.inter_matrix[j] = v;
1578            self.chroma_inter_matrix[j] = v;
1579        }
1580    }
1581
1582    fn load_matrix_from_stream(&mut self, gb: &mut GetBits<'_>, intra: bool) -> Result<()> {
1583        for i in 0..64 {
1584            let j = FF_ZIGZAG_DIRECT[i] as usize;
1585            let mut v = gb.get_bits(8) as u16;
1586            if v == 0 {
1587                return Err(DecodeError::InvalidData("matrix"));
1588            }
1589            if intra && i == 0 && v != 8 {
1590                v = 8;
1591            }
1592            if intra {
1593                self.intra_matrix[j] = v;
1594                self.chroma_intra_matrix[j] = v;
1595            } else {
1596                self.inter_matrix[j] = v;
1597                self.chroma_inter_matrix[j] = v;
1598            }
1599        }
1600        Ok(())
1601    }
1602
1603    fn load_matrix_chroma_only(&mut self, gb: &mut GetBits<'_>, intra: bool) -> Result<()> {
1604        for i in 0..64 {
1605            let j = FF_ZIGZAG_DIRECT[i] as usize;
1606            let mut v = gb.get_bits(8) as u16;
1607            if v == 0 {
1608                return Err(DecodeError::InvalidData("matrix"));
1609            }
1610            if intra && i == 0 && v != 8 {
1611                v = 8;
1612            }
1613            if intra {
1614                self.chroma_intra_matrix[j] = v;
1615            } else {
1616                self.chroma_inter_matrix[j] = v;
1617            }
1618        }
1619        Ok(())
1620    }
1621}
1622
1623#[inline]
1624fn mpeg_get_qscale(gb: &mut GetBits<'_>, q_scale_type: i32) -> i32 {
1625    let code = gb.get_bits(5) as usize;
1626    if q_scale_type == 0 {
1627        // MPEG-1/2 linear quantiser scale uses even values (2..62).
1628        // FFmpeg keeps `qscale` in that internal representation: `code << 1`.
1629        (code as i32) << 1
1630    } else {
1631        FF_MPEG2_NON_LINEAR_QSCALE[code] as i32
1632    }
1633}
1634
1635#[inline]
1636fn has_mv_dir(mb_type: i16, dir: usize) -> bool {
1637    if dir == 0 {
1638        (mb_type & (MB_TYPE_FORWARD_MV | MB_TYPE_BIDIR_MV)) != 0
1639    } else {
1640        (mb_type & (MB_TYPE_BACKWARD_MV | MB_TYPE_BIDIR_MV)) != 0
1641    }
1642}
1643
1644#[inline]
1645fn mpeg_decode_motion(
1646    gb: &mut GetBits<'_>,
1647    mv_vlc: &super::vlc::Vlc,
1648    fcode: i32,
1649    pred: i32,
1650) -> Result<i32> {
1651    let code = get_vlc2(gb, &mv_vlc.table, mv_vlc.bits, 2);
1652    if code == 0 {
1653        return Ok(pred);
1654    }
1655    if code < 0 {
1656        return Err(DecodeError::InvalidData("mv"));
1657    }
1658    let sign = gb.get_bits1() as i32;
1659    let shift = fcode - 1;
1660    let mut val = code;
1661    if shift != 0 {
1662        val = (val - 1) << shift;
1663        val |= gb.get_bits(shift as usize) as i32;
1664        val += 1;
1665    }
1666    if sign != 0 {
1667        val = -val;
1668    }
1669    val += pred;
1670    Ok(GetBits::sign_extend(val, (5 + shift) as usize))
1671}
1672
1673#[inline]
1674fn get_dmv(gb: &mut GetBits<'_>) -> i32 {
1675    if gb.get_bits1() != 0 {
1676        1 - ((gb.get_bits1() as i32) << 1)
1677    } else {
1678        0
1679    }
1680}
1681
1682fn find_next_start_code(buf: &[u8], from: usize) -> Option<(usize, u8)> {
1683    if buf.len() < 4 {
1684        return None;
1685    }
1686    let mut i = from;
1687    while i + 3 < buf.len() {
1688        if buf[i] == 0 && buf[i + 1] == 0 && buf[i + 2] == 1 {
1689            return Some((i, buf[i + 3]));
1690        }
1691        i += 1;
1692    }
1693    None
1694}