Browse Source

Adjustments in ReadSequenceHeader() for case when image is not ReducedStillPictureHeader (still incomplete)

pull/2633/head
Brian Popow 2 years ago
parent
commit
136110fe5e
  1. 12
      src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuOperatingPoint.cs
  2. 84
      src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuReader.cs
  3. 2
      src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuSequenceHeader.cs

12
src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuOperatingPoint.cs

@ -14,4 +14,16 @@ internal class ObuOperatingPoint
internal bool IsDecoderModelPresent { get; set; }
internal bool IsInitialDisplayDelayPresent { get; set; }
internal uint InitialDisplayDelay { get; set; }
/// <summary>
/// Gets or sets of sets the Idc bitmask. The bitmask that indicates which spatial and temporal layers should be decoded for
/// operating point i.Bit k is equal to 1 if temporal layer k should be decoded(for k between 0 and 7). Bit j+8 is equal to 1 if
/// spatial layer j should be decoded(for j between 0 and 3).
/// However, if operating_point_idc[i] is equal to 0 then the coded video sequence has no scalability information in OBU
/// extension headers and the operating point applies to the entire coded video sequence.This means that all OBUs must be decoded.
/// It is a requirement of bitstream conformance that operating_point_idc[i] is not equal to operating_point_idc[j] for j = 0..(i- 1).
/// </summary>
internal uint Idc { get; set; }
}

84
src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuReader.cs

@ -265,27 +265,77 @@ internal class ObuReader
sequenceHeader.IsStillPicture = reader.ReadBoolean();
sequenceHeader.IsReducedStillPictureHeader = reader.ReadBoolean();
if (!sequenceHeader.IsStillPicture || !sequenceHeader.IsReducedStillPictureHeader)
if (sequenceHeader.IsReducedStillPictureHeader)
{
throw new ImageFormatException("Not a picture header, is this a movie file ??");
}
sequenceHeader.TimingInfo = null;
sequenceHeader.DecoderModelInfoPresentFlag = false;
sequenceHeader.InitialDisplayDelayPresentFlag = false;
sequenceHeader.OperatingPoint = new ObuOperatingPoint[1];
ObuOperatingPoint operatingPoint = new();
sequenceHeader.OperatingPoint[0] = operatingPoint;
operatingPoint.OperatorIndex = 0;
operatingPoint.SequenceLevelIndex = (int)reader.ReadLiteral(Av1Constants.LevelBits);
if (!IsValidSequenceLevel(sequenceHeader.OperatingPoint[0].SequenceLevelIndex))
{
throw new ImageFormatException("Invalid sequence level.");
}
sequenceHeader.TimingInfo = null;
sequenceHeader.DecoderModelInfoPresentFlag = false;
sequenceHeader.InitialDisplayDelayPresentFlag = false;
sequenceHeader.OperatingPoint = new ObuOperatingPoint[1];
ObuOperatingPoint operatingPoint = new();
sequenceHeader.OperatingPoint[0] = operatingPoint;
operatingPoint.OperatorIndex = 0;
operatingPoint.SequenceLevelIndex = (int)reader.ReadLiteral(Av1Constants.LevelBits);
if (!IsValidSequenceLevel(sequenceHeader.OperatingPoint[0].SequenceLevelIndex))
{
throw new ImageFormatException("Invalid sequence level.");
operatingPoint.SequenceTier = 0;
operatingPoint.IsDecoderModelPresent = false;
operatingPoint.IsInitialDisplayDelayPresent = false;
}
else
{
sequenceHeader.TimingInfoPresentFlag = reader.ReadBoolean();
if (sequenceHeader.TimingInfoPresentFlag)
{
sequenceHeader.DecoderModelInfoPresentFlag = reader.ReadBoolean();
if (sequenceHeader.DecoderModelInfoPresentFlag)
{
// TODO: read decoder_model_info( )
}
}
sequenceHeader.InitialDisplayDelayPresentFlag = reader.ReadBoolean();
uint operatingPointsCnt = reader.ReadLiteral(5) + 1;
sequenceHeader.OperatingPoint = new ObuOperatingPoint[operatingPointsCnt];
for (int i = 0; i < operatingPointsCnt; i++)
{
sequenceHeader.OperatingPoint[i] = new ObuOperatingPoint();
sequenceHeader.OperatingPoint[i].Idc = reader.ReadLiteral(12);
sequenceHeader.OperatingPoint[i].SequenceLevelIndex = (int)reader.ReadLiteral(5);
if (sequenceHeader.OperatingPoint[i].SequenceLevelIndex > 7)
{
sequenceHeader.OperatingPoint[i].SequenceTier = (int)reader.ReadLiteral(1);
}
else
{
sequenceHeader.OperatingPoint[i].SequenceTier = 0;
}
if (sequenceHeader.DecoderModelInfoPresentFlag)
{
sequenceHeader.OperatingPoint[i].IsDecoderModelPresent = reader.ReadBoolean();
if (sequenceHeader.OperatingPoint[i].IsDecoderModelPresent)
{
// TODO: operating_parameters_info( i )
}
}
else
{
sequenceHeader.OperatingPoint[i].IsDecoderModelPresent = false;
}
operatingPoint.SequenceTier = 0;
operatingPoint.IsDecoderModelPresent = false;
operatingPoint.IsInitialDisplayDelayPresent = false;
if (sequenceHeader.InitialDisplayDelayPresentFlag)
{
sequenceHeader.OperatingPoint[i].IsInitialDisplayDelayPresent = reader.ReadBoolean();
if (sequenceHeader.OperatingPoint[i].IsInitialDisplayDelayPresent)
{
sequenceHeader.OperatingPoint[i].InitialDisplayDelay = reader.ReadLiteral(4) + 1;
}
}
}
}
// Video related flags removed

2
src/ImageSharp/Formats/Heif/Av1/OpenBitstreamUnit/ObuSequenceHeader.cs

@ -21,6 +21,8 @@ internal class ObuSequenceHeader
public bool DecoderModelInfoPresentFlag { get; set; }
public bool TimingInfoPresentFlag { get; set; }
public object? TimingInfo { get; set; }
public bool IsFrameIdNumbersPresent { get; set; }

Loading…
Cancel
Save