Skip to content

Commit

Permalink
Merge pull request #94 from bbc/philipn-avc-separate-fields
Browse files Browse the repository at this point in the history
Add support for AVC separate fields
  • Loading branch information
philipnbbc authored Sep 5, 2024
2 parents 3bc0bb3 + 3ce05f2 commit 78c3744
Show file tree
Hide file tree
Showing 33 changed files with 1,237 additions and 267 deletions.
176 changes: 130 additions & 46 deletions apps/bmxparse/bmxparse.cpp

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions apps/raw2bmx/raw2bmx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4645,8 +4645,8 @@ int main(int argc, const char** argv)
throw false;
}

avc_parser->ParseFrameInfo(input->raw_reader->GetSampleData(),
input->raw_reader->GetSampleDataSize());
avc_parser->ParseFrameInfo2(input->raw_reader->GetSampleData(),
ParsedFrameSize(input->raw_reader->GetSampleDataSize()));
input->essence_type = avc_parser->GetAVCIEssenceType(input->raw_reader->GetSampleDataSize(),
input->avci_guess_interlaced,
input->avci_guess_progressive);
Expand Down Expand Up @@ -4693,8 +4693,8 @@ int main(int argc, const char** argv)
if (input->essence_type_group == AVC_ESSENCE_GROUP)
input->essence_type = AVC_HIGH_422;
} else {
avc_parser->ParseFrameInfo(input->raw_reader->GetSampleData(),
input->raw_reader->GetSampleDataSize());
avc_parser->ParseFrameInfo2(input->raw_reader->GetSampleData(),
ParsedFrameSize(input->raw_reader->GetSampleDataSize()));
if (input->essence_type_group != AVC_ESSENCE_GROUP &&
avc_parser->GetEssenceType() != input->essence_type)
{
Expand Down
135 changes: 128 additions & 7 deletions include/bmx/essence_parser/AVCEssenceParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,19 +134,28 @@ class POCState
};


class AVCEssenceParser : public EssenceParser
class AVCEssenceParser;

// Parses either a Coded Frame or Coded Field
class AVCCodedPictureEssenceParser : public EssenceParser
{
public:
AVCEssenceParser();
virtual ~AVCEssenceParser();
friend class AVCEssenceParser;

public:
AVCCodedPictureEssenceParser();
virtual ~AVCCodedPictureEssenceParser();

void SetSPS(const unsigned char *data, uint32_t size);
void SetPPS(const unsigned char *data, uint32_t size);

virtual uint32_t ParseFrameStart(const unsigned char *data, uint32_t data_size);

virtual void ResetParseFrameSize();
virtual uint32_t ParseFrameSize(const unsigned char *data, uint32_t data_size);

virtual void ParseFrameInfo(const unsigned char *data, uint32_t data_size);
// Only call after ParseFrameInfo
void DecodePOC(POCState *poc_state, int32_t *pic_order_cnt);

void ParseNALUnits(const unsigned char *data, uint32_t size, std::vector<NALReference> *nals);
Expand Down Expand Up @@ -248,6 +257,7 @@ class AVCEssenceParser : public EssenceParser
{
public:
SPSExtra();
SPSExtra(const SPSExtra &other);
~SPSExtra();

uint8_t num_ref_frames_in_pic_order_cnt_cycle;
Expand Down Expand Up @@ -288,6 +298,21 @@ class AVCEssenceParser : public EssenceParser
uint8_t have_mmco_5;
} SliceHeader;

class POCInfo
{
public:
POCInfo();
POCInfo(AVCCodedPictureEssenceParser *parser);
~POCInfo();

bool have_active_sps;
SPS active_sps;
SPSExtra *active_sps_extra;
SliceHeader prim_pic_slice_header;
bool is_idr_frame;
bool have_mmco5;
};

private:
uint32_t NextStartCodePrefix(const unsigned char *data, uint32_t size);
uint32_t CompletePSSize(const unsigned char *ps_start, const unsigned char *ps_max_end);
Expand All @@ -299,9 +324,13 @@ class AVCEssenceParser : public EssenceParser
SliceHeader *slice_header, bool *unknown_param_sets = 0);
void ParseHRDParameters(AVCGetBitBuffer &buffer, SPS *sps);

void DecodePOCType0(POCState *poc_state, int32_t *top_field_order_cnt, int32_t *bottom_field_order_cnt);
void DecodePOCType1(POCState *poc_state, int32_t *top_field_order_cnt, int32_t *bottom_field_order_cnt);
void DecodePOCType2(POCState *poc_state, int32_t *top_field_order_cnt, int32_t *bottom_field_order_cnt);
void DecodePOC(POCState *poc_state, const POCInfo *poc_info, int32_t *pic_order_cnt);
void DecodePOCType0(POCState *poc_state, const POCInfo *poc_info,
int32_t *top_field_order_cnt, int32_t *bottom_field_order_cnt);
void DecodePOCType1(POCState *poc_state, const POCInfo *poc_info,
int32_t *top_field_order_cnt, int32_t *bottom_field_order_cnt);
void DecodePOCType2(POCState *poc_state, const POCInfo *poc_info,
int32_t *top_field_order_cnt, int32_t *bottom_field_order_cnt);

bool GetParameterSets(uint8_t pic_parameter_set_id, const SPS **sps, const PPS **pps);

Expand All @@ -312,7 +341,6 @@ class AVCEssenceParser : public EssenceParser
void SetSPSData(uint8_t id, const unsigned char *data, uint32_t size);
void SetPPSData(uint8_t id, const unsigned char *data, uint32_t size);

void ResetFrameSize();
void ResetFrameInfo();

private:
Expand Down Expand Up @@ -360,6 +388,99 @@ class AVCEssenceParser : public EssenceParser
};


