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