Merge pull request #524 from jcdr428/Simplify_VC1_Class

Simplify VC1 classes
This commit is contained in:
jcdr428 2021-12-31 18:07:17 +01:00 committed by GitHub
commit ce632ae77d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 152 additions and 221 deletions

View File

@ -36,7 +36,7 @@ static inline int decode012(BitStreamReader& bitReader)
void VC1Unit::updateBits(int bitOffset, int bitLen, int value)
{
uint8_t* ptr = (uint8_t*)bitReader.getBuffer() + bitOffset / 8;
BitStreamWriter bitWriter;
BitStreamWriter bitWriter{};
int byteOffset = bitOffset % 8;
bitWriter.setBuffer(ptr, ptr + (bitLen / 8 + 5));
@ -66,16 +66,16 @@ string VC1SequenceHeader::getStreamDescr()
rez << "Profile: ";
switch (profile)
{
case PROFILE_SIMPLE:
case Profile::PROFILE_SIMPLE:
rez << "Simple";
break;
case PROFILE_MAIN:
case Profile::PROFILE_MAIN:
rez << "Main";
break;
case PROFILE_COMPLEX:
case Profile::PROFILE_COMPLEX:
rez << "Complex";
break;
case PROFILE_ADVANCED:
case Profile::PROFILE_ADVANCED:
rez << "Advanced@" << level;
break;
default:
@ -107,11 +107,12 @@ void VC1SequenceHeader::setFPS(double value)
{
// if (value < 25.0 && pulldown)
// value *= 1.25;
int nr, dr;
if (m_fpsFieldBitVal > 0)
{
int time_scale = (uint32_t)(value + 0.5) * 1000;
int num_units_in_tick = time_scale / value + 0.5;
int nr, dr;
int time_scale = (int)(value + 0.5) * 1000;
int num_units_in_tick = (int)(time_scale / value + 0.5);
if ((time_scale == 24000 || time_scale == 25000 || time_scale == 30000 || time_scale == 50000 ||
time_scale == 60000) &&
(num_units_in_tick == 1000 || num_units_in_tick == 1001))
@ -122,25 +123,33 @@ void VC1SequenceHeader::setFPS(double value)
else
THROW(ERR_VC1_ERR_FPS,
"Can't overwrite stream fps. Non standard fps values not supported for VC-1 streams");
if (time_scale == 24000)
switch (time_scale)
{
case 24000:
nr = 1;
else if (time_scale == 25000)
break;
case 25000:
nr = 2;
else if (time_scale == 30000)
break;
case 30000:
nr = 3;
else if (time_scale == 50000)
break;
case 50000:
nr = 4;
else // if (time_scale == 60000)
break;
case 60000:
nr = 5;
if (num_units_in_tick == 1000)
dr = 1;
else
dr = 2;
break;
default:
THROW(ERR_VC1_ERR_FPS,
"Can't overwrite stream fps. Non standard fps values not supported for VC-1 streams");
}
dr = (num_units_in_tick == 1000) ? 1 : 2;
updateBits(m_fpsFieldBitVal, 8, nr);
updateBits(m_fpsFieldBitVal + 8, 4, dr);
}
else
THROW(ERR_VC1_ERR_FPS, "Can't overwrite stream fps. Non standard fps values not supported for VC-1 streams");
}
int VC1SequenceHeader::decode_sequence_header()
@ -148,15 +157,15 @@ int VC1SequenceHeader::decode_sequence_header()
try
{
bitReader.setBuffer(m_nalBuffer, m_nalBuffer + m_nalBufferLen); // skip 00 00 01 xx marker
profile = bitReader.getBits(2);
if (profile == PROFILE_COMPLEX)
profile = (Profile)bitReader.getBits(2);
if (profile == Profile::PROFILE_COMPLEX)
LTRACE(LT_WARN, 0, "WMV3 Complex Profile is not fully supported");
if (profile == PROFILE_ADVANCED)
else if (profile == Profile::PROFILE_ADVANCED)
return decode_sequence_header_adv();
else
{
res_sm = bitReader.getBits(2); // reserved
int res_sm = bitReader.getBits(2); // reserved
if (res_sm)
{
LTRACE(LT_ERROR, 0, "Reserved RES_SM=" << res_sm << " is forbidden");
@ -164,48 +173,42 @@ int VC1SequenceHeader::decode_sequence_header()
}
}
frmrtq_postproc = bitReader.getBits(3); // common
bitrtq_postproc = bitReader.getBits(5); // common
loop_filter = bitReader.getBit(); // common
if (loop_filter == 1 && profile == PROFILE_SIMPLE)
bitReader.skipBits(8); // frmrtq_postproc, bitrtq_postproc
if (bitReader.getBit() && profile == Profile::PROFILE_SIMPLE) // loop_filter
LTRACE(LT_WARN, 0, "LOOPFILTER shell not be enabled in simple profile");
int res_x8 = bitReader.getBit(); // reserved
if (res_x8)
if (bitReader.getBit()) // reserved res_x8
LTRACE(LT_WARN, 0, "1 for reserved RES_X8 is forbidden");
multires = bitReader.getBit();
int res_fasttx = bitReader.getBit();
bitReader.skipBit(); // multires
int res_fasttx = bitReader.getBit(); // reserved
if (!res_fasttx)
LTRACE(LT_WARN, 0, "0 for reserved RES_FASTTX is forbidden");
fastuvmc = bitReader.getBit();
if (!profile && !fastuvmc)
if (profile == Profile::PROFILE_SIMPLE && !bitReader.getBit()) // fastuvmc
{
LTRACE(LT_ERROR, 0, "FASTUVMC unavailable in Simple Profile");
return NALUnit::UNSUPPORTED_PARAM;
}
extended_mv = bitReader.getBit();
if (!profile && extended_mv)
if (profile == Profile::PROFILE_SIMPLE && bitReader.getBit()) // extended_mv
{
LTRACE(LT_ERROR, 0, "Extended MVs unavailable in Simple Profile");
return NALUnit::UNSUPPORTED_PARAM;
}
dquant = bitReader.getBits(2);
vstransform = bitReader.getBit();
int res_transtab = bitReader.getBit();
if (res_transtab)
bitReader.skipBits(3); // dquant, vstransform
if (bitReader.getBit()) // res_transtab
{
LTRACE(LT_ERROR, 0, "1 for reserved RES_TRANSTAB is forbidden\n");
return NALUnit::UNSUPPORTED_PARAM;
}
overlap = bitReader.getBit();
resync_marker = bitReader.getBit();
bitReader.skipBits(2); // overlap, resync_marker
rangered = bitReader.getBit();
if (rangered && profile == PROFILE_SIMPLE)
if (rangered && profile == Profile::PROFILE_SIMPLE)
LTRACE(LT_WARN, 0, "RANGERED should be set to 0 in simple profile");
max_b_frames = bitReader.getBits(3);
quantizer_mode = bitReader.getBits(2);
bitReader.skipBits(2); // quantizer_mode
finterpflag = bitReader.getBit();
int res_rtm_flag = bitReader.getBit();
if (res_rtm_flag)
if (!bitReader.getBit()) // res_rtm_flag
LTRACE(LT_WARN, 0, "Old WMV3 version detected.");
// TODO: figure out what they mean (always 0x402F)
if (!res_fasttx)
@ -223,10 +226,7 @@ int VC1SequenceHeader::decode_sequence_header_adv()
level = bitReader.getBits(3);
if (level >= 5)
LTRACE(LT_WARN, 0, "Reserved LEVEL " << level);
chromaformat = bitReader.getBits(2);
frmrtq_postproc = bitReader.getBits(3); // common
bitrtq_postproc = bitReader.getBits(5); // common
postprocflag = bitReader.getBit(); // common
bitReader.skipBits(11); // chromaformat, frmrtq_postproc, bitrtq_postproc, postprocflag
coded_width = (bitReader.getBits(12) + 1) << 1;
coded_height = (bitReader.getBits(12) + 1) << 1;
pulldown = bitReader.getBit();
@ -284,49 +284,36 @@ if(psf) { //PsF, 6.1.13
}
if (bitReader.getBit())
{
color_prim = bitReader.getBits(8);
transfer_char = bitReader.getBits(8);
matrix_coef = bitReader.getBits(8);
}
bitReader.skipBits(24); // color_prim, transfer_char, matrix_coef
}
hrd_param_flag = bitReader.getBit();
if (hrd_param_flag)
{
hrd_num_leaky_buckets = bitReader.getBits(5);
bitReader.skipBits(4); // bitrate exponent
bitReader.skipBits(4); // buffer size exponent
for (int i = 0; i < hrd_num_leaky_buckets; i++)
{
bitReader.skipBits(16); // hrd_rate[n]
bitReader.skipBits(16); // hrd_buffer[n]
}
bitReader.skipBits(8); // bitrate exponent, buffer size exponent
for (int i = 0; i < hrd_num_leaky_buckets; i++) bitReader.skipBits(32); // hrd_rate[n], hrd_buffer[n]
}
return 0;
}
int VC1SequenceHeader::decode_entry_point()
{
int i, blink, clentry, refdist;
try
{
bitReader.setBuffer(m_nalBuffer, m_nalBuffer + m_nalBufferLen); // skip 00 00 01 xx marker
blink = bitReader.getBit(); // broken link
clentry = bitReader.getBit(); // closed entry
panscanflag = bitReader.getBit();
refdist = bitReader.getBit(); // refdist flag
loop_filter = bitReader.getBit();
fastuvmc = bitReader.getBit();
extended_mv = bitReader.getBit();
dquant = bitReader.getBits(2);
vstransform = bitReader.getBit();
overlap = bitReader.getBit();
quantizer_mode = bitReader.getBits(2);
bitReader.skipBit(); // blink = broken link
bitReader.skipBit(); // clentry = closed entry
bitReader.skipBit(); // panscanflag
bitReader.skipBit(); // refdist flag
bitReader.skipBit(); // loop_filter
bitReader.skipBit(); // fastuvmc
int extended_mv = bitReader.getBit();
bitReader.skipBits(6); // dquant, vstransform, overlap, quantizer_mode
if (hrd_param_flag)
{
for (i = 0; i < hrd_num_leaky_buckets; i++) bitReader.skipBits(8); // hrd_full[n]
for (int i = 0; i < hrd_num_leaky_buckets; i++) bitReader.skipBits(8); // hrd_full[n]
}
if (bitReader.getBit())
@ -335,7 +322,7 @@ int VC1SequenceHeader::decode_entry_point()
coded_height = (bitReader.getBits(12) + 1) << 1;
}
if (extended_mv)
extended_dmv = bitReader.getBit();
bitReader.skipBit(); // extended_dmv
if (bitReader.getBit())
{
// av_log(avctx, AV_LOG_ERROR, "Luma scaling is not supported, expect wrong picture\n");
@ -361,7 +348,7 @@ int VC1Frame::decode_frame_direct(const VC1SequenceHeader& sequenceHdr, uint8_t*
try
{
bitReader.setBuffer(buffer, end); // skip 00 00 01 xx marker
if (sequenceHdr.profile < PROFILE_ADVANCED)
if (sequenceHdr.profile < Profile::PROFILE_ADVANCED)
return vc1_parse_frame_header(sequenceHdr);
else
return vc1_parse_frame_header_adv(sequenceHdr);
@ -374,13 +361,11 @@ int VC1Frame::decode_frame_direct(const VC1SequenceHeader& sequenceHdr, uint8_t*
int VC1Frame::vc1_parse_frame_header(const VC1SequenceHeader& sequenceHdr)
{
interpfrm = -1;
if (sequenceHdr.finterpflag)
interpfrm = bitReader.getBit();
framecnt = bitReader.getBits(2); // framecnt unused
rangeredfrm = 0;
bitReader.skipBit(); // interpfrm
bitReader.skipBits(2); // framecnt
if (sequenceHdr.rangered)
rangeredfrm = bitReader.getBit();
bitReader.skipBit(); // rangeredfrm
pict_type = (VC1PictType)bitReader.getBit();
if (sequenceHdr.max_b_frames > 0)
{
@ -401,42 +386,8 @@ int VC1Frame::vc1_parse_frame_header(const VC1SequenceHeader& sequenceHdr)
int VC1Frame::vc1_parse_frame_header_adv(const VC1SequenceHeader& sequenceHdr)
{
fcm = 0;
if (sequenceHdr.interlace)
fcm = decode012(bitReader);
fcm = sequenceHdr.interlace ? decode012(bitReader) : 0;
/*
if (fcm == 2) // is coded field
{
int tmpType = bitReader.getBits(3);
switch(tmpType) {
case 0:
pict_type = I_TYPE;
break;
case 1:
pict_type = isFrame ? I_TYPE : P_TYPE;
break;
case 2:
pict_type = isFrame ? P_TYPE : I_TYPE;
break;
case 3:
pict_type = P_TYPE;
break;
case 4:
pict_type = B_TYPE;
break;
case 5:
pict_type = isFrame ? B_TYPE : BI_TYPE;
break;
case 6:
pict_type = isFrame ? BI_TYPE : B_TYPE;
break;
case 7:
pict_type = isFrame ? BI_TYPE : B_TYPE;
break;
}
}
*/
if (fcm == 2) // is coded field
{
switch (bitReader.getBits(3))
@ -482,7 +433,7 @@ int VC1Frame::vc1_parse_frame_header_adv(const VC1SequenceHeader& sequenceHdr)
}
if (sequenceHdr.tfcntrflag)
int TFCNTR = bitReader.getBits(8);
bitReader.skipBits(8); // TFCNTR
if (sequenceHdr.pulldown)
{
rptfrmBitPos = bitReader.getBitsCount();

View File

@ -9,7 +9,7 @@
#include "memory.h"
#include "vod_common.h"
enum VC1Code
enum class VC1Code
{
VC1_CODE_ENDOFSEQ = 0x0A,
VC1_CODE_SLICE,
@ -25,16 +25,13 @@ enum VC1Code
VC1_USER_CODE_SEQHDR
};
/** Available Profiles */
//@{
enum Profile
enum class Profile
{
PROFILE_SIMPLE,
PROFILE_MAIN,
PROFILE_COMPLEX, ///< TODO: WMV9 specific
PROFILE_ADVANCED
};
//@}
const int ff_vc1_fps_nr[7] = {24, 25, 30, 50, 60, 48, 72};
const int ff_vc1_fps_dr[2] = {1000, 1001};
@ -87,18 +84,18 @@ class VC1Unit
}
return end;
}
inline int vc1_unescape_buffer(uint8_t* src, int size)
inline size_t vc1_unescape_buffer(uint8_t* src, size_t size)
{
delete[] m_nalBuffer;
m_nalBuffer = new uint8_t[size];
int dsize = 0, i;
size_t dsize = 0;
if (size < 4)
{
std::copy(src, src + size, m_nalBuffer);
m_nalBufferLen = size;
return size;
}
for (i = 0; i < size; i++, src++)
for (size_t i = 0; i < size; i++, src++)
{
if (src[0] == 3 && i >= 2 && !src[-1] && !src[-2] && i < size - 1 && src[1] < 4)
{
@ -148,55 +145,55 @@ class VC1Unit
void updateBits(int bitOffset, int bitLen, int value);
BitStreamReader bitReader;
uint8_t* m_nalBuffer;
uint32_t m_nalBufferLen;
size_t m_nalBufferLen;
};
class VC1SequenceHeader : public VC1Unit
{
public:
VC1SequenceHeader()
: VC1Unit(), interlace(0), time_base_num(0), time_base_den(0), m_fpsFieldBitVal(0), sample_aspect_ratio(1, 1)
: VC1Unit(),
profile(Profile::PROFILE_SIMPLE),
level(0),
interlace(0),
time_base_num(0),
time_base_den(0),
m_fpsFieldBitVal(0),
sample_aspect_ratio(1, 1),
coded_height(0),
coded_width(0),
display_height(0),
display_width(0),
finterpflag(false),
hrd_param_flag(false),
hrd_num_leaky_buckets(0),
psf(0),
pulldown(0),
rangered(0),
max_b_frames(0),
tfcntrflag(false)
{
}
int profile;
int res_sm;
int frmrtq_postproc;
int bitrtq_postproc;
int loop_filter;
int multires;
int fastuvmc;
int extended_mv;
int dquant;
int vstransform;
int overlap;
int resync_marker;
Profile profile;
int rangered;
int max_b_frames;
int quantizer_mode;
int finterpflag; ///< INTERPFRM present
int level;
int chromaformat; ///< 2bits, 2=4:2:0, only defined
int coded_width;
int coded_height;
int display_width;
int display_height;
int pulldown; ///< TFF/RFF present
bool interlace; ///< Progressive/interlaced (RPTFTM syntax element)
int tfcntrflag; ///< TFCNTR present
int psf; ///< Progressive Segmented Frame
int pulldown; ///< TFF/RFF present
bool interlace; ///< Progressive/interlaced (RPTFTM syntax element)
bool tfcntrflag; ///< TFCNTR present
int psf; ///< Progressive Segmented Frame
int time_base_num;
int time_base_den;
int color_prim; ///< 8bits, chroma coordinates of the color primaries
int transfer_char; ///< 8bits, Opto-electronic transfer characteristics
int matrix_coef; ///< 8bits, Color primaries->YCbCr transform matrix
int hrd_param_flag;
int hrd_num_leaky_buckets;
int postprocflag;
/* for decoding entry point */
int panscanflag;
int decode_entry_point();
int extended_dmv;
/* ------------------------*/
AVRational sample_aspect_ratio; // w, h
@ -210,31 +207,11 @@ class VC1SequenceHeader : public VC1Unit
int m_fpsFieldBitVal;
};
/*
VC1EntryPoint: public VC1Unit {
public:
int panscanflag;
int loop_filter;
int fastuvmc;
int extended_mv;
int dquant;
int vstransform;
int overlap;
int quantizer_mode;
int coded_width;
int coded_height;
int extended_dmv; ///< Additional extended dmv range at P/B frame-level
};
*/
class VC1Frame : public VC1Unit
{
public:
VC1Frame() : VC1Unit(), rptfrm(0), fcm(0), rff(0), rptfrmBitPos(0) {}
VC1Frame() : VC1Unit(), rptfrm(0), fcm(0), rff(0), tff(0), rptfrmBitPos(0), pict_type(VC1PictType::I_TYPE) {}
int fcm;
int interpfrm;
int framecnt;
int rangeredfrm;
VC1PictType pict_type;
int rptfrm;
int tff;

View File

@ -17,7 +17,7 @@ void VC1StreamReader::writePESExtension(PESPacket* pesPacket, const AVPacket& av
pesPacket->flagsLo |= 1; // enable PES extension for VC-1 stream
uint8_t* data = (uint8_t*)(pesPacket) + pesPacket->getHeaderLength();
*data++ = 0x1;
*data++ = 0x01;
*data++ = 0x81;
*data++ = 0x55; // VC-1 sub type id 0x55-0x5f
pesPacket->m_pesHeaderLen += 3;
@ -34,14 +34,14 @@ int VC1StreamReader::writeAdditionData(uint8_t* dstBuffer, uint8_t* dstEnd, AVPa
m_firstFileFrame = false;
if (m_seqBuffer.size() > 0)
{
if (dstEnd - curPtr < (int)m_seqBuffer.size())
if ((size_t)(dstEnd - curPtr) < m_seqBuffer.size())
THROW(ERR_COMMON, "VC1 stream error: Not enough buffer for write headers");
memcpy(curPtr, &m_seqBuffer[0], m_seqBuffer.size());
curPtr += m_seqBuffer.size();
}
if (m_entryPointBuffer.size() > 0)
{
if (dstEnd - curPtr < (int)m_entryPointBuffer.size())
if ((size_t)(dstEnd - curPtr) < m_entryPointBuffer.size())
THROW(ERR_COMMON, "VC1 stream error: Not enough buffer for write headers");
memcpy(curPtr, &m_entryPointBuffer[0], m_entryPointBuffer.size());
curPtr += m_entryPointBuffer.size();
@ -56,9 +56,9 @@ int VC1StreamReader::getTSDescriptor(uint8_t* dstBuff, bool blurayMode, bool hdm
nal = VC1Unit::findNextMarker(nal + 4, m_bufEnd))
{
uint8_t unitType = nal[3];
switch (unitType)
if (unitType == (uint8_t)VC1Code::VC1_CODE_SEQHDR)
{
case VC1_CODE_SEQHDR:
uint8_t* nextNal = VC1Unit::findNextMarker(nal + 4, m_bufEnd);
VC1SequenceHeader sequence;
sequence.vc1_unescape_buffer(nal + 4, nextNal - nal - 4);
@ -66,30 +66,36 @@ int VC1StreamReader::getTSDescriptor(uint8_t* dstBuff, bool blurayMode, bool hdm
return 0;
dstBuff[0] = 0x05; // registration descriptor tag
dstBuff[1] = 6; // descriptor len
dstBuff[1] = 0x06; // descriptor len
dstBuff[2] = 0x56; // format identifier 0
dstBuff[3] = 0x43; // format identifier 1
dstBuff[4] = 0x2D; // format identifier 2
dstBuff[5] = 0x31; // format identifier 3
dstBuff[6] = 0x01; // profile and level subdescriptor
if (sequence.profile == 0)
dstBuff[7] = (sequence.profile << 4) + 0x11 + (sequence.level >> 1);
else if (sequence.profile == 1)
dstBuff[7] = (sequence.profile << 4) + 0x41 + (sequence.level >> 1);
else if (sequence.profile == 3)
dstBuff[7] = (sequence.profile << 4) + 0x61 + sequence.level;
else
dstBuff[1] -= 2; // remove profile and level descriptor
return dstBuff[1] + 2;
break;
int profile = (int)sequence.profile << 4;
switch (sequence.profile)
{
case Profile::PROFILE_SIMPLE:
dstBuff[7] = profile + 0x11 + (sequence.level >> 1);
break;
case Profile::PROFILE_MAIN:
dstBuff[7] = profile + 0x41 + (sequence.level >> 1);
break;
case Profile::PROFILE_ADVANCED:
dstBuff[7] = profile + 0x61 + sequence.level;
break;
default:
dstBuff[1] -= 2; // remove profile and level descriptor
return 6;
}
return 8;
}
}
return 0;
}
bool VC1StreamReader::skipNal(uint8_t* nal) { return !m_eof && nal[0] == VC1_CODE_ENDOFSEQ; }
bool VC1StreamReader::skipNal(uint8_t* nal) { return !m_eof && nal[0] == (uint8_t)VC1Code::VC1_CODE_ENDOFSEQ; }
CheckStreamRez VC1StreamReader::checkStream(uint8_t* buffer, int len)
{
@ -105,16 +111,16 @@ CheckStreamRez VC1StreamReader::checkStream(uint8_t* buffer, int len)
uint8_t unitType = nal[3];
switch (unitType)
{
case VC1_CODE_ENDOFSEQ:
case (uint8_t)VC1Code::VC1_CODE_ENDOFSEQ:
break;
case VC1_CODE_SLICE:
case VC1_USER_CODE_SLICE:
case (uint8_t)VC1Code::VC1_CODE_SLICE:
case (uint8_t)VC1Code::VC1_USER_CODE_SLICE:
break;
case VC1_CODE_FIELD:
case VC1_USER_CODE_FIELD:
case (uint8_t)VC1Code::VC1_CODE_FIELD:
case (uint8_t)VC1Code::VC1_USER_CODE_FIELD:
break;
case VC1_CODE_FRAME:
case VC1_USER_CODE_FRAME:
case (uint8_t)VC1Code::VC1_CODE_FRAME:
case (uint8_t)VC1Code::VC1_USER_CODE_FRAME:
nextNal = VC1Unit::findNextMarker(nal + 4, end);
if (m_frame.decode_frame_direct(m_sequence, nal + 4, nextNal) != 0)
break;
@ -132,15 +138,15 @@ CheckStreamRez VC1StreamReader::checkStream(uint8_t* buffer, int len)
if (m_frame.pict_type == VC1PictType::I_TYPE)
iFrameFound = true;
break;
case VC1_CODE_ENTRYPOINT:
case VC1_USER_CODE_ENTRYPOINT:
case (uint8_t)VC1Code::VC1_CODE_ENTRYPOINT:
case (uint8_t)VC1Code::VC1_USER_CODE_ENTRYPOINT:
nextNal = VC1Unit::findNextMarker(nal + 4, end);
m_sequence.vc1_unescape_buffer(nal + 4, nextNal - nal - 4);
if (m_sequence.decode_entry_point() != 0)
break;
break;
case VC1_CODE_SEQHDR:
case VC1_USER_CODE_SEQHDR:
case (uint8_t)VC1Code::VC1_CODE_SEQHDR:
case (uint8_t)VC1Code::VC1_USER_CODE_SEQHDR:
nextNal = VC1Unit::findNextMarker(nal + 4, end);
m_sequence.vc1_unescape_buffer(nal + 4, nextNal - nal - 4);
if (m_sequence.decode_sequence_header() != 0)
@ -169,15 +175,15 @@ int VC1StreamReader::intDecodeNAL(uint8_t* buff)
uint8_t* nextNal = 0;
switch (*buff)
{
case VC1_CODE_ENTRYPOINT:
case (uint8_t)VC1Code::VC1_CODE_ENTRYPOINT:
return decodeEntryPoint(buff);
break;
case VC1_CODE_ENDOFSEQ:
case (uint8_t)VC1Code::VC1_CODE_ENDOFSEQ:
nextNal = VC1Unit::findNextMarker(buff, m_bufEnd) + 3;
if (!m_eof && nextNal >= m_bufEnd)
return NOT_ENOUGH_BUFFER;
break;
case VC1_CODE_SEQHDR:
case (uint8_t)VC1Code::VC1_CODE_SEQHDR:
m_spsPpsFound = true;
rez = decodeSeqHeader(buff);
if (rez != 0)
@ -189,13 +195,13 @@ int VC1StreamReader::intDecodeNAL(uint8_t* buff)
return NOT_ENOUGH_BUFFER;
switch (*nextNal)
{
case VC1_CODE_ENTRYPOINT:
case (uint8_t)VC1Code::VC1_CODE_ENTRYPOINT:
rez = decodeEntryPoint(nextNal);
if (rez != 0)
return rez;
break;
case VC1_CODE_FRAME:
case VC1_USER_CODE_FRAME:
case (uint8_t)VC1Code::VC1_CODE_FRAME:
case (uint8_t)VC1Code::VC1_USER_CODE_FRAME:
rez = decodeFrame(nextNal);
if (rez == 0)
{
@ -208,8 +214,8 @@ int VC1StreamReader::intDecodeNAL(uint8_t* buff)
}
// m_lastIFrame = true;
break;
case VC1_CODE_FRAME:
case VC1_USER_CODE_FRAME:
case (uint8_t)VC1Code::VC1_CODE_FRAME:
case (uint8_t)VC1Code::VC1_USER_CODE_FRAME:
m_decodedAfterSeq = false;
rez = decodeFrame(buff);
return rez;
@ -225,8 +231,8 @@ int VC1StreamReader::decodeSeqHeader(uint8_t* buff)
{
return NOT_ENOUGH_BUFFER;
}
int oldSpsLen = nextNal - buff - 1;
m_sequence.vc1_unescape_buffer(buff + 1, nextNal - buff - 1);
size_t oldSpsLen = (size_t)(nextNal - buff - 1);
m_sequence.vc1_unescape_buffer(buff + 1, oldSpsLen);
int rez = m_sequence.decode_sequence_header();
if (rez != 0)
return rez;
@ -238,7 +244,7 @@ int VC1StreamReader::decodeSeqHeader(uint8_t* buff)
{
LTRACE(LT_INFO, 2, "Decoding VC-1 stream (track " << m_streamIndex << "): " << m_sequence.getStreamDescr());
}
if (m_sequence.profile != PROFILE_ADVANCED)
if (m_sequence.profile != Profile::PROFILE_ADVANCED)
THROW(ERR_VC1_ERR_PROFILE,
"Only ADVANCED profile are supported now. For feature request contat to: r_vasilenko@smlabs.net.");
@ -283,7 +289,7 @@ int VC1StreamReader::decodeFrame(uint8_t* buff)
{
if (!m_sequence.interlace || m_sequence.psf)
{
m_prevDtsInc = pcrIncVal * (m_frame.rptfrm + 1);
m_prevDtsInc = pcrIncVal * ((int64_t)m_frame.rptfrm + 1);
}
else
{
@ -354,10 +360,10 @@ int VC1StreamReader::getNextBFrames(uint8_t* buffer, int64_t& bTiming)
for (uint8_t* nal = VC1Unit::findNextMarker(buffer, m_bufEnd); nal < m_bufEnd - 4;
nal = VC1Unit::findNextMarker(nal + 4, m_bufEnd))
{
if (nal[3] != VC1_CODE_FIELD && nal[3] != VC1_USER_CODE_FIELD)
if (nal[3] != (uint8_t)VC1Code::VC1_CODE_FIELD && nal[3] != (uint8_t)VC1Code::VC1_USER_CODE_FIELD)
m_nextFrameAddr = nal;
if (nal[3] == VC1_CODE_FRAME || nal[3] == VC1_USER_CODE_FRAME)
if (nal[3] == (uint8_t)VC1Code::VC1_CODE_FRAME || nal[3] == (uint8_t)VC1Code::VC1_USER_CODE_FRAME)
{
VC1Frame frame;
if (frame.decode_frame_direct(m_sequence, nal + 4, m_bufEnd) != 0)
@ -368,13 +374,13 @@ int VC1StreamReader::getNextBFrames(uint8_t* buffer, int64_t& bTiming)
int64_t pcrIncVal = m_pcrIncPerFrame;
// if (frame.fcm == 2) // coded field
// pcrIncVal = m_pcrIncPerField;
// pcrIncVal = m_pcrIncPerField;
if (m_sequence.pulldown)
{
if (!m_sequence.interlace || m_sequence.psf)
{
pcrIncVal = pcrIncVal * (frame.rptfrm + 1);
pcrIncVal = pcrIncVal * ((int64_t)frame.rptfrm + 1);
}
else
{
@ -404,7 +410,7 @@ uint8_t* VC1StreamReader::findNextFrame(uint8_t* buffer)
for (uint8_t* nal = VC1Unit::findNextMarker(buffer, m_bufEnd); nal < m_bufEnd - 4;
nal = VC1Unit::findNextMarker(nal + 4, m_bufEnd))
{
if (nal[3] != VC1_CODE_FIELD && nal[3] != VC1_USER_CODE_FIELD)
if (nal[3] != (uint8_t)VC1Code::VC1_CODE_FIELD && nal[3] != (uint8_t)VC1Code::VC1_USER_CODE_FIELD)
return nal;
}
if (m_eof)
@ -415,8 +421,6 @@ uint8_t* VC1StreamReader::findNextFrame(uint8_t* buffer)
void VC1StreamReader::updateStreamFps(void* nalUnit, uint8_t* buff, uint8_t* nextNal, int oldSpsLen)
{
// SPSUnit* sps = (SPSUnit*) nalUnit;
// sps->setFps(m_fps);
m_sequence.setFPS(m_fps);
uint8_t* tmpBuffer = new uint8_t[oldSpsLen + 16];
long newSpsLen = m_sequence.vc1_escape_buffer(tmpBuffer);
@ -425,7 +429,6 @@ void VC1StreamReader::updateStreamFps(void* nalUnit, uint8_t* buff, uint8_t* nex
int sizeDiff = newSpsLen - oldSpsLen;
memmove(nextNal + sizeDiff, nextNal, m_bufEnd - nextNal);
m_bufEnd += sizeDiff;
// m_dataLen += sizeDiff;
}
memcpy(buff + 1, tmpBuffer, newSpsLen);
delete[] tmpBuffer;