Skip to content

Commit

Permalink
backport from dav1d 1.2.0: picture: allow storing an array of `Dav1…
Browse files Browse the repository at this point in the history
…dITUTT35` entries (#993)

Reopening #528 since it got closed because I deleted the target branch,
which I guess happens when the PR branch is on a fork.
  • Loading branch information
kkysen authored Apr 23, 2024
2 parents c9e134f + 1c24cee commit be8c0e6
Show file tree
Hide file tree
Showing 14 changed files with 150 additions and 60 deletions.
27 changes: 27 additions & 0 deletions include/dav1d/headers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ use std::ops::Deref;
use std::ops::Sub;
use std::sync::atomic::AtomicU64;
use std::sync::atomic::Ordering;
use std::sync::Arc;
use std::sync::Mutex;
use strum::EnumCount;
use strum::FromRepr;

Expand Down Expand Up @@ -42,6 +44,19 @@ impl<R, D> Deref for DRav1d<R, D> {
}
}

impl<R, D> Default for DRav1d<R, D>
where
R: Default,
D: Default,
{
fn default() -> Self {
Self {
rav1d: Default::default(),
dav1d: Default::default(),
}
}
}

// Constants from Section 3. "Symbols and abbreviated terms"
pub const DAV1D_MAX_CDEF_STRENGTHS: usize = 8;
pub const DAV1D_MAX_OPERATING_POINTS: usize = 32;
Expand Down Expand Up @@ -817,6 +832,18 @@ impl From<Rav1dITUTT35> for Dav1dITUTT35 {
}
}

impl Rav1dITUTT35 {
pub fn to_immut(
mutable: Arc<Mutex<Vec<Rav1dITUTT35>>>,
) -> Arc<DRav1d<Box<[Rav1dITUTT35]>, Box<[Dav1dITUTT35]>>> {
let mutable = Arc::into_inner(mutable).unwrap().into_inner().unwrap();
let immutable = mutable.into_boxed_slice();
let rav1d = immutable;
let dav1d = rav1d.iter().cloned().map(Dav1dITUTT35::from).collect();
Arc::new(DRav1d { rav1d, dav1d })
}
}

#[derive(Clone, Copy)]
#[repr(C)]
pub struct Dav1dSequenceHeaderOperatingPoint {
Expand Down
9 changes: 7 additions & 2 deletions include/dav1d/picture.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,16 @@ typedef struct Dav1dPicture {
*/
Dav1dMasteringDisplay *mastering_display;
/**
* ITU-T T.35 metadata as defined in section 5.8.2 and 6.7.2
* Array of ITU-T T.35 metadata as defined in section 5.8.2 and 6.7.2
*/
Dav1dITUTT35 *itut_t35;

uintptr_t reserved[4]; ///< reserved for future use
/**
* Number of ITU-T T35 metadata entries in the array
*/
size_t n_itut_t35;

uintptr_t reserved[3]; ///< reserved for future use

struct Dav1dRef *frame_hdr_ref; ///< Dav1dFrameHeader allocation origin
struct Dav1dRef *seq_hdr_ref; ///< Dav1dSequenceHeader allocation origin
Expand Down
17 changes: 11 additions & 6 deletions include/dav1d/picture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,13 @@ pub struct Dav1dPicture {
pub content_light: Option<NonNull<Rav1dContentLightLevel>>,
pub mastering_display: Option<NonNull<Rav1dMasteringDisplay>>,
pub itut_t35: Option<NonNull<Dav1dITUTT35>>,
pub reserved: [uintptr_t; 4],
pub n_itut_t35: usize,
pub reserved: [uintptr_t; 3],
pub frame_hdr_ref: Option<RawArc<DRav1d<Rav1dFrameHeader, Dav1dFrameHeader>>>, // opaque, so we can change this
pub seq_hdr_ref: Option<RawArc<DRav1d<Rav1dSequenceHeader, Dav1dSequenceHeader>>>, // opaque, so we can change this
pub content_light_ref: Option<RawArc<Rav1dContentLightLevel>>, // opaque, so we can change this
pub mastering_display_ref: Option<RawArc<Rav1dMasteringDisplay>>, // opaque, so we can change this
pub itut_t35_ref: Option<RawArc<DRav1d<Rav1dITUTT35, Dav1dITUTT35>>>, // opaque, so we can change this
pub itut_t35_ref: Option<RawArc<DRav1d<Box<[Rav1dITUTT35]>, Box<[Dav1dITUTT35]>>>>, // opaque, so we can change this
pub reserved_ref: [uintptr_t; 4],
pub r#ref: Option<NonNull<Dav1dRef>>,
pub allocator_data: Option<NonNull<c_void>>,
Expand Down Expand Up @@ -126,7 +127,7 @@ pub(crate) struct Rav1dPicture {
pub m: Rav1dDataProps,
pub content_light: Option<Arc<Rav1dContentLightLevel>>,
pub mastering_display: Option<Arc<Rav1dMasteringDisplay>>,
pub itut_t35: Option<Arc<DRav1d<Rav1dITUTT35, Dav1dITUTT35>>>,
pub itut_t35: Arc<DRav1d<Box<[Rav1dITUTT35]>, Box<[Dav1dITUTT35]>>>,
pub r#ref: Option<NonNull<Rav1dRef>>,
}

Expand All @@ -142,6 +143,7 @@ impl From<Dav1dPicture> for Rav1dPicture {
content_light: _,
mastering_display: _,
itut_t35: _,
n_itut_t35: _,
reserved: _,
frame_hdr_ref,
seq_hdr_ref,
Expand Down Expand Up @@ -172,7 +174,9 @@ impl From<Dav1dPicture> for Rav1dPicture {
mastering_display: mastering_display_ref.map(|raw| unsafe { raw.into_arc() }),
// We don't `.update_rav1d` [`Rav1dITUTT35`] because never read it.
// Safety: `raw` came from [`RawArc::from_arc`].
itut_t35: itut_t35_ref.map(|raw| unsafe { raw.into_arc() }),
itut_t35: itut_t35_ref
.map(|raw| unsafe { raw.into_arc() })
.unwrap_or_default(),
r#ref,
}
}
Expand Down Expand Up @@ -208,13 +212,14 @@ impl From<Rav1dPicture> for Dav1dPicture {
content_light: content_light.as_ref().map(|arc| arc.as_ref().into()),
mastering_display: mastering_display.as_ref().map(|arc| arc.as_ref().into()),
// [`DRav1d::from_rav1d`] is called in [`rav1d_parse_obus`].
itut_t35: itut_t35.as_ref().map(|arc| (&arc.as_ref().dav1d).into()),
itut_t35: Some(NonNull::new(itut_t35.dav1d.as_ptr().cast_mut()).unwrap()),
n_itut_t35: itut_t35.len(),
reserved: Default::default(),
frame_hdr_ref: frame_hdr.map(RawArc::from_arc),
seq_hdr_ref: seq_hdr.map(RawArc::from_arc),
content_light_ref: content_light.map(RawArc::from_arc),
mastering_display_ref: mastering_display.map(RawArc::from_arc),
itut_t35_ref: itut_t35.map(RawArc::from_arc),
itut_t35_ref: Some(itut_t35).map(RawArc::from_arc),
reserved_ref: Default::default(),
r#ref,
allocator_data,
Expand Down
2 changes: 1 addition & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ project('dav1d', ['c'],
'b_ndebug=if-release'],
meson_version: '>= 0.49.0')

dav1d_soname_version = '6.8.0'
dav1d_soname_version = '6.9.0'
dav1d_api_version_array = dav1d_soname_version.split('.')
dav1d_api_version_major = dav1d_api_version_array[0]
dav1d_api_version_minor = dav1d_api_version_array[1]
Expand Down
2 changes: 1 addition & 1 deletion src/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4823,7 +4823,7 @@ pub unsafe fn rav1d_submit_frame(c: &mut Rav1dContext) -> Rav1dResult {

// We must take itut_t35 out of the context before the call so borrowck can
// see we mutably borrow `c.itut_t35` disjointly from the task thread lock.
let itut_t35 = c.itut_t35.take();
let itut_t35 = mem::take(&mut c.itut_t35);
let res = rav1d_thread_picture_alloc(c, f, bpc, itut_t35);
if res.is_err() {
on_error(f, c, out);
Expand Down
1 change: 1 addition & 0 deletions src/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ struct Dav1dContext {
Dav1dMasteringDisplay *mastering_display;
Dav1dRef *itut_t35_ref;
Dav1dITUTT35 *itut_t35;
int n_itut_t35;

// decoded output picture queue
Dav1dData in;
Expand Down
4 changes: 2 additions & 2 deletions src/internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use crate::include::dav1d::dav1d::Rav1dEventFlags;
use crate::include::dav1d::dav1d::Rav1dInloopFilterType;
use crate::include::dav1d::headers::DRav1d;
use crate::include::dav1d::headers::Dav1dFrameHeader;
use crate::include::dav1d::headers::Dav1dITUTT35;
use crate::include::dav1d::headers::Dav1dSequenceHeader;
use crate::include::dav1d::headers::Rav1dContentLightLevel;
use crate::include::dav1d::headers::Rav1dFrameHeader;
Expand Down Expand Up @@ -272,6 +271,7 @@ pub(crate) struct TaskThreadData {
pub delayed_fg: Mutex<TaskThreadData_delayed_fg>,
}

#[derive(Default)]
#[repr(C)]
pub(crate) struct Rav1dContext_refs {
pub p: Rav1dThreadPicture,
Expand Down Expand Up @@ -324,7 +324,7 @@ pub struct Rav1dContext {
pub(crate) frame_hdr: Option<Arc<DRav1d<Rav1dFrameHeader, Dav1dFrameHeader>>>, // TODO(kkysen) Previously pooled.
pub(crate) content_light: Option<Arc<Rav1dContentLightLevel>>,
pub(crate) mastering_display: Option<Arc<Rav1dMasteringDisplay>>,
pub(crate) itut_t35: Option<Arc<DRav1d<Rav1dITUTT35, Dav1dITUTT35>>>,
pub(crate) itut_t35: Arc<Mutex<Vec<Rav1dITUTT35>>>,

// decoded output picture queue
pub(crate) in_0: Rav1dData,
Expand Down
1 change: 1 addition & 0 deletions src/lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,7 @@ void dav1d_flush(Dav1dContext *const c) {
c->mastering_display = NULL;
c->content_light = NULL;
c->itut_t35 = NULL;
c->n_itut_t35 = 0;
dav1d_ref_dec(&c->mastering_display_ref);
dav1d_ref_dec(&c->content_light_ref);
dav1d_ref_dec(&c->itut_t35_ref);
Expand Down
9 changes: 8 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ pub unsafe extern "C" fn dav1d_version() -> *const c_char {
}

pub const DAV1D_API_VERSION_MAJOR: u8 = 6;
pub const DAV1D_API_VERSION_MINOR: u8 = 8;
pub const DAV1D_API_VERSION_MINOR: u8 = 9;
pub const DAV1D_API_VERSION_PATCH: u8 = 0;

/// Get the `dav1d` library C API version.
Expand Down Expand Up @@ -277,6 +277,10 @@ pub(crate) unsafe fn rav1d_open(c_out: &mut *mut Rav1dContext, s: &Rav1dSettings
} else {
Box::new([])
});
addr_of_mut!((*c).itut_t35).write(Arc::new(Mutex::new(Default::default())));
addr_of_mut!((*c).out).write(Default::default());
addr_of_mut!((*c).cache).write(Default::default());
addr_of_mut!((*c).refs).write(Default::default());
for n in 0..n_fc {
let f: &mut Rav1dFrameData = &mut *((*c).fc).offset(n as isize);
f.index = n;
Expand All @@ -297,6 +301,9 @@ pub(crate) unsafe fn rav1d_open(c_out: &mut *mut Rav1dContext, s: &Rav1dSettings
(&mut f.task_thread.ttd as *mut Arc<TaskThreadData>).write(Arc::clone(&(*c).task_thread));
f.lf.last_sharpness = -(1 as c_int);
rav1d_refmvs_init(&mut f.rf);
addr_of_mut!(f.refp).write(Default::default());
addr_of_mut!(f.cur).write(Default::default());
addr_of_mut!(f.sr_cur).write(Default::default());
}
(*c).tc = (0..n_tc)
.map(|n| {
Expand Down
44 changes: 33 additions & 11 deletions src/obu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1566,22 +1566,42 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in) {
break;
}

Dav1dRef *ref = dav1d_ref_create(sizeof(Dav1dITUTT35) + payload_size * sizeof(uint8_t));
if (!ref) return DAV1D_ERR(ENOMEM);
Dav1dITUTT35 *const itut_t35_metadata = ref->data;
if ((c->n_itut_t35 + 1) > INT_MAX / (int)sizeof(*c->itut_t35)) return dav1d_parse_obus_error(c, in);
struct Dav1dITUTT35 *itut_t35 = realloc(c->itut_t35, (c->n_itut_t35 + 1) * sizeof(*c->itut_t35));
if (!itut_t35) return dav1d_parse_obus_error(c, in);
c->itut_t35 = itut_t35;
memset(c->itut_t35 + c->n_itut_t35, 0, sizeof(*c->itut_t35));

struct itut_t35_ctx_context *itut_t35_ctx;
if (!c->n_itut_t35) {
assert(!c->itut_t35_ref);
itut_t35_ctx = malloc(sizeof(struct itut_t35_ctx_context));
if (!itut_t35_ctx) return dav1d_parse_obus_error(c, in);
c->itut_t35_ref = dav1d_ref_wrap((uint8_t *)c->itut_t35, dav1d_picture_free_itut_t35,
itut_t35_ctx);
if (!c->itut_t35_ref) {
free(itut_t35_ctx);
return dav1d_parse_obus_error(c, in);
}
} else {
assert(c->itut_t35_ref && atomic_load(&c->itut_t35_ref->ref_cnt) == 1);
itut_t35_ctx = c->itut_t35_ref->user_data;
c->itut_t35_ref->const_data = (uint8_t *)c->itut_t35;
}
itut_t35_ctx->itut_t35 = c->itut_t35;
itut_t35_ctx->n_itut_t35 = c->n_itut_t35 + 1;

Dav1dITUTT35 *const itut_t35_metadata = &c->itut_t35[c->n_itut_t35];
itut_t35_metadata->payload = malloc(payload_size);
if (!itut_t35_metadata->payload) return dav1d_parse_obus_error(c, in);

// We need our public headers to be C++ compatible, so payload can't be
// a flexible array member
itut_t35_metadata->payload = (uint8_t *) &itut_t35_metadata[1];
itut_t35_metadata->country_code = country_code;
itut_t35_metadata->country_code_extension_byte = country_code_extension_byte;
for (int i = 0; i < payload_size; i++)
itut_t35_metadata->payload[i] = dav1d_get_bits(&gb, 8);
itut_t35_metadata->payload_size = payload_size;

dav1d_ref_dec(&c->itut_t35_ref);
c->itut_t35 = itut_t35_metadata;
c->itut_t35_ref = ref;
c->n_itut_t35++;
break;
}
case OBU_META_SCALABILITY:
Expand Down Expand Up @@ -1636,11 +1656,12 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in) {
dav1d_picture_copy_props(&c->out.p,
c->content_light, c->content_light_ref,
c->mastering_display, c->mastering_display_ref,
c->itut_t35, c->itut_t35_ref,
c->itut_t35, c->itut_t35_ref, c->n_itut_t35,
&in->m);
// Must be removed from the context after being attached to the frame
dav1d_ref_dec(&c->itut_t35_ref);
c->itut_t35 = NULL;
c->n_itut_t35 = 0;
c->event_flags |= dav1d_picture_get_event_flags(&c->refs[c->frame_hdr->existing_frame_idx].p);
} else {
pthread_mutex_lock(&c->task_thread.lock);
Expand Down Expand Up @@ -1689,11 +1710,12 @@ int dav1d_parse_obus(Dav1dContext *const c, Dav1dData *const in) {
dav1d_picture_copy_props(&out_delayed->p,
c->content_light, c->content_light_ref,
c->mastering_display, c->mastering_display_ref,
c->itut_t35, c->itut_t35_ref,
c->itut_t35, c->itut_t35_ref, c->n_itut_t35,
&in->m);
// Must be removed from the context after being attached to the frame
dav1d_ref_dec(&c->itut_t35_ref);
c->itut_t35 = NULL;
c->n_itut_t35 = 0;

pthread_mutex_unlock(&c->task_thread.lock);
}
Expand Down
10 changes: 5 additions & 5 deletions src/obu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2463,12 +2463,12 @@ unsafe fn parse_obus(
let country_code = country_code as u8;
let country_code_extension_byte = country_code_extension_byte as u8;
let payload = (0..payload_size).map(|_| gb.get_bits(8) as u8).collect(); // TODO(kkysen) fallible allocation

c.itut_t35 = Some(Arc::new(DRav1d::from_rav1d(Rav1dITUTT35 {
let itut_t35 = Rav1dITUTT35 {
country_code,
country_code_extension_byte,
payload,
}))); // TODO(kkysen) fallible allocation
};
c.itut_t35.try_lock().unwrap().push(itut_t35); // TODO fallible allocation
}
}
Some(ObuMetaType::Scalability | ObuMetaType::Timecode) => {} // Ignore metadata OBUs we don't care about.
Expand Down Expand Up @@ -2529,7 +2529,7 @@ unsafe fn parse_obus(
c.content_light.clone(),
c.mastering_display.clone(),
// Must be moved from the context to the frame.
c.itut_t35.take(),
Rav1dITUTT35::to_immut(mem::take(&mut c.itut_t35)),
props.clone(),
);
c.event_flags |= c.refs[frame_hdr.existing_frame_idx as usize].p.flags.into();
Expand Down Expand Up @@ -2593,7 +2593,7 @@ unsafe fn parse_obus(
c.content_light.clone(),
c.mastering_display.clone(),
// Must be moved from the context to the frame.
c.itut_t35.take(),
Rav1dITUTT35::to_immut(mem::take(&mut c.itut_t35)),
props.clone(),
);
}
Expand Down
Loading

0 comments on commit be8c0e6

Please sign in to comment.