// Parses a pair of Coded Fields or a Coded Frame
class AVCEssenceParser : public EssenceParser
{
public:
AVCEssenceParser();
virtual ~AVCEssenceParser();

void SetSPS(const unsigned char *data, uint32_t size);
void SetPPS(const unsigned char *data, uint32_t size);

virtual uint32_t ParseFrameStart(const unsigned char *data, uint32_t data_size);

virtual void ResetParseFrameSize();
virtual ParsedFrameSize ParseFrameSize2(const unsigned char *data, uint32_t data_size);

virtual ParsedFrameSize ParseFrameInfo2(const unsigned char *data, ParsedFrameSize frame_size);
// Only call after ParseFrameInfo2
void DecodePOC(POCState *poc_state, int32_t *pic_order_cnt);

void ParseNALUnits(const unsigned char *data, uint32_t size, std::vector<NALReference> *nals);

bool CheckFrameHasAVCIHeader(const unsigned char *data, uint32_t data_size);

public:
uint8_t GetProfile() const { return mCodedPictureParser.GetProfile(); }
uint8_t GetProfileConstraint() const { return mCodedPictureParser.GetProfileConstraint(); }
uint8_t GetLevel() const { return mCodedPictureParser.GetLevel(); }
uint32_t GetMaxBitRate() const { return mCodedPictureParser.GetMaxBitRate(); }
uint8_t GetMaxNumRefFrames() const { return mCodedPictureParser.GetMaxNumRefFrames(); }
bool HaveFrameRate() const { return mCodedPictureParser.HaveFrameRate(); }
bool IsFixedFrameRate() const { return mCodedPictureParser.IsFixedFrameRate(); }
Rational GetFrameRate() const { return mFrameRate; }
uint32_t GetStoredWidth() const { return mCodedPictureParser.GetStoredWidth(); }
uint32_t GetStoredHeight() const { return mCodedPictureParser.GetStoredHeight(); }
uint32_t GetDisplayWidth() const { return mCodedPictureParser.GetDisplayWidth(); }
uint32_t GetDisplayHeight() const { return mCodedPictureParser.GetDisplayHeight(); }
uint32_t GetDisplayXOffset() const { return mCodedPictureParser.GetDisplayXOffset(); }
uint32_t GetDisplayYOffset() const { return mCodedPictureParser.GetDisplayYOffset(); }
Rational GetSampleAspectRatio() const { return mCodedPictureParser.GetSampleAspectRatio(); }
uint32_t GetComponentDepth() const { return mCodedPictureParser.GetComponentDepth(); }
uint8_t GetChromaFormat() const { return mCodedPictureParser.GetChromaFormat(); }
uint8_t GetChromaLocation() const { return mCodedPictureParser.GetChromaLocation(); }
uint8_t GetVideoFormat() const { return mCodedPictureParser.GetVideoFormat(); }
uint8_t GetColorPrimaries() const { return mCodedPictureParser.GetColorPrimaries(); }
uint8_t GetTransferCharacteristics() const { return mCodedPictureParser.GetTransferCharacteristics(); }
uint8_t GetMatrixCoefficients() const { return mCodedPictureParser.GetMatrixCoefficients(); }
MPEGFrameType GetFrameType() const { return mFrameType; }
MPEGFrameType GetSecondFieldFrameType() const { return mSecondFieldFrameType; }
bool IsIDRFrame() const { return mIsIDRFrame; }
bool IsFrameMBSOnly() const { return mFrameMBSOnlyFlag; }
bool IsMBAdaptiveFFEncoding() const { return mMBAdaptiveFFEncoding; }
bool IsFieldPicture() const { return mCodedPictureParser.IsFieldPicture(); }
bool IsSeparateFieldPicture() const { return mSeparateFieldPicture > 0; }
bool IsBottomFieldFirst() const { return mBottomFieldFirst; }
uint64_t GetFrameNum() const { return mCodedPictureParser.GetFrameNum(); }

bool FrameHasActiveSPS() const { return mFrameHasActiveSPS; }
bool SecondFieldHasActiveSPS() const { return mSecondFieldHasActiveSPS; }
bool FrameHasActivePPS() const { return mFrameHasActivePPS; }
bool SecondFieldHasActivePPS() const { return mSecondFieldHasActivePPS; }
bool IsActiveSPSDataConstant() const { return mActiveSPSDataConstant; };
bool IsActivePPSDataConstant() const { return mActivePPSDataConstant; };

EssenceType GetEssenceType() const { return mCodedPictureParser.GetEssenceType(); }
EssenceType GetAVCIEssenceType(uint32_t data_size, bool is_interlaced, bool is_progressive) const {
return mCodedPictureParser.GetAVCIEssenceType(data_size, is_interlaced, is_progressive);
}

private:
void ResetFrameInfo();

private:
AVCCodedPictureEssenceParser mCodedPictureParser;
ParsedFrameSize mParsedFrameSize;

bool mIsIDRFrame;
Rational mFrameRate;
MPEGFrameType mFrameType;
MPEGFrameType mSecondFieldFrameType;
bool mFrameMBSOnlyFlag;
bool mMBAdaptiveFFEncoding;
int mSeparateFieldPicture; // <0 unknown, 0 false, >0 true
bool mBottomFieldFirst;
bool mFrameHasActiveSPS;
bool mSecondFieldHasActiveSPS;
bool mFrameHasActivePPS;
bool mSecondFieldHasActivePPS;
bool mActiveSPSDataConstant;
bool mActivePPSDataConstant;
AVCCodedPictureEssenceParser::POCInfo *mPOCInfo1;
AVCCodedPictureEssenceParser::POCInfo *mPOCInfo2;
};

};


Expand Down
2 changes: 2 additions & 0 deletions include/bmx/essence_parser/DVEssenceParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ class DVEssenceParser : public EssenceParser
virtual ~DVEssenceParser();

virtual uint32_t ParseFrameStart(const unsigned char *data, uint32_t data_size);

virtual void ResetParseFrameSize();
virtual uint32_t ParseFrameSize(const unsigned char *data, uint32_t data_size);

virtual void ParseFrameInfo(const unsigned char *data, uint32_t data_size);
Expand Down
52 changes: 50 additions & 2 deletions include/bmx/essence_parser/EssenceParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@


#include <bmx/BMXTypes.h>
#include <utility>


#define ESSENCE_PARSER_NULL_OFFSET 0xffffffff
Expand All @@ -45,15 +46,62 @@ namespace bmx
{


class ParsedFrameSize
{
public:
ParsedFrameSize();
ParsedFrameSize(const ParsedFrameSize &other);
ParsedFrameSize(uint32_t frame_size);
ParsedFrameSize(std::pair<uint32_t, uint32_t> field_sizes);
~ParsedFrameSize();

ParsedFrameSize& operator=(const ParsedFrameSize &other);

std::pair<uint32_t, uint32_t> GetFieldSizes() const;
uint32_t GetFirstFieldSize() const;
uint32_t GetSecondFieldSize() const;
uint32_t GetSize() const;
uint32_t GetFirstFieldOrFrameSize() const;

bool IsUnknown() const;
bool IsNull() const;

bool IsFrame() const;
bool IsFields() const;

bool HaveFirstField() const;
bool HaveSecondField() const;
bool HaveFirstFieldOrFrame() const;

bool IsComplete() const;

void SetSize(uint32_t size);
void SetFirstFieldSize(uint32_t size);
void SetSecondFieldSize(uint32_t size);

bool CompleteSize(uint32_t data_size);

void Reset();

private:
bool mIsFields;
std::pair<uint32_t, uint32_t> mFieldSizes;
};


class EssenceParser
{
public:
virtual ~EssenceParser() {}

virtual uint32_t ParseFrameStart(const unsigned char *data, uint32_t data_size) = 0;
virtual uint32_t ParseFrameSize(const unsigned char *data, uint32_t data_size) = 0;

virtual void ParseFrameInfo(const unsigned char *data, uint32_t data_size) = 0;
virtual void ResetParseFrameSize() = 0;
virtual uint32_t ParseFrameSize(const unsigned char *data, uint32_t data_size);
virtual ParsedFrameSize ParseFrameSize2(const unsigned char *data, uint32_t data_size);

virtual void ParseFrameInfo(const unsigned char *data, uint32_t data_size);
virtual ParsedFrameSize ParseFrameInfo2(const unsigned char *data, ParsedFrameSize frame_size);
};


Expand Down
2 changes: 2 additions & 0 deletions include/bmx/essence_parser/J2CEssenceParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ class J2CEssenceParser : public EssenceParser
virtual ~J2CEssenceParser();

virtual uint32_t ParseFrameStart(const unsigned char *data, uint32_t data_size);

virtual void ResetParseFrameSize();
virtual uint32_t ParseFrameSize(const unsigned char *data, uint32_t data_size);

virtual void ParseFrameInfo(const unsigned char *data, uint32_t data_size);
Expand Down
1 change: 1 addition & 0 deletions include/bmx/essence_parser/JXSEssenceParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ namespace bmx
virtual ~JXSEssenceParser() {}

virtual uint32_t ParseFrameStart(const unsigned char *data, uint32_t data_size);
virtual void ResetParseFrameSize();
virtual uint32_t ParseFrameSize(const unsigned char *data, uint32_t data_size);
virtual void ParseFrameInfo(const unsigned char *data, uint32_t data_size);

Expand Down
5 changes: 2 additions & 3 deletions include/bmx/essence_parser/MJPEGEssenceParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,12 @@ class MJPEGEssenceParser : public EssenceParser
virtual ~MJPEGEssenceParser();

virtual uint32_t ParseFrameStart(const unsigned char *data, uint32_t data_size);

virtual void ResetParseFrameSize();
virtual uint32_t ParseFrameSize(const unsigned char *data, uint32_t data_size);

virtual void ParseFrameInfo(const unsigned char *data, uint32_t data_size);

private:
void Reset();

private:
bool mSingleField;

Expand Down
3 changes: 2 additions & 1 deletion include/bmx/essence_parser/MPEG2EssenceParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ class MPEG2EssenceParser : public EssenceParser
virtual ~MPEG2EssenceParser();

virtual uint32_t ParseFrameStart(const unsigned char *data, uint32_t data_size);

virtual void ResetParseFrameSize();
virtual uint32_t ParseFrameSize(const unsigned char *data, uint32_t data_size);

virtual void ParseFrameInfo(const unsigned char *data, uint32_t data_size);
Expand Down Expand Up @@ -96,7 +98,6 @@ class MPEG2EssenceParser : public EssenceParser
bool IsTFF() const { return mIsTFF; }

private:
void ResetFrameSize();
void ResetFrameInfo();

private:
Expand Down
2 changes: 2 additions & 0 deletions include/bmx/essence_parser/RDD36EssenceParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ class RDD36EssenceParser : public EssenceParser
virtual ~RDD36EssenceParser();

virtual uint32_t ParseFrameStart(const unsigned char *data, uint32_t data_size);

virtual void ResetParseFrameSize();
virtual uint32_t ParseFrameSize(const unsigned char *data, uint32_t data_size);

virtual void ParseFrameInfo(const unsigned char *data, uint32_t data_size);
Expand Down
3 changes: 2 additions & 1 deletion include/bmx/essence_parser/VC2EssenceParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ class VC2EssenceParser : public EssenceParser
virtual ~VC2EssenceParser();

virtual uint32_t ParseFrameStart(const unsigned char *data, uint32_t data_size);

virtual void ResetParseFrameSize();
virtual uint32_t ParseFrameSize(const unsigned char *data, uint32_t data_size);

virtual void ParseFrameInfo(const unsigned char *data, uint32_t data_size);
Expand Down Expand Up @@ -176,7 +178,6 @@ class VC2EssenceParser : public EssenceParser
bool ParseSourceParameters(VC2GetBitBuffer *buffer, SequenceHeader *sequence_header);
void SetCodingParameters(SequenceHeader *sequence_header);

void ResetFrameSize();
void ResetFrameInfo();

private:
Expand Down
2 changes: 2 additions & 0 deletions include/bmx/essence_parser/VC3EssenceParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ class VC3EssenceParser : public EssenceParser
virtual ~VC3EssenceParser();

virtual uint32_t ParseFrameStart(const unsigned char *data, uint32_t data_size);

virtual void ResetParseFrameSize();
virtual uint32_t ParseFrameSize(const unsigned char *data, uint32_t data_size);

virtual void ParseFrameInfo(const unsigned char *data, uint32_t data_size);
Expand Down
1 change: 1 addition & 0 deletions include/bmx/writer_helper/AVCWriterHelper.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ class AVCWriterHelper
int64_t mNextIndexedDecodedPos;
int64_t mNextIndexedPos;
int64_t mKeyFramePosition;
int64_t mIDRKeyFramePosition;

uint8_t mDecodingDelay;
uint16_t mBPictureCount;
Expand Down
Loading

0 comments on commit 78c3744

Please sign in to comment.