Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

backport from dav1d 1.2.0: picture: allow storing an array of Dav1dITUTT35 entries #528

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ paste = "1.0.14"
raw-cpuid = "11.0.1"
strum = { version = "0.25.0", features = ["derive"] }
to_method = "1.1.0"
try-lock = "0.2.5"
zerocopy = { version = "0.7.32", features = ["derive"] }

[build-dependencies]
Expand Down
27 changes: 27 additions & 0 deletions include/dav1d/headers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ use std::ops::Deref;
use std::ops::Sub;
use std::sync::atomic::AtomicU64;
use std::sync::atomic::Ordering;
use std::sync::Arc;
use strum::EnumCount;
use strum::FromRepr;
use try_lock::TryLock;

/// This is so we can store both `*mut D` and `*mut R`
/// for maintaining `dav1d` ABI compatibility,
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<TryLock<Vec<Rav1dITUTT35>>>,
) -> Arc<DRav1d<Box<[Rav1dITUTT35]>, Box<[Dav1dITUTT35]>>> {
let mutable = Arc::into_inner(mutable).unwrap().into_inner();
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'
kkysen marked this conversation as resolved.
Show resolved Hide resolved
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 @@ -4794,7 +4794,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
5 changes: 3 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 @@ -109,6 +108,7 @@ use std::sync::Condvar;
use std::sync::Mutex;
use std::sync::OnceLock;
use std::thread::JoinHandle;
use try_lock::TryLock;

#[repr(C)]
pub(crate) struct Rav1dDSPContext {
Expand Down Expand Up @@ -272,6 +272,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 +325,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<TryLock<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
10 changes: 9 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ use std::sync::Mutex;
use std::sync::Once;
use std::thread;
use to_method::To as _;
use try_lock::TryLock;

#[cold]
fn init_internal() {
Expand All @@ -101,7 +102,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 +278,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(TryLock::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 +302,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