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

mkv, mp4 track detection improvements #316

Merged
merged 5 commits into from
Oct 15, 2024

Conversation

sscobici
Copy link

@sscobici sscobici commented Oct 3, 2024

I will try to create small PRs for easy review.
Dolby Vision HEVC files have more configuration atoms (side data) besides hvcC, for example dvcC
It might be useful if VideoCodecParameters.extra_data to be a map of buffers instead of a single buffer.

Comment on lines 632 to 637
if (header.atom_type != AtomType::VisualSampleEntryDvhe
&& header.atom_type != AtomType::VisualSampleEntryDvh1
&& header.atom_type != AtomType::VisualSampleEntryHev1
&& header.atom_type != AtomType::VisualSampleEntryHvc1) || codec_specific.is_some() {
return decode_error("isomp4: invalid hevc configuration sample entry");
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it make sense to put this error in the _ match arm below?

Copy link
Author

@sscobici sscobici Oct 6, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just copied the pattern from above VisualSampleEntryAvc1, I think this check doesn't allow parsing known sample entry twice. To keep the same behavior decode error will need to be repeated for each known variant.

Is naming VisualSampleEntry better than VideoSampleEntry?

Comment on lines 35 to 54
// Parse the HEVCDecoderConfigurationRecord to get the profile and level. Defined in
// ISO/IEC 14496-15 section 8.3.3.1.2
let mut br = BitReaderLtr::new(&extra_data);

// Configuration version is always 1.
let configuration_version = br.read_bits_leq32(8)?;

if configuration_version != 1 {
return decode_error(
"isomp4 (hvcC): unexpected hevc decoder configuration record version",
);
}

// HEVC profile as defined in ISO/IEC 23008-2.
let _general_profile_space = br.read_bits_leq32(2)?;
let _general_tier_flag = br.read_bits_leq32(1)?;
let general_profile_idc = br.read_bits_leq32(5)?;
let _general_profile_compatibility_flags = br.read_bits_leq32(32)?;
let _general_constraint_indicator_flags = br.read_bits_leq64(48)?;
let general_level_idc = br.read_bits_leq32(8)?;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just parsing the HEVCDecoderConfigurationRecord, let me know what you think about my comment from your MKV PR.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will create separate crate to reuse the code.

@sscobici sscobici marked this pull request as draft October 10, 2024 20:12
@sscobici sscobici marked this pull request as ready for review October 10, 2024 23:31
@sscobici sscobici changed the title isomp4: Add HEVC basic detection mkv, mp4 track detection improvements Oct 10, 2024
@sscobici
Copy link
Author

Hopefully these changes will not introduce regressions with audio playback.

@sscobici
Copy link
Author

rebased, fixed symphonia-check compilation.

On a separate topic:
VideoCodecParameters need enhancements.

There is a need to store multiple codec buffers per track
pub extra_data: Option<Box<[u8]>>,

Do you want me to convert extra_data property to a dictionary where keys will be an Enum:
"HEVCDecoderConfigurationRecord",
"AVCDecoderConfigurationRecord",
"DolbyVisionConfiguration",

and values to be Box ?

I would also add Hdr enumeration to understand if this file is a SDR, HDR10, HDR10+ or DolbyVision

Do you like me to open a discussion on this topic, or I can create a PR with proposed changes and you will review.

@pdeljanov
Copy link
Owner

pdeljanov commented Oct 14, 2024

Hello,

It's a holiday this weekend so I haven't gotten to doing a deep review, however, I've skimmed it over and have some thoughts.


The MP4 changes look reasonable and are pretty low risk for regression. I think we can likely merge those as soon as I finish a more thorough review pass.


The changes to symphonia-check probably need some more work. I suggest we move it to a new PR.

If we are going to expand the scope of tests symphonia-check can perform, I think we should use sub-commands to select the test. For example, the existing audio test could be symphonia-check audio .... Your new test could be symphonia-check info ..., etc. I think this is better than overloading the refdec option to alter the behaviour.

I'm also not enthusiastic about relying on a format.txt. I think it'd be better if we could have a built-in default format string that could be overridden with an option to the info sub-command. This should be pretty simple since either the default format string or the override just needs to be passed to mediainfo.


On the topic of VideoCodecParameters, we can make extra_data a Vec for video, however, it cannot be an enum. The core crate should never create interfaces that are specific to any particular codec or format. You can however do something similar to VideoCodecId and have some well-known ones defined in the well_known sub-module. That way developers outside the project can define their own extra data types.

struct VideoExtraDataType(u32);

struct VideoExtraData {
   id: VideoExtraDataType,
   data: Box<[u8]>,
}

struct VideoCodecParameters {
  // ...
  extra_data: Vec<VideoExtraData>,
}

mod well_known {
  pub const EXTRA_DATA_TYPE_HEVC_DECODER_CONFIG_RECORD: VideoExtraDataId = VideoExtraDataId(0);
  // ...
}

Let's do this one in a separate PR as well since there will probably be some iteration on it.

@sscobici
Copy link
Author

removed commit for check, will make separate PRs.
It seems that converting of extra_data to vector will affect some other classes: like TrackElement in mkv and probably others.

@pdeljanov pdeljanov merged commit 82d7d43 into pdeljanov:dev-0.6 Oct 15, 2024
11 checks passed
@pdeljanov
Copy link
Owner

pdeljanov commented Oct 15, 2024

Thanks, merged!

It seems that converting of extra_data to vector will affect some other classes: like TrackElement in mkv and probably others.

Hmm, if it's just for VideoCodecParameters, then it's all new code anyways. You don't need to really worry about breaking anything that's in production.

However, I did miss a couple things in my last message.

In the code example I gave, the value of 0 should be reserved for a "null"/"default" buffer. Atleast for audio, there wasn't a need for multiple extra data buffers, so there was no need to label it. I imagine that older video codecs could be same. In these cases the default type could be used. A second option is to not have a default type, but just make the type optional.

Option 1:

struct VideoExtraDataType(u32);

pub const EXTRA_DATA_TYPE_DEFAULT: VideoExtraDataType = VideoExtraDataType(0x0);

mod well_known {
  // ...
  pub const EXTRA_DATA_TYPE_HEVC_DECODER_CONFIG_RECORD: VideoExtraDataType = VideoExtraDataType(0x1);
  // ...
}

struct VideoExtraData {
   data_type: VideoExtraDataType,
   data: Box<[u8]>,
}

struct VideoCodecParameters {
  // ...
  extra_data: Vec<VideoExtraData>,
}

Option 2:

struct VideoExtraData {
   data_type: Option<VideoExtraDataType>, // Can be `None` if codec only need one extra data buffer.
   data: Box<[u8]>,
}

@sscobici sscobici deleted the hevc-detection-new branch October 16, 2024 03:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants