diff --git a/src/mpegparser/M2VParser.cpp b/src/mpegparser/M2VParser.cpp index e26bb2f5f..1e19b56ea 100644 --- a/src/mpegparser/M2VParser.cpp +++ b/src/mpegparser/M2VParser.cpp @@ -128,20 +128,19 @@ int32_t M2VParser::InitParser(){ //Gotta find a sequence header now MPEGChunk* chunk; //MPEGChunk* seqHdrChunk; - for(int i = 0; i < chunks.size(); i++){ + for(size_t i = 0; i < chunks.size(); i++){ chunk = chunks[i]; if(chunk->GetType() == MPEG_VIDEO_SEQUENCE_START_CODE){ //Copy the header for later, we must copy because the actual chunk will be deleted in a bit binary * hdrData = new binary[chunk->GetSize()]; memcpy(hdrData, chunk->GetPointer(), chunk->GetSize()); seqHdrChunk = new MPEGChunk(hdrData, chunk->GetSize()); //Save this for adding as private data... - MPEG2SequenceHeader seqHdr = ParseSequenceHeader(chunk); - m_seqHdr = seqHdr; + ParseSequenceHeader(chunk, m_seqHdr); //Look for sequence extension to identify mpeg2 binary* pData = chunk->GetPointer(); - for(int i = 3; i < chunk->GetSize() - 4; i++){ - if(pData[i] == 0x00 && pData[i+1] == 0x00 && pData[i+2] == 0x01 && pData[i+3] == 0xb5 && ((pData[i+4] & 0xF0) == 0x10)){ + for(size_t j = 3; i < chunk->GetSize() - 4; i++){ + if(pData[j] == 0x00 && pData[j+1] == 0x00 && pData[j+2] == 0x01 && pData[j+3] == 0xb5 && ((pData[j+4] & 0xF0) == 0x10)){ mpegVersion = 2; break; } @@ -181,7 +180,7 @@ MediaTime M2VParser::GetFrameDuration(MPEG2PictureHeader picHdr){ } } -int32_t M2VParser::GetState(){ +MPEG2ParserState_e M2VParser::GetState(){ FillQueues(); if(!buffers.empty()) parserState = MPV_PARSER_STATE_FRAME; @@ -193,15 +192,16 @@ int32_t M2VParser::GetState(){ return parserState; } -int32_t M2VParser::CountBFrames(){ +MediaTime M2VParser::CountBFrames(){ //We count after the first chunk. - int32_t count = 0; + MediaTime count = 0; if(m_eos) return 0; if(notReachedFirstGOP) return 0; - for(int i = 1; i < chunks.size(); i++){ + for(size_t i = 1; i < chunks.size(); i++){ MPEGChunk* c = chunks[i]; if(c->GetType() == MPEG_VIDEO_PICTURE_START_CODE){ - MPEG2PictureHeader h = ParsePictureHeader(c); + MPEG2PictureHeader h; + ParsePictureHeader(c, h); if(h.frameType == MPEG2_B_FRAME){ count += GetFrameDuration(h); }else{ @@ -249,9 +249,9 @@ int32_t M2VParser::QueueFrame(MPEGChunk* seqHdr, MPEGChunk* chunk, MediaTime tim outBuf->firstRef = (MediaTime)(firstRef * (1000000000/(m_seqHdr.frameRate*2))); outBuf->secondRef = (MediaTime)(secondRef * (1000000000/(m_seqHdr.frameRate*2))); } - outBuf->rff = (bool) picHdr.repeatFirstField; - outBuf->tff = (bool) picHdr.topFieldFirst; - outBuf->progressive = (bool) picHdr.progressive; + outBuf->rff = (picHdr.repeatFirstField != 0); + outBuf->tff = (picHdr.topFieldFirst != 0); + outBuf->progressive = (picHdr.progressive != 0); outBuf->pictureStructure = (uint8_t) picHdr.pictureStructure; buffers.push(outBuf); return 0; @@ -285,7 +285,7 @@ int32_t M2VParser::FillQueues(){ if(chunk->GetType() == MPEG_VIDEO_SEQUENCE_START_CODE){ if (chunks.size() == 1) return -1; if(seqHdr) delete seqHdr; - m_seqHdr = ParseSequenceHeader(chunk); + ParseSequenceHeader(chunk, m_seqHdr); seqHdr = chunk; }else{ delete chunk; //Skip all non picture, non seq headers @@ -298,8 +298,9 @@ int32_t M2VParser::FillQueues(){ } chunk = chunks.front(); } - MPEG2PictureHeader picHdr = ParsePictureHeader(chunk); - int bcount; + MPEG2PictureHeader picHdr; + ParsePictureHeader(chunk, picHdr); + MediaTime bcount; if(myTime == nextSkip){ myTime+=nextSkipDuration; currentStampingTime=myTime; @@ -318,7 +319,7 @@ int32_t M2VParser::FillQueues(){ } ShoveRef(myTime); QueueFrame(seqHdr,chunk,myTime,picHdr); - if(notReachedFirstGOP) notReachedFirstGOP = false; + notReachedFirstGOP = false; break; case MPEG2_P_FRAME: bcount = CountBFrames(); diff --git a/src/mpegparser/M2VParser.h b/src/mpegparser/M2VParser.h index a52bb8a1c..840c95814 100644 --- a/src/mpegparser/M2VParser.h +++ b/src/mpegparser/M2VParser.h @@ -27,10 +27,12 @@ #include #include -#define MPV_PARSER_STATE_FRAME 0 -#define MPV_PARSER_STATE_NEED_DATA 1 -#define MPV_PARSER_STATE_EOS -1 -#define MPV_PARSER_STATE_ERROR -2 +enum MPEG2ParserState_e { + MPV_PARSER_STATE_FRAME, + MPV_PARSER_STATE_NEED_DATA, + MPV_PARSER_STATE_EOS, + MPV_PARSER_STATE_ERROR +}; class MPEGFrame { public: @@ -68,13 +70,13 @@ private: MediaTime nextSkipDuration; MediaTime secondRef; uint8_t mpegVersion; - int32_t parserState; + MPEG2ParserState_e parserState; MPEGVideoBuffer * mpgBuf; int32_t InitParser(); void DumpQueues(); int32_t FillQueues(); - int32_t CountBFrames(); + MediaTime CountBFrames(); void ShoveRef(MediaTime ref); MediaTime GetFrameDuration(MPEG2PictureHeader picHdr); int32_t QueueFrame(MPEGChunk* seqHdr, MPEGChunk* chunk, MediaTime timecode, MPEG2PictureHeader picHdr); @@ -94,7 +96,7 @@ public: return seqHdrChunk; } - uint8_t GetMPEGVersion(){ + uint8_t GetMPEGVersion() const{ return mpegVersion; } @@ -110,7 +112,7 @@ public: int32_t WriteData(binary* data, uint32_t dataSize); //Returns the current state of the parser - int32_t GetState(); + MPEG2ParserState_e GetState(); //Sets "end of stream" status on the buffer, forces timestamping of frames waiting. //Do not call this without good reason. diff --git a/src/mpegparser/MPEGVideoBuffer.cpp b/src/mpegparser/MPEGVideoBuffer.cpp index b7aad4a83..fa5332b4f 100644 --- a/src/mpegparser/MPEGVideoBuffer.cpp +++ b/src/mpegparser/MPEGVideoBuffer.cpp @@ -70,23 +70,14 @@ void MPEGVideoBuffer::UpdateState(){ if(test != -1) //We found a new startcode chunkEnd = test; } - if(chunkStart == -1){ + if(chunkStart == -1 || chunkEnd == -1){ state = MPEG2_BUFFER_STATE_NEED_MORE_DATA; - return; - }else if(chunkEnd == -1){ - state = MPEG2_BUFFER_STATE_NEED_MORE_DATA; - return; }else{ assert(chunkStart >= 0 && chunkStart < chunkEnd && chunkEnd > 0); state = MPEG2_BUFFER_STATE_CHUNK_READY; - return; } } -uint32_t MPEGVideoBuffer::GetState(){ - return state; -} - MPEGChunk * MPEGVideoBuffer::ReadChunk(){ MPEGChunk* myChunk = NULL; if(state == MPEG2_BUFFER_STATE_CHUNK_READY){ @@ -121,14 +112,9 @@ int32_t MPEGVideoBuffer::Feed(binary* data, uint32_t numBytes){ return res; } -MPEG2SequenceHeader ParseSequenceHeader(MPEGChunk* chunk){ - MPEG2SequenceHeader hdr; +void ParseSequenceHeader(MPEGChunk* chunk, MPEG2SequenceHeader & hdr){ binary* pos = chunk->GetPointer(); uint8_t haveSeqExt = 0; - if(chunk->GetType() != MPEG_VIDEO_SEQUENCE_START_CODE){ - //printf("Don't feed parse_sequence_header a chunk that isn't a sequence header!!!\n"); - return hdr; - } //Parse out the resolution info, horizontal first pos+=4; //Skip the start code hdr.width = (((unsigned int)pos[0]) << 4) | (((unsigned int) pos[1])>>4); //xx x0 00 @@ -206,18 +192,15 @@ MPEG2SequenceHeader ParseSequenceHeader(MPEGChunk* chunk){ }else{ hdr.progressiveSequence = 0; } - - return hdr; } -MPEG2GOPHeader ParseGOPHeader(MPEGChunk* chunk){ - MPEG2GOPHeader hdr; - binary* pos = chunk->GetPointer(); - uint32_t timecode; +bool ParseGOPHeader(MPEGChunk* chunk, MPEG2GOPHeader & hdr){ if(chunk->GetType() != MPEG_VIDEO_GOP_START_CODE){ //printf("Don't feed parse_gop_header a chunk that isn't a gop header!!!\n"); - return hdr; + return false; } + binary* pos = chunk->GetPointer(); + uint32_t timecode; pos+=4; //skip the startcode //Parse GOP timecode structure timecode = ((uint32_t)pos[0] << 24) | @@ -234,19 +217,17 @@ MPEG2GOPHeader ParseGOPHeader(MPEGChunk* chunk){ }else{ hdr.closedGOP = 0; } - return hdr; + return true; } -MPEG2PictureHeader ParsePictureHeader(MPEGChunk* chunk){ - MPEG2PictureHeader hdr; - binary* pos = chunk->GetPointer(); -// int i = 0; - int havePicExt = 0; - uint32_t temp = 0; +bool ParsePictureHeader(MPEGChunk* chunk, MPEG2PictureHeader & hdr){ if(chunk->GetType() != MPEG_VIDEO_PICTURE_START_CODE){ //printf("Don't feed parse_picture_header a chunk that isn't a picture!!!\n"); - return hdr; + return false; } + binary* pos = chunk->GetPointer(); + int havePicExt = 0; + uint32_t temp = 0; pos+=4; temp = (((uint32_t)pos[0]) << 8) | (pos[1] & 0xC0); hdr.temporalReference = temp >> 6; @@ -284,5 +265,5 @@ MPEG2PictureHeader ParsePictureHeader(MPEGChunk* chunk){ hdr.progressive = (pos[0] & 0x80); } - return hdr; + return true; } diff --git a/src/mpegparser/MPEGVideoBuffer.h b/src/mpegparser/MPEGVideoBuffer.h index 80f500a32..2a10514aa 100644 --- a/src/mpegparser/MPEGVideoBuffer.h +++ b/src/mpegparser/MPEGVideoBuffer.h @@ -33,10 +33,12 @@ #define MPEG_VIDEO_GOP_START_CODE 0xb8 #define MPEG_VIDEO_USER_START_CODE 0xb2 -#define MPEG2_BUFFER_STATE_NEED_MORE_DATA 1 -#define MPEG2_BUFFER_STATE_CHUNK_READY 2 -#define MPEG2_BUFFER_STATE_EMPTY 0 -#define MPEG2_BUFFER_INVALID -1 +enum MPEG2BufferState_e { + MPEG2_BUFFER_STATE_NEED_MORE_DATA, + MPEG2_BUFFER_STATE_CHUNK_READY, + MPEG2_BUFFER_STATE_EMPTY, + MPEG2_BUFFER_INVALID +}; #define MPEG2_I_FRAME 1 #define MPEG2_P_FRAME 2 @@ -90,11 +92,11 @@ public: delete [] data; } - uint8_t GetType(){ + inline uint8_t GetType() const { return type; } - uint32_t GetSize(){ + inline uint32_t GetSize() const{ return size; } @@ -106,19 +108,19 @@ public: return data[i]; } - binary * GetPointer(){ + inline binary * GetPointer(){ return data; } }; -MPEG2SequenceHeader ParseSequenceHeader(MPEGChunk* chunk); -MPEG2PictureHeader ParsePictureHeader(MPEGChunk* chunk); -MPEG2GOPHeader ParseGOPHeader(MPEGChunk* chunk); +void ParseSequenceHeader(MPEGChunk* chunk, MPEG2SequenceHeader & hdr); +bool ParsePictureHeader(MPEGChunk* chunk, MPEG2PictureHeader & hdr); +bool ParseGOPHeader(MPEGChunk* chunk, MPEG2GOPHeader & hdr); class MPEGVideoBuffer{ private: CircBuffer * myBuffer; - uint32_t state; + MPEG2BufferState_e state; int32_t chunkStart; int32_t chunkEnd; void UpdateState(); @@ -135,7 +137,7 @@ public: delete myBuffer; } - uint32_t GetState(); + inline MPEG2BufferState_e GetState() const { return state; } int32_t GetFreeBufferSpace(){ return (myBuffer->buf_capacity - myBuffer->bytes_in_buf);