]> git.nihav.org Git - nihav.git/blame - nihav-itu/src/codecs/h264/decoder_st.rs
avimux: do not record palette change chunks in OpenDML index
[nihav.git] / nihav-itu / src / codecs / h264 / decoder_st.rs
CommitLineData
93839abd
KS
1use std::sync::Arc;
2
47ecb2b7
KS
3use nihav_core::codecs::*;
4use nihav_core::io::bitreader::*;
5
6use super::*;
7
8struct H264Decoder {
9 info: NACodecInfoRef,
10 width: usize,
11 height: usize,
25f6045b
KS
12 disp_w: usize,
13 disp_h: usize,
47ecb2b7
KS
14 num_mbs: usize,
15 nal_len: u8,
93839abd 16 sps: Vec<Arc<SeqParameterSet>>,
47ecb2b7 17 cur_sps: usize,
93839abd 18 pps: Vec<Arc<PicParameterSet>>,
47ecb2b7
KS
19 cur_pps: usize,
20
21 skip_mode: FrameSkipMode,
22 deblock_skip: bool,
23
24 is_mbaff: bool,
25
26 cavlc_cb: CAVLCTables,
27
28 sstate: SliceState,
29
30 cur_pic: Option<PictureInfo>,
31 cur_id: u16,
32 has_pic: bool,
33 frame_refs: FrameRefs,
34
35 temporal_mv: bool,
36 deblock_mode: u8,
37 lf_alpha: i8,
38 lf_beta: i8,
39 is_s: bool,
40
41 ipcm_buf: [u8; 256 + 64 + 64],
42
43 mc_dsp: H264MC,
44
45 transform_8x8_mode: bool,
46}
47
48impl H264Decoder {
49 fn new() -> Self {
47ecb2b7
KS
50 H264Decoder{
51 info: NACodecInfoRef::default(),
52 width: 0,
53 height: 0,
25f6045b
KS
54 disp_w: 0,
55 disp_h: 0,
47ecb2b7
KS
56 num_mbs: 0,
57 nal_len: 0,
58 sps: Vec::with_capacity(1),
59 cur_sps: 0,
60 pps: Vec::with_capacity(3),
61 cur_pps: 0,
62
63 skip_mode: FrameSkipMode::default(),
64 deblock_skip: false,
65
66 is_mbaff: false,
67
68 cavlc_cb: CAVLCTables::new(),
69
70 sstate: SliceState::new(),
71 cur_pic: None,
72 cur_id: 0,
73 has_pic: false,
74 frame_refs: FrameRefs::new(),
75
76 temporal_mv: false,
77 deblock_mode: 0,
78 lf_alpha: 0,
79 lf_beta: 0,
80 is_s: false,
81
82 ipcm_buf: [0; 256 + 64 + 64],
83
71efc2dc 84 mc_dsp: H264MC::new(),
47ecb2b7
KS
85
86 transform_8x8_mode: false,
87 }
88 }
89 fn handle_nal(&mut self, src: &[u8], supp: &mut NADecoderSupport, skip_decoding: bool) -> DecoderResult<()> {
90 validate!(!src.is_empty());
91 validate!((src[0] & 0x80) == 0);
92 let nal_ref_idc = src[0] >> 5;
93 let nal_unit_type = src[0] & 0x1F;
94
95 let mut full_size = src.len() * 8;
96 for &byte in src.iter().rev() {
97 if byte == 0 {
98 full_size -= 8;
99 } else {
100 full_size -= (byte.trailing_zeros() + 1) as usize;
101 break;
102 }
103 }
104 validate!(full_size > 0);
105 match nal_unit_type {
106 1 | 5 if !skip_decoding => {
107 let is_idr = nal_unit_type == 5;
108 let mut br = BitReader::new(&src[..(full_size + 7)/8], BitReaderMode::BE);
109 br.skip(8)?;
110
93839abd 111 let slice_hdr = parse_slice_header(&mut br, self.sps.as_slice(), self.pps.as_slice(), is_idr, nal_ref_idc)?;
47ecb2b7
KS
112 validate!(br.tell() < full_size);
113 let full_id;
114 if slice_hdr.first_mb_in_slice == 0 {
115 validate!(self.cur_pic.is_none());
116 for (i, pps) in self.pps.iter().enumerate() {
117 if pps.pic_parameter_set_id == slice_hdr.pic_parameter_set_id {
118 self.cur_pps = i;
119 break;
120 }
121 }
122 for (i, sps) in self.sps.iter().enumerate() {
123 if sps.seq_parameter_set_id == self.pps[self.cur_pps].seq_parameter_set_id {
124 self.cur_sps = i;
125 break;
126 }
127 }
128
129 full_id = self.frame_refs.calc_picture_num(&slice_hdr, is_idr, nal_ref_idc, &self.sps[self.cur_sps]);
130
131 let sps = &self.sps[self.cur_sps];
132 if sps.chroma_format_idc != 1 || sps.bit_depth_luma != 8 || sps.bit_depth_chroma != 8 {
133println!(" chroma fmt {} bits {}/{}", sps.chroma_format_idc, sps.bit_depth_luma, sps.bit_depth_chroma);
134 return Err(DecoderError::NotImplemented);
135 }
136 //let pps = &self.pps[self.cur_pps];
137
138 if is_idr {
139 self.frame_refs.clear_refs();
140 }
141
142 self.width = sps.pic_width_in_mbs << 4;
143 self.height = sps.pic_height_in_mbs << 4;
144 self.num_mbs = sps.pic_width_in_mbs * sps.pic_height_in_mbs;
145 self.mc_dsp.set_dimensions(self.width, self.height);
146
147 self.is_mbaff = sps.mb_adaptive_frame_field && !slice_hdr.field_pic;
148 if self.is_mbaff {
149println!("MBAFF");
150 return Err(DecoderError::NotImplemented);
151 }
152 if !sps.frame_mbs_only {
153println!("PAFF?");
154 return Err(DecoderError::NotImplemented);
155 }
156
157//if slice_hdr.slice_type.is_b() { return Ok(()); }
158 self.cur_id = full_id as u16;
159 } else {
160 if let Some(ref mut pic) = self.cur_pic {
161 validate!(pic.cur_mb == slice_hdr.first_mb_in_slice);
162 let new_type = slice_hdr.slice_type.to_frame_type();
163 pic.pic_type = match (pic.pic_type, new_type) {
164 (FrameType::I, _) => new_type,
165 (_, FrameType::B) => FrameType::B,
166 _ => pic.pic_type,
167 };
168 full_id = pic.full_id;
169 } else {
170 return Ok(());//Err(DecoderError::InvalidData);
171 }
172 validate!(self.cur_pps < self.pps.len() && self.pps[self.cur_pps].pic_parameter_set_id == slice_hdr.pic_parameter_set_id);
173 }
174
175 let sps = &self.sps[self.cur_sps];
176 let pps = &self.pps[self.cur_pps];
177
178 self.temporal_mv = !slice_hdr.direct_spatial_mv_pred;
179 self.is_s = slice_hdr.slice_type == SliceType::SI || slice_hdr.slice_type == SliceType::SP;
180 self.deblock_mode = slice_hdr.disable_deblocking_filter_idc;
181 self.lf_alpha = slice_hdr.slice_alpha_c0_offset;
182 self.lf_beta = slice_hdr.slice_beta_offset;
183
184 self.frame_refs.select_refs(sps, &slice_hdr, full_id);
185
186 if slice_hdr.adaptive_ref_pic_marking_mode {
187 self.frame_refs.apply_adaptive_marking(&slice_hdr.adaptive_ref_pic_marking, slice_hdr.frame_num, 1 << self.sps[self.cur_sps].log2_max_frame_num)?;
188 }
189 if slice_hdr.first_mb_in_slice == 0 {
190 let ret = supp.pool_u8.get_free();
191 if ret.is_none() {
192 return Err(DecoderError::AllocError);
193 }
25f6045b
KS
194 let (w, h) = if ((self.disp_w + 15) & !15) == self.width && ((self.disp_h + 15) & !15) == self.height {
195 (self.disp_w, self.disp_h)
196 } else {
197 (self.width, self.height)
198 };
199 let tmp_vinfo = NAVideoInfo::new(w, h, false, YUV420_FORMAT);
47ecb2b7
KS
200 let mut buf = ret.unwrap();
201 if buf.get_info() != tmp_vinfo {
202 supp.pool_u8.reset();
203 supp.pool_u8.prealloc_video(tmp_vinfo, 4)?;
204 let ret = supp.pool_u8.get_free();
205 if ret.is_none() {
206 return Err(DecoderError::AllocError);
207 }
208 buf = ret.unwrap();
209 }
210 self.cur_pic = Some(PictureInfo {
211 id: slice_hdr.frame_num,
212 full_id,
11d7aef2
KS
213 user_id: full_id,
214 time: NATimeInfo::new(None, None, None, 0, 0),
47ecb2b7
KS
215 pic_type: slice_hdr.slice_type.to_frame_type(),
216 buf,
217 cur_mb: 0,
218 is_ref: nal_ref_idc != 0,
11d7aef2 219 is_idr,
47ecb2b7 220 long_term: get_long_term_id(is_idr, &slice_hdr),
93839abd 221 mv_info: NABufferRef::new(FrameMV::new(sps.pic_width_in_mbs, sps.pic_height_in_mbs)),
47ecb2b7
KS
222 });
223 }
224
225 self.transform_8x8_mode = pps.transform_8x8_mode;
226
227 self.sstate.reset(sps.pic_width_in_mbs, sps.pic_height_in_mbs, slice_hdr.first_mb_in_slice);
fe64781d
KS
228
229 let mut dst_pic = if let Some(ref pic) = self.cur_pic {
230 pic.clone()
231 } else {
232 return Err(DecoderError::InvalidData);
233 };
234 let mut dst_frm = NASimpleVideoFrame::from_video_buf(&mut dst_pic.buf).unwrap();
235 let dst_mv_info = &mut dst_pic.mv_info;
47ecb2b7 236 if !pps.entropy_coding_mode {
fe64781d 237 self.has_pic = self.decode_slice_cavlc(&mut br, &slice_hdr, full_size, &mut dst_frm, dst_mv_info)?;
47ecb2b7
KS
238 } else {
239 br.align();
e6aaad5c 240 let start = br.tell() / 8;
47ecb2b7
KS
241 let csrc = &src[start..];
242 validate!(csrc.len() >= 2);
243 let mut cabac = CABAC::new(csrc, slice_hdr.slice_type, slice_hdr.slice_qp, slice_hdr.cabac_init_idc as usize)?;
fe64781d 244 self.has_pic = self.decode_slice_cabac(&mut cabac, &slice_hdr, &mut dst_frm, dst_mv_info)?;
47ecb2b7
KS
245 }
246 },
247 2 => { // slice data partition A
248 //slice header
249 //slice id = read_ue()
250 //cat 2 slice data (all but MB layer residual)
251 return Err(DecoderError::NotImplemented);
252 },
253 3 => { // slice data partition B
254 //slice id = read_ue()
255 //if pps.redundant_pic_cnt_present { redundant_pic_cnt = read_ue() }
256 //cat 3 slice data (MB layer residual)
257 return Err(DecoderError::NotImplemented);
258 },
259 4 => { // slice data partition C
260 //slice id = read_ue()
261 //if pps.redundant_pic_cnt_present { redundant_pic_cnt = read_ue() }
262 //cat 4 slice data (MB layer residual)
263 return Err(DecoderError::NotImplemented);
264 },
265 6 => {}, //SEI
266 7 => {
267 let sps = parse_sps(&src[1..])?;
93839abd 268 self.sps.push(Arc::new(sps));
47ecb2b7
KS
269 },
270 8 => {
271 validate!(full_size >= 8 + 16);
272 let pps = parse_pps(&src[1..], &self.sps, full_size - 8)?;
273 let mut found = false;
274 for stored_pps in self.pps.iter_mut() {
275 if stored_pps.pic_parameter_set_id == pps.pic_parameter_set_id {
93839abd 276 *stored_pps = Arc::clone(&pps);
47ecb2b7
KS
277 found = true;
278 break;
279 }
280 }
281 if !found {
282 self.pps.push(pps);
283 }
284 },
285 9 => { // access unit delimiter
286 },
287 10 => {}, //end of sequence
288 11 => {}, //end of stream
289 12 => {}, //filler
290 _ => {},
291 };
292
293 Ok(())
294 }
5f223cdb 295 fn pred_mv(sstate: &mut SliceState, frame_refs: &SimplifiedSliceRefs, mb_info: &mut CurrentMBInfo, cur_id: u16, temporal_mv: bool, direct_8x8: bool) {
47ecb2b7
KS
296 let mb_type = mb_info.mb_type;
297 if !mb_type.is_4x4() {
298 let (pw, ph) = mb_type.size();
299 let mut xoff = 0;
300 let mut yoff = 0;
301 if mb_type == MBType::Direct || mb_type == MBType::BSkip {
302 sstate.predict_direct_mb(frame_refs, temporal_mv, direct_8x8, cur_id);
303 }
304 for part in 0..mb_type.num_parts() {
305 if !mb_type.is_l1(part) {
306 match mb_type {
307 MBType::PSkip => sstate.predict_pskip(),
308 MBType::BSkip | MBType::Direct => {
309 },
310 _ => {
311 sstate.predict(xoff, yoff, pw, ph, 0,
312 mb_info.mv_l0[part], mb_info.ref_l0[part]);
313 },
314 };
315 }
316 if !mb_type.is_l0(part) && mb_type != MBType::BSkip && mb_type != MBType::Direct {
317 sstate.predict(xoff, yoff, pw, ph, 1, mb_info.mv_l1[part], mb_info.ref_l1[part]);
318 }
319 if pw != 16 {
320 xoff += pw;
321 } else {
322 yoff += ph;
323 }
324 }
325 } else {
326 for part in 0..4 {
327 let sub_type = mb_info.sub_mb_type[part];
328 let mut xoff = (part & 1) * 8;
329 let mut yoff = (part & 2) * 4;
330 let orig_x = xoff;
331 let (pw, ph) = sub_type.size();
332 for subpart in 0..sub_type.num_parts() {
333 if sub_type != SubMBType::Direct8x8 {
334 if !sub_type.is_l1() {
335 sstate.predict(xoff, yoff, pw, ph, 0, mb_info.mv_l0[part * 4 + subpart], mb_info.ref_l0[part]);
336 }
337 if !sub_type.is_l0() {
338 sstate.predict(xoff, yoff, pw, ph, 1, mb_info.mv_l1[part * 4 + subpart], mb_info.ref_l1[part]);
339 }
340 } else {
341 for sblk in 0..4 {
342 sstate.predict_direct_sub(frame_refs, temporal_mv, direct_8x8, cur_id, (xoff / 4) + (sblk & 1) + (yoff / 4) * 4 + (sblk & 2) * 2);
343 }
344 }
345 xoff += pw;
346 if xoff == orig_x + 8 {
347 xoff -= 8;
348 yoff += ph;
349 }
350 }
351 }
352 }
353 }
354 #[allow(clippy::cognitive_complexity)]
fe64781d 355 fn handle_macroblock(&mut self, slice_hdr: &SliceHeader, mb_info: &mut CurrentMBInfo, slice_refs: &SimplifiedSliceRefs, frm: &mut NASimpleVideoFrame<u8>, mv_info: &mut FrameMV) {
47ecb2b7
KS
356 let pps = &self.pps[self.cur_pps];
357
358 let qp_y = mb_info.qp_y;
359 let qpr = ((qp_y as i8) + pps.chroma_qp_index_offset).max(0).min(51) as usize;
360 let qp_u = CHROMA_QUANTS[qpr];
361 let qpb = ((qp_y as i8) + pps.second_chroma_qp_index_offset).max(0).min(51) as usize;
362 let qp_v = CHROMA_QUANTS[qpb];
363
364 let tx_bypass = qp_y == 0 && self.sps[self.cur_sps].qpprime_y_zero_transform_bypass;
365
366 self.sstate.get_cur_mb().mb_type = mb_info.mb_type.into();
367 if mb_info.mb_type != MBType::PCM {
368 self.sstate.get_cur_mb().qp_y = qp_y;
369 self.sstate.get_cur_mb().qp_u = qp_u;
370 self.sstate.get_cur_mb().qp_v = qp_v;
371 self.sstate.get_cur_mb().transform_8x8 = mb_info.transform_size_8x8;
372 }
373 let has_dc = mb_info.mb_type.is_intra16x16() && mb_info.coded[24];
374 if has_dc {
375 idct_luma_dc(&mut mb_info.coeffs[24], qp_y);
376 for i in 0..16 {
377 mb_info.coeffs[i][0] = mb_info.coeffs[24][i];
378 }
379 }
754ab49a
KS
380 if !tx_bypass {
381 if !mb_info.transform_size_8x8 {
382 let quant_dc = !mb_info.mb_type.is_intra16x16();
fe64781d
KS
383 if quant_dc {
384 for (coded, coeffs) in mb_info.coded[..16].iter_mut().zip(mb_info.coeffs[..16].iter_mut()) {
385 if *coded {
386 idct(coeffs, qp_y);
387 } else if has_dc {
388 idct_dc(coeffs, qp_y, quant_dc);
389 *coded = true;
390 }
391 }
392 } else {
393 for (coded, coeffs) in mb_info.coded[..16].iter_mut().zip(mb_info.coeffs[..16].iter_mut()) {
394 if *coded {
395 idct_skip_dc(coeffs, qp_y);
396 } else if has_dc {
397 idct_dc(coeffs, qp_y, quant_dc);
398 *coded = true;
399 }
47ecb2b7 400 }
754ab49a
KS
401 }
402 } else {
403 for i in 0..4 {
404 if mb_info.coded[(i & 1) * 2 + (i & 2) * 4] {
405 dequant8x8(&mut mb_info.coeffs8x8[i].coeffs, &pps.scaling_list_8x8[!mb_info.mb_type.is_intra() as usize]);
406 idct8x8(&mut mb_info.coeffs8x8[i].coeffs, qp_y);
47ecb2b7 407 }
47ecb2b7
KS
408 }
409 }
754ab49a
KS
410 } else if !mb_info.transform_size_8x8 {
411 for i in 0..16 {
412 if !mb_info.coded[i] && has_dc {
413 mb_info.coded[i] = true;
47ecb2b7
KS
414 }
415 }
416 }
417 for chroma in 0..2 {
418 let qp_c = if chroma == 0 { qp_u } else { qp_v };
419 if mb_info.cbpc != 0 {
420 chroma_dc_transform(&mut mb_info.chroma_dc[chroma], qp_c);
421 }
422 for i in 0..4 {
423 let blk_no = 16 + chroma * 4 + i;
424 mb_info.coeffs[blk_no][0] = mb_info.chroma_dc[chroma][i];
425 if mb_info.coded[blk_no] {
fe64781d 426 idct_skip_dc(&mut mb_info.coeffs[blk_no], qp_c);
47ecb2b7
KS
427 } else if mb_info.coeffs[blk_no][0] != 0 {
428 idct_dc(&mut mb_info.coeffs[blk_no], qp_c, false);
429 mb_info.coded[blk_no] = true;
430 }
431 }
432 }
433 if !pps.entropy_coding_mode || mb_info.mb_type.is_skip() || mb_info.mb_type.is_intra() {
434 self.sstate.reset_mb_mv();
435 }
436 if !mb_info.mb_type.is_intra() {
5f223cdb 437 Self::pred_mv(&mut self.sstate, slice_refs, mb_info, self.cur_id, self.temporal_mv, self.sps[self.cur_sps].direct_8x8_inference);
47ecb2b7
KS
438 }
439 if !pps.constrained_intra_pred && mb_info.mb_type != MBType::Intra4x4 && mb_info.mb_type != MBType::Intra8x8 {
440 self.sstate.fill_ipred(IntraPredMode::DC);
441 }
442
443 let xpos = self.sstate.mb_x * 16;
444 let ypos = self.sstate.mb_y * 16;
fe64781d
KS
445
446 if mb_info.mb_type != MBType::PCM {
447 let weight_mode = if self.pps[self.cur_pps].weighted_pred && slice_hdr.slice_type.is_p() {
448 1
449 } else if slice_hdr.slice_type.is_b() {
450 self.pps[self.cur_pps].weighted_bipred_idc
451 } else {
452 0
453 };
454 recon_mb(frm, slice_hdr, mb_info, &mut self.sstate, slice_refs, &mut self.mc_dsp, weight_mode);
455 } else {
456 for (dline, src) in frm.data[frm.offset[0] + xpos + ypos * frm.stride[0]..].chunks_mut(frm.stride[0]).take(16).zip(self.ipcm_buf.chunks(16)) {
457 dline[..16].copy_from_slice(src);
47ecb2b7 458 }
fe64781d
KS
459 for (dline, src) in frm.data[frm.offset[1] + xpos/2 + ypos/2 * frm.stride[1]..].chunks_mut(frm.stride[1]).take(8).zip(self.ipcm_buf[256..].chunks(8)) {
460 dline[..8].copy_from_slice(src);
461 }
462 for (dline, src) in frm.data[frm.offset[2] + xpos/2 + ypos/2 * frm.stride[2]..].chunks_mut(frm.stride[2]).take(8).zip(self.ipcm_buf[256 + 64..].chunks(8)) {
463 dline[..8].copy_from_slice(src);
464 }
465 }
47ecb2b7
KS
466/*match mb_info.mb_type {
467MBType::BSkip | MBType::Direct | MBType::B16x16(_) | MBType::B16x8(_, _) | MBType::B8x16(_, _) | MBType::B8x8 => {
468 let dstride = frm.stride[0];
469 let dst = &mut frm.data[frm.offset[0] + self.sstate.mb_x * 16 + self.sstate.mb_y * 16 * dstride..];
470 for el in dst[..16].iter_mut() { *el = 255; }
471 for row in dst.chunks_mut(dstride).skip(1).take(15) {
472 row[0] = 255;
473 }
474},
475_ => {},
476};*/
fe64781d
KS
477 self.sstate.save_ipred_context(frm);
478
479 let mb_pos = self.sstate.mb_x + self.sstate.mb_y * mv_info.mb_stride;
480 let mut mb = FrameMBInfo::new();
481 mb.mb_type = mb_info.mb_type.into();
482 for blk4 in 0..16 {
483 mb.mv[blk4] = self.sstate.get_cur_blk4(blk4).mv;
47ecb2b7 484 }
fe64781d
KS
485 for blk8 in 0..4 {
486 mb.ref_poc[blk8] = slice_refs.map_refs(self.sstate.get_cur_blk8(blk8).ref_idx);
487 mb.ref_idx[blk8] = self.sstate.get_cur_blk8(blk8).ref_idx;
47ecb2b7 488 }
fe64781d
KS
489 mv_info.mbs[mb_pos] = mb;
490
47ecb2b7 491 if !self.deblock_skip && self.deblock_mode != 1 {
5f223cdb 492 self.sstate.fill_deblock(slice_refs, self.deblock_mode, self.is_s);
fe64781d 493 loop_filter_mb(frm, &self.sstate, self.lf_alpha, self.lf_beta);
47ecb2b7
KS
494 }
495 self.sstate.next_mb();
496 }
fe64781d 497 fn decode_slice_cavlc(&mut self, br: &mut BitReader, slice_hdr: &SliceHeader, full_size: usize, frm: &mut NASimpleVideoFrame<u8>, mv_info: &mut FrameMV) -> DecoderResult<bool> {
47ecb2b7
KS
498 const INTRA_CBP: [u8; 48] = [
499 47, 31, 15, 0, 23, 27, 29, 30, 7, 11, 13, 14, 39, 43, 45, 46,
500 16, 3, 5, 10, 12, 19, 21, 26, 28, 35, 37, 42, 44, 1, 2, 4,
501 8, 17, 18, 20, 24, 6, 9, 22, 25, 32, 33, 34, 36, 40, 38, 41
502 ];
503 const INTER_CBP: [u8; 48] = [
504 0, 16, 1, 2, 4, 8, 32, 3, 5, 10, 12, 15, 47, 7, 11, 13,
505 14, 6, 9, 31, 35, 37, 42, 44, 33, 34, 36, 40, 39, 43, 45, 46,
506 17, 18, 20, 24, 19, 21, 26, 28, 23, 27, 29, 30, 22, 25, 38, 41
507 ];
508
e6aaad5c 509 let mut mb_idx = slice_hdr.first_mb_in_slice;
47ecb2b7
KS
510 let mut mb_info = CurrentMBInfo { qp_y: slice_hdr.slice_qp, ..Default::default() };
511 let skip_type = if slice_hdr.slice_type.is_p() { MBType::PSkip } else { MBType::BSkip };
5f223cdb
KS
512
513 let slice_refs = self.frame_refs.cur_refs.clone();
514 let sslice_refs = SimplifiedSliceRefs::new(&slice_refs);
515
47ecb2b7
KS
516 while br.tell() < full_size && mb_idx < self.num_mbs {
517 mb_info.coded = [false; 25];
518 mb_info.ref_l0 = [ZERO_REF; 4];
519 mb_info.ref_l1 = [ZERO_REF; 4];
520 mb_info.mv_l0 = [ZERO_MV; 16];
521 mb_info.mv_l1 = [ZERO_MV; 16];
522 mb_info.chroma_dc = [[0; 4]; 2];
523 mb_info.cbpy = 0;
524 mb_info.cbpc = 0;
525
526 if !slice_hdr.slice_type.is_intra() {
527 let mb_skip_run = br.read_ue()? as usize;
528 validate!(mb_idx + mb_skip_run <= self.num_mbs);
529 mb_info.mb_type = skip_type;
530 for _ in 0..mb_skip_run {
fe64781d 531 self.handle_macroblock(slice_hdr, &mut mb_info, &sslice_refs, frm, mv_info);
47ecb2b7
KS
532 mb_idx += 1;
533 }
534 if mb_idx == self.num_mbs || br.tell() >= full_size {
535 break;
536 }
537 }
538 if br.tell() < full_size {
539 if self.is_mbaff && ((mb_idx & 1) == 0) {
540 let _mb_field_decoding = br.read_bool()?;
541 }
542 let mut mb_type = decode_mb_type_cavlc(br, slice_hdr)?;
543 mb_info.mb_type = mb_type;
544 mb_info.transform_size_8x8 = false;
545 if mb_type == MBType::PCM {
546 br.align();
547 for pix in self.ipcm_buf[..256 + 64 + 64].iter_mut() {
548 *pix = br.read(8)? as u8;
549 }
550 self.sstate.fill_ncoded(16);
551 } else {
552 if self.transform_8x8_mode && mb_type == MBType::Intra4x4 {
553 mb_info.transform_size_8x8 = br.read_bool()?;
554 if mb_info.transform_size_8x8 {
555 mb_type = MBType::Intra8x8;
556 mb_info.mb_type = MBType::Intra8x8;
557 }
558 }
559 decode_mb_pred_cavlc(br, slice_hdr, mb_type, &mut self.sstate, &mut mb_info)?;
560 let (cbpy, cbpc) = if let MBType::Intra16x16(_, cbpy, cbpc) = mb_type {
561 (cbpy, cbpc)
562 } else {
563 let cbp_id = br.read_ue()? as usize;
564 validate!(cbp_id < INTRA_CBP.len());
565 let cbp = if mb_type == MBType::Intra4x4 || mb_type == MBType::Intra8x8 {
566 INTRA_CBP[cbp_id]
567 } else {
568 INTER_CBP[cbp_id]
569 };
570 if self.transform_8x8_mode && (cbp & 0xF) != 0 && mb_info.can_have_8x8_tx(self.sps[self.cur_sps].direct_8x8_inference) {
571 mb_info.transform_size_8x8 = br.read_bool()?;
572 }
573 ((cbp & 0xF), (cbp >> 4))
574 };
575 mb_info.cbpy = cbpy;
576 mb_info.cbpc = cbpc;
577 self.sstate.get_cur_mb().cbp = (cbpc << 4) | cbpy;
578 if cbpy != 0 || cbpc != 0 || mb_type.is_intra16x16() {
579 let mb_qp_delta = br.read_se()?;
580 validate!(mb_qp_delta >= -26 && mb_qp_delta <= 25);
581 let new_qp = mb_qp_delta + i32::from(mb_info.qp_y);
582 mb_info.qp_y = if new_qp < 0 {
583 (new_qp + 52) as u8
584 } else if new_qp >= 52 {
585 (new_qp - 52) as u8
586 } else {
587 new_qp as u8
588 };
589 mb_info.coeffs = [[0; 16]; 25];
590 if self.transform_8x8_mode {
591 mb_info.clear_coeffs8x8();
592 }
593 mb_info.chroma_dc = [[0; 4]; 2];
594 decode_residual_cavlc(br, &mut self.sstate, &mut mb_info, &self.cavlc_cb)?;
595 }
596 }
fe64781d 597 self.handle_macroblock(slice_hdr, &mut mb_info, &sslice_refs, frm, mv_info);
47ecb2b7
KS
598 }
599 mb_idx += 1;
600 }
601 if let Some(ref mut pic) = self.cur_pic {
602 pic.cur_mb = mb_idx;
603 }
604 Ok(mb_idx == self.num_mbs)
605 }
fe64781d 606 fn decode_slice_cabac(&mut self, cabac: &mut CABAC, slice_hdr: &SliceHeader, frm: &mut NASimpleVideoFrame<u8>, mv_info: &mut FrameMV) -> DecoderResult<bool> {
e6aaad5c 607 let mut mb_idx = slice_hdr.first_mb_in_slice;
47ecb2b7
KS
608 let mut prev_mb_skipped = false;
609 let skip_type = if slice_hdr.slice_type.is_p() { MBType::PSkip } else { MBType::BSkip };
610 let mut last_qp_diff = false;
611
612 let mut mb_info = CurrentMBInfo { qp_y: slice_hdr.slice_qp, ..Default::default() };
613
5f223cdb
KS
614 let slice_refs = self.frame_refs.cur_refs.clone();
615 let sslice_refs = SimplifiedSliceRefs::new(&slice_refs);
616
47ecb2b7
KS
617 while mb_idx < self.num_mbs {
618 mb_info.coded = [false; 25];
619 mb_info.ref_l0 = [ZERO_REF; 4];
620 mb_info.ref_l1 = [ZERO_REF; 4];
621 mb_info.mv_l0 = [ZERO_MV; 16];
622 mb_info.mv_l1 = [ZERO_MV; 16];
623 mb_info.chroma_dc = [[0; 4]; 2];
624 mb_info.cbpy = 0;
625 mb_info.cbpc = 0;
626 let mb_skip = cabac_decode_mbskip(cabac, &self.sstate, slice_hdr);
627 if !mb_skip {
628 if self.is_mbaff && (((mb_idx & 1) == 0) || (prev_mb_skipped && ((mb_idx & 1) == 1))) {
629 let _mb_field_decoding = cabac.decode_bit(70);
630 }
631 let mut mb_type = cabac_decode_mb_type(cabac, slice_hdr, &self.sstate);
632 mb_info.mb_type = mb_type;
633 mb_info.transform_size_8x8 = false;
634 if mb_type == MBType::PCM {
635 let ipcm_size = 256 + 64 + 64;
636 validate!(cabac.pos + ipcm_size <= cabac.src.len());
637 self.ipcm_buf[..ipcm_size].copy_from_slice(&cabac.src[cabac.pos..][..ipcm_size]);
638 cabac.pos += ipcm_size;
639 cabac.reinit()?;
640 last_qp_diff = false;
641 } else {
642 if self.transform_8x8_mode && mb_type == MBType::Intra4x4 {
643 let mut ctx = 0;
644 if self.sstate.get_top_mb().transform_8x8 {
645 ctx += 1;
646 }
647 if self.sstate.get_left_mb().transform_8x8 {
648 ctx += 1;
649 }
650 mb_info.transform_size_8x8 = cabac.decode_bit(399 + ctx);
651 if mb_info.transform_size_8x8 {
652 mb_type = MBType::Intra8x8;
653 mb_info.mb_type = MBType::Intra8x8;
654 }
655 }
656 decode_mb_pred_cabac(cabac, slice_hdr, mb_type, &mut self.sstate, &mut mb_info);
657 let (cbpy, cbpc) = if let MBType::Intra16x16(_, cbpy, cbpc) = mb_type {
658 (cbpy, cbpc)
659 } else {
660 decode_cbp_cabac(cabac, &self.sstate)
661 };
662 if self.transform_8x8_mode && cbpy != 0 && mb_info.can_have_8x8_tx(self.sps[self.cur_sps].direct_8x8_inference) {
663 let mut ctx = 0;
664 if self.sstate.get_top_mb().transform_8x8 {
665 ctx += 1;
666 }
667 if self.sstate.get_left_mb().transform_8x8 {
668 ctx += 1;
669 }
670 mb_info.transform_size_8x8 = cabac.decode_bit(399 + ctx);
671 }
672 if mb_type.is_intra() {
673 self.sstate.get_cur_mb().cmode = mb_info.chroma_ipred;
674 }
675 mb_info.cbpy = cbpy;
676 mb_info.cbpc = cbpc;
677 self.sstate.get_cur_mb().cbp = (cbpc << 4) | cbpy;
678 if cbpy != 0 || cbpc != 0 || mb_type.is_intra16x16() {
679 let mb_qp_delta = decode_mb_qp_delta_cabac(cabac, last_qp_diff as usize);
680 validate!(mb_qp_delta >= -26 && mb_qp_delta <= 25);
681 last_qp_diff = mb_qp_delta != 0;
682 let new_qp = mb_qp_delta + i32::from(mb_info.qp_y);
683 mb_info.qp_y = if new_qp < 0 {
684 (new_qp + 52) as u8
685 } else if new_qp >= 52 {
686 (new_qp - 52) as u8
687 } else {
688 new_qp as u8
689 };
690 mb_info.coeffs = [[0; 16]; 25];
691 if self.transform_8x8_mode {
692 mb_info.clear_coeffs8x8();
693 }
694 mb_info.chroma_dc = [[0; 4]; 2];
695 decode_residual_cabac(cabac, &mut self.sstate, &mut mb_info);
696 } else {
697 last_qp_diff = false;
698 }
699 }
700 } else {
701 mb_info.mb_type = skip_type;
702 mb_info.transform_size_8x8 = false;
703 last_qp_diff = false;
704 }
fe64781d 705 self.handle_macroblock(slice_hdr, &mut mb_info, &sslice_refs, frm, mv_info);
47ecb2b7
KS
706 prev_mb_skipped = mb_skip;
707 if !(self.is_mbaff && ((mb_idx & 1) == 0)) && cabac.decode_terminate() {
708 if let Some(ref mut pic) = self.cur_pic {
709 pic.cur_mb = mb_idx + 1;
710 }
711 return Ok(mb_idx + 1 == self.num_mbs);
712 }
713 mb_idx += 1;
714 }
715 Err(DecoderError::InvalidData)
716 }
717}
718
719impl NADecoder for H264Decoder {
720 fn init(&mut self, supp: &mut NADecoderSupport, info: NACodecInfoRef) -> DecoderResult<()> {
721 if let NACodecTypeInfo::Video(vinfo) = info.get_properties() {
722 let fmt = YUV420_FORMAT;
723 let myinfo = NACodecTypeInfo::Video(NAVideoInfo::new(0, 0, false, fmt));
724 self.info = NACodecInfo::new_ref(info.get_name(), myinfo, info.get_extradata()).into_ref();
725
726 let edata = info.get_extradata().unwrap();
727//print!("edata:"); for &el in edata.iter() { print!(" {:02X}", el); } println!();
728 if edata.len() > 11 && &edata[0..4] == b"avcC" {
729 let mut mr = MemoryReader::new_read(edata.as_slice());
730 let mut br = ByteReader::new(&mut mr);
731 let mut nal_buf = Vec::new();
732
733 br.read_skip(4)?;
734 let version = br.read_byte()?;
735 validate!(version == 1);
736 let profile = br.read_byte()?;
737 let _compatibility = br.read_byte()?;
738 let _level = br.read_byte()?;
739 let b = br.read_byte()?;
344e803e 740 //validate!((b & 0xFC) == 0xFC);
47ecb2b7
KS
741 self.nal_len = (b & 3) + 1;
742 let b = br.read_byte()?;
344e803e 743 //validate!((b & 0xE0) == 0xE0);
47ecb2b7
KS
744 let num_sps = (b & 0x1F) as usize;
745 for _ in 0..num_sps {
746 let len = br.read_u16be()? as usize;
747 let offset = br.tell() as usize;
748 validate!((br.peek_byte()? & 0x1F) == 7);
749 let _size = unescape_nal(&edata[offset..][..len], &mut nal_buf);
750 self.handle_nal(&nal_buf, supp, true)?;
751 br.read_skip(len)?;
752 }
753 let num_pps = br.read_byte()? as usize;
754 for _ in 0..num_pps {
755 let len = br.read_u16be()? as usize;
756 let offset = br.tell() as usize;
757 validate!((br.peek_byte()? & 0x1F) == 8);
758 let _size = unescape_nal(&edata[offset..][..len], &mut nal_buf);
759 self.handle_nal(&nal_buf, supp, true)?;
760 br.read_skip(len)?;
761 }
762 if br.left() > 0 {
763 match profile {
764 100 | 110 | 122 | 144 => {
765 let b = br.read_byte()?;
e12dabcd
KS
766 // some encoders put something different here
767 if (b & 0xFC) != 0xFC {
768 return Ok(());
769 }
47ecb2b7
KS
770 // b & 3 -> chroma format
771 let b = br.read_byte()?;
772 validate!((b & 0xF8) == 0xF8);
773 // b & 7 -> luma depth minus 8
774 let b = br.read_byte()?;
775 validate!((b & 0xF8) == 0xF8);
776 // b & 7 -> chroma depth minus 8
777 let num_spsext = br.read_byte()? as usize;
778 for _ in 0..num_spsext {
779 let len = br.read_u16be()? as usize;
780 // parse spsext
781 br.read_skip(len)?;
782 }
783 },
784 _ => {},
785 };
786 }
787 } else {
788 return Err(DecoderError::NotImplemented);
789 }
790
791 self.width = vinfo.get_width();
792 self.height = vinfo.get_height();
25f6045b
KS
793 self.disp_w = self.width;
794 self.disp_h = self.height;
47ecb2b7
KS
795
796 if (self.width == 0 || self.height == 0) && !self.sps.is_empty() {
797 self.width = self.sps[0].pic_width_in_mbs * 16;
798 self.height = self.sps[0].pic_height_in_mbs * 16;
799 }
800
801 let num_bufs = if !self.sps.is_empty() {
e6aaad5c 802 self.sps[0].num_ref_frames + 1
47ecb2b7
KS
803 } else {
804 3
805 }.max(16 + 1);
806 supp.pool_u8.set_dec_bufs(num_bufs);
807 supp.pool_u8.prealloc_video(NAVideoInfo::new(self.width, self.height, false, fmt), 4)?;
808
809 Ok(())
810 } else {
811 Err(DecoderError::InvalidData)
812 }
813 }
814 fn decode(&mut self, supp: &mut NADecoderSupport, pkt: &NAPacket) -> DecoderResult<NAFrameRef> {
815 let src = pkt.get_buffer();
816
817 let mut mr = MemoryReader::new_read(&src);
818 let mut br = ByteReader::new(&mut mr);
819 let mut nal_buf = Vec::with_capacity(src.len());
820 if self.nal_len > 0 {
821 let mut skip_decoding = false;
822 if self.skip_mode != FrameSkipMode::None {
823 let mut pic_type = FrameType::I;
824 let mut is_ref = false;
825 while br.left() > 0 {
826 let size = match self.nal_len {
827 1 => br.read_byte()? as usize,
828 2 => br.read_u16be()? as usize,
829 3 => br.read_u24be()? as usize,
830 4 => br.read_u32be()? as usize,
831 _ => unreachable!(),
832 };
833 validate!(br.left() >= (size as i64));
834 let offset = br.tell() as usize;
835 let size = unescape_nal(&src[offset..][..size], &mut nal_buf);
836 validate!(size > 0);
837 let nal_ref_idc = nal_buf[0] >> 5;
838 let nal_unit_type = nal_buf[0] & 0x1F;
839 if nal_unit_type == 1 || nal_unit_type == 5 {
840 let mut bitr = BitReader::new(&nal_buf[1..], BitReaderMode::BE);
841 let (first_mb, slice_type) = parse_slice_header_minimal(&mut bitr)?;
842 if first_mb == 0 && nal_ref_idc != 0 {
843 is_ref = true;
844 }
845 let new_type = slice_type.to_frame_type();
846 pic_type = match (pic_type, new_type) {
847 (FrameType::I, _) => new_type,
848 (_, FrameType::B) => FrameType::B,
849 _ => pic_type,
850 };
851 }
852 br.read_skip(size)?;
853 }
854 match self.skip_mode {
855 FrameSkipMode::IntraOnly => {
856 skip_decoding = pic_type != FrameType::I;
857 },
858 FrameSkipMode::KeyframesOnly => {
859 if !is_ref {
860 skip_decoding = true;
861 }
862 },
863 _ => {},
864 };
865 br.seek(SeekFrom::Start(0))?;
866 }
867 while br.left() > 0 {
868 let size = match self.nal_len {
869 1 => br.read_byte()? as usize,
870 2 => br.read_u16be()? as usize,
871 3 => br.read_u24be()? as usize,
872 4 => br.read_u32be()? as usize,
873 _ => unreachable!(),
874 };
875 validate!(br.left() >= (size as i64));
876 let offset = br.tell() as usize;
877 let _size = unescape_nal(&src[offset..][..size], &mut nal_buf);
878 self.handle_nal(nal_buf.as_slice(), supp, skip_decoding)?;
879 br.read_skip(size)?;
880 }
881 } else {
882//todo NAL detection
883 unimplemented!();
884 }
885
886 let (bufinfo, ftype, dts) = if self.has_pic && self.cur_pic.is_some() {
887 let mut npic = None;
888 std::mem::swap(&mut self.cur_pic, &mut npic);
889 let cpic = npic.unwrap();
890 let ret = (NABufferType::Video(cpic.buf.clone()), cpic.pic_type, Some(u64::from(cpic.full_id)));
891 if cpic.is_ref {
892 self.frame_refs.add_short_term(cpic.clone(), self.sps[self.cur_sps].num_ref_frames);
893 }
894 if let Some(lt_idx) = cpic.long_term {
895 self.frame_refs.add_long_term(lt_idx, cpic);
896 }
897 ret
898 } else {
899 (NABufferType::None, FrameType::Skip, None)
900 };
901
902 let mut frm = NAFrame::new_from_pkt(pkt, self.info.clone(), bufinfo);
903 frm.set_keyframe(ftype == FrameType::I);
904 if let (Some(mydts), None) = (dts, frm.get_dts()) {
905 frm.set_dts(Some(mydts));
906 }
907 if let Some(dts) = dts {
908 frm.set_id(dts as i64);
909 }
910 frm.set_frame_type(ftype);
911 Ok(frm.into_ref())
912 }
913 fn flush(&mut self) {
914 }
915}
916
917impl NAOptionHandler for H264Decoder {
918 fn get_supported_options(&self) -> &[NAOptionDefinition] { DECODER_OPTIONS }
919 fn set_options(&mut self, options: &[NAOption]) {
920 for option in options.iter() {
921 for opt_def in DECODER_OPTIONS.iter() {
922 if opt_def.check(option).is_ok() {
923 match (option.name, &option.value) {
924 (FRAME_SKIP_OPTION, NAValue::String(ref strval)) => {
925 if let Ok(smode) = FrameSkipMode::from_str(strval) {
926 self.skip_mode = smode;
927 }
928 },
929 (DEBLOCK_SKIP_OPTION, NAValue::Bool(val)) => {
930 self.deblock_skip = *val;
931 },
932 _ => {},
933 }
934 }
935 }
936 }
937 }
938 fn query_option_value(&self, name: &str) -> Option<NAValue> {
939 match name {
940 FRAME_SKIP_OPTION => Some(NAValue::String(self.skip_mode.to_string())),
941 DEBLOCK_SKIP_OPTION => Some(NAValue::Bool(self.deblock_skip)),
942 _ => None,
943 }
944 }
945}
946
947pub fn get_decoder() -> Box<dyn NADecoder + Send> {
948 Box::new(H264Decoder::new())
949}