test_encode_decode_dav1d.rs 3.77 KB
Newer Older
rzumer's avatar
rzumer committed
1 2 3 4 5 6 7 8 9
// Copyright (c) 2018, The rav1e contributors. All rights reserved
//
// This source code is subject to the terms of the BSD 2 Clause License and
// the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
// was not distributed with this source code in the LICENSE file, you can
// obtain it at www.aomedia.org/license/software. If the Alliance for Open
// Media Patent License 1.0 was not distributed with this source code in the
// PATENTS file, you can obtain it at www.aomedia.org/license/patent.

10
use super::*;
11
use std::marker::PhantomData;
Raphaël Zumer's avatar
Raphaël Zumer committed
12
use std::{mem, ptr, slice};
13
use std::collections::VecDeque;
14
use crate::util::{Pixel, CastFromPrimitive};
15
use crate::test_encode_decode::{compare_plane, TestDecoder, DecodeResult};
16

17 18
use dav1d_sys::*;

19 20 21
pub(crate) struct Dav1dDecoder<T: Pixel> {
  dec: *mut Dav1dContext,
  pixel: PhantomData<T>
22 23
}

24
impl<T: Pixel> TestDecoder<T> for Dav1dDecoder<T> {
25 26 27
  fn setup_decoder(_w: usize, _h: usize) -> Self {
    unsafe {
      let mut settings = mem::uninitialized();
28
      let mut dec: Dav1dDecoder<T> = mem::uninitialized();
29

30
      dav1d_default_settings(&mut settings);
31

32
      let ret = dav1d_open(&mut dec.dec, &settings);
33

34 35 36
      if ret != 0 {
        panic!("Cannot instantiate the decoder {}", ret);
      }
37

38 39
      dec
    }
40 41
  }

42
  fn decode_packet(&mut self, packet: &[u8], rec_fifo: &mut VecDeque<Frame<T>>, w: usize, h: usize, bit_depth: usize) -> DecodeResult {
43 44 45 46 47 48 49 50 51 52 53 54
    let mut corrupted_count = 0;
    unsafe {
      let mut data: Dav1dData = mem::zeroed();
      let ptr = dav1d_data_create(&mut data, packet.len());
      ptr::copy_nonoverlapping(packet.as_ptr(), ptr, packet.len());
      let ret = dav1d_send_data(
        self.dec, &mut data
      );
      println!("Decoded. -> {}", ret);
      if ret != 0 {
        corrupted_count += 1;
      }
55

56 57 58 59 60 61 62 63
      if ret == 0 {
        loop {
          let mut pic: Dav1dPicture = mem::zeroed();
          println!("Retrieving frame");
          let ret = dav1d_get_picture(self.dec, &mut pic);
          println!("Retrieved.");
          if ret == -(EAGAIN as i32) {
            return DecodeResult::Done;
64
          }
65 66
          if ret != 0 {
            panic!("Decode fail");
67
          }
68 69 70

          let rec = rec_fifo.pop_front().unwrap();
          compare_pic(&pic, &rec, bit_depth, w, h);
71
        }
72
      }
73 74 75 76 77
    }
    if corrupted_count > 0 {
      DecodeResult::Corrupted(corrupted_count)
    } else {
      DecodeResult::NotDone
78
    }
79 80 81
  }
}

82
impl<T: Pixel> Drop for Dav1dDecoder<T> {
83 84
  fn drop(&mut self) {
    unsafe { dav1d_close(&mut self.dec) };
85 86 87
  }
}

88
fn compare_pic<T: Pixel>(pic: &Dav1dPicture, frame: &Frame<T>, bit_depth: usize, width: usize, height: usize) {
89
  use plane::Plane;
90

91
  let cmp_plane = |data, stride, frame_plane: &Plane<T>| {
Frank Bossen's avatar
Frank Bossen committed
92 93
    let w = width >> frame_plane.cfg.xdec;
    let h = height >> frame_plane.cfg.ydec;
94 95 96
    let rec_stride = frame_plane.cfg.stride;

    if bit_depth > 8 {
97
      let stride = stride / 2;
98
      let dec = unsafe {
99 100
        let data = data as *const u16;
        let size = stride * h;
101 102 103 104 105

        slice::from_raw_parts(data, size)
      };

      let rec: Vec<u16> =
106
        frame_plane.data_origin().iter().map(|&v| u16::cast_from(v)).collect();
107

108
      compare_plane::<u16>(&rec[..], rec_stride, dec, stride, w, h);
109 110
    } else {
      let dec = unsafe {
111 112
        let data = data as *const u8;
        let size = stride * h;
113 114 115 116 117

        slice::from_raw_parts(data, size)
      };

      let rec: Vec<u8> =
118
        frame_plane.data_origin().iter().map(|&v| u8::cast_from(v)).collect();
119

120
      compare_plane::<u8>(&rec[..], rec_stride, dec, stride, w, h);
121
    }
122 123 124 125 126 127 128 129
  };

  let lstride = pic.stride[0] as usize;
  let cstride = pic.stride[1] as usize;

  cmp_plane(pic.data[0], lstride, &frame.planes[0]);
  cmp_plane(pic.data[1], cstride, &frame.planes[1]);
  cmp_plane(pic.data[2], cstride, &frame.planes[2]);
130
}