Skip to main content

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