summaryrefslogtreecommitdiff
path: root/src/MPEG2_Parser.cpp
diff options
context:
space:
mode:
authorjhurst <jhurst@cinecert.com>2006-04-05 23:03:55 +0000
committerjhurst <>2006-04-05 23:03:55 +0000
commitbfedf725dac9d13f3a02fe69f45c302ab29d2b1e (patch)
tree4a746f759dcb62ebeb6309373e7579d6048f4af6 /src/MPEG2_Parser.cpp
parentfdf31e0105bf8272a6b7fa9c4039941dff37a271 (diff)
ginormo merge-back with Kumu, SMPTE MIC key and MPEG parser fix
Diffstat (limited to 'src/MPEG2_Parser.cpp')
-rwxr-xr-xsrc/MPEG2_Parser.cpp93
1 files changed, 53 insertions, 40 deletions
diff --git a/src/MPEG2_Parser.cpp b/src/MPEG2_Parser.cpp
index f6e0089..af7396f 100755
--- a/src/MPEG2_Parser.cpp
+++ b/src/MPEG2_Parser.cpp
@@ -1,5 +1,5 @@
/*
-Copyright (c) 2004, John Hurst
+Copyright (c) 2004-2006, John Hurst
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -29,14 +29,17 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\brief AS-DCP library, MPEG2 raw essence reader implementation
*/
-#include <FileIO.h>
+#include <KM_fileio.h>
#include <MPEG.h>
+#include <KM_log.h>
+using Kumu::DefaultLogSink;
+
using namespace ASDCP;
using namespace ASDCP::MPEG2;
// data will be read from a VES file in chunks of this size
-const ui32_t VESReadSize = 4096;
+const ui32_t VESReadSize = 4 * Kumu::Kilobyte;
//------------------------------------------------------------------------------------------
@@ -59,11 +62,11 @@ class h__ParserState
ASDCP_NO_COPY_CONSTRUCT(h__ParserState);
public:
- h__ParserState() : m_State(::ST_INIT) {}
+ h__ParserState() : m_State(ST_INIT) {}
~h__ParserState() {}
- bool Test_SLICE() { return m_State == ST_SLICE; }
- void Reset() { m_State = ST_INIT; }
+ inline bool Test_SLICE() { return m_State == ST_SLICE; }
+ inline void Reset() { m_State = ST_INIT; }
//
inline Result_t Goto_SEQ()
@@ -75,6 +78,7 @@ class h__ParserState
return RESULT_OK;
}
+ DefaultLogSink().Error("SEQ follows 0x%02x\n", m_State);
return RESULT_STATE;
}
@@ -90,6 +94,7 @@ class h__ParserState
return RESULT_OK;
}
+ DefaultLogSink().Error("Slice follows 0x%02x\n", m_State);
return RESULT_STATE;
}
@@ -107,23 +112,25 @@ class h__ParserState
return RESULT_OK;
}
+ DefaultLogSink().Error("PIC follows 0x%02x\n", m_State);
return RESULT_STATE;
}
//
inline Result_t Goto_GOP()
- {
- switch ( m_State )
- {
- case ST_EXT:
- case ST_SEQ:
- m_State = ST_GOP;
- return RESULT_OK;
- }
-
- return RESULT_STATE;
- }
+ {
+ switch ( m_State )
+ {
+ case ST_EXT:
+ case ST_SEQ:
+ m_State = ST_GOP;
+ return RESULT_OK;
+ }
+
+ DefaultLogSink().Error("GOP follows 0x%02x\n", m_State);
+ return RESULT_STATE;
+ }
//
inline Result_t Goto_EXT()
@@ -138,6 +145,7 @@ class h__ParserState
return RESULT_OK;
}
+ DefaultLogSink().Error("EXT follows 0x%02x\n", m_State);
return RESULT_STATE;
}
};
@@ -216,8 +224,8 @@ public:
Result_t GOP(VESParser*, const byte_t*, ui32_t) { return RESULT_FALSE; }
Result_t Picture(VESParser*, const byte_t*, ui32_t) { return RESULT_FALSE; }
- Result_t Slice(VESParser*) { return RESULT_FALSE; }
- Result_t Data(VESParser*, const byte_t*, ui32_t) { return RESULT_OK; }
+ Result_t Slice(VESParser*, byte_t) { return RESULT_FALSE; }
+ Result_t Data(VESParser*, const byte_t*, i32_t) { return RESULT_OK; }
};
@@ -258,7 +266,7 @@ public:
m_PlaintextOffset = 0;
m_FrameType = FRAME_U;
m_State.Reset();
- }
+ }
Result_t Sequence(VESParser*, const byte_t* b, ui32_t s)
{
@@ -287,10 +295,15 @@ public:
return m_State.Goto_PIC();
}
- Result_t Slice(VESParser*)
+ Result_t Slice(VESParser*, byte_t slice_id)
{
- m_PlaintextOffset = m_FrameSize;
- return m_State.Goto_SLICE();
+ if ( slice_id == FIRST_SLICE )
+ {
+ m_PlaintextOffset = m_FrameSize;
+ return m_State.Goto_SLICE();
+ }
+
+ return m_State.Test_SLICE() ? RESULT_OK : RESULT_FAIL;
}
Result_t Extension(VESParser*, const byte_t* b, ui32_t s)
@@ -308,7 +321,7 @@ public:
return m_State.Goto_GOP();
}
- Result_t Data(VESParser*, const byte_t* b, ui32_t s)
+ Result_t Data(VESParser*, const byte_t* b, i32_t s)
{
m_FrameSize += s;
return RESULT_OK;
@@ -324,13 +337,12 @@ public:
// - any frame that begins with a picture header is either an I, B or P frame
// and is assumed to contain a complete picture header and picture data
-
class ASDCP::MPEG2::Parser::h__Parser
{
StreamParams m_ParamsDelegate;
FrameParser m_ParserDelegate;
VESParser m_Parser;
- FileReader m_FileReader;
+ Kumu::FileReader m_FileReader;
ui32_t m_FrameNumber;
bool m_EOF;
ASDCP::MPEG2::FrameBuffer m_TmpBuffer;
@@ -387,9 +399,9 @@ ASDCP::MPEG2::Parser::h__Parser::OpenRead(const char* filename)
// Since no one complained and that's the easiest thing to implement,
// I have left it that way. Let me know if you want to be able to
// locate the first GOP in the stream.
- if ( p[0] != 0 || p[1] != 0 || p[2] != 1 )
+ if ( p[0] != 0 || p[1] != 0 || p[2] != 1 || ! ( p[3] == SEQ_START || p[3] == PIC_START ) )
{
- DefaultLogSink().Error("Frame buffer does not begin with a start code.\n");
+ DefaultLogSink().Error("Frame buffer does not begin with a PIC or SEQ start code.\n");
return RESULT_RAW_FORMAT;
}
@@ -412,8 +424,8 @@ ASDCP::MPEG2::Parser::h__Parser::OpenRead(const char* filename)
m_FileReader.Close();
}
- return result;
-}
+ return result;}
+
//
//
@@ -434,6 +446,7 @@ ASDCP::MPEG2::Parser::h__Parser::ReadFrame(FrameBuffer& FB)
// the input file is exhausted. The partial next frame is cached for the
// next call.
m_ParserDelegate.Reset();
+ m_Parser.Reset();
if ( m_TmpBuffer.Size() > 0 )
{
@@ -443,7 +456,7 @@ ASDCP::MPEG2::Parser::h__Parser::ReadFrame(FrameBuffer& FB)
m_TmpBuffer.Size(0);
}
- while ( ! m_ParserDelegate.m_CompletePicture && ASDCP_SUCCESS(result) )
+ while ( ! m_ParserDelegate.m_CompletePicture && result == RESULT_OK )
{
if ( FB.Capacity() < ( write_offset + VESReadSize ) )
{
@@ -454,7 +467,7 @@ ASDCP::MPEG2::Parser::h__Parser::ReadFrame(FrameBuffer& FB)
result = m_FileReader.Read(FB.Data() + write_offset, VESReadSize, &read_count);
- if ( result == RESULT_ENDOFFILE )
+ if ( result == RESULT_ENDOFFILE || read_count == 0 )
{
m_EOF = true;
@@ -471,6 +484,7 @@ ASDCP::MPEG2::Parser::h__Parser::ReadFrame(FrameBuffer& FB)
if ( m_EOF )
break;
}
+ assert(m_ParserDelegate.m_FrameSize <= write_offset);
if ( ASDCP_SUCCESS(result)
&& m_ParserDelegate.m_FrameSize < write_offset )
@@ -478,21 +492,20 @@ ASDCP::MPEG2::Parser::h__Parser::ReadFrame(FrameBuffer& FB)
assert(m_TmpBuffer.Size() == 0);
ui32_t diff = write_offset - m_ParserDelegate.m_FrameSize;
assert(diff <= m_TmpBuffer.Capacity());
+
memcpy(m_TmpBuffer.Data(), FB.RoData() + m_ParserDelegate.m_FrameSize, diff);
m_TmpBuffer.Size(diff);
}
-#ifndef NDEBUG
if ( ASDCP_SUCCESS(result) )
{
const byte_t* p = FB.RoData();
- if ( p[0] != 0 || p[1] != 0 || p[2] != 1 )
- {
- DefaultLogSink().Error("Parsed frame buffer does not begin with a start code.\n");
- return RESULT_RAW_FORMAT;
- }
+ if ( p[0] != 0 || p[1] != 0 || p[2] != 1 || ! ( p[3] == SEQ_START || p[3] == PIC_START ) )
+ {
+ DefaultLogSink().Error("Frame buffer does not begin with a PIC or SEQ start code.\n");
+ return RESULT_RAW_FORMAT;
+ }
}
-#endif
if ( ASDCP_SUCCESS(result) )
{
@@ -573,5 +586,5 @@ ASDCP::MPEG2::Parser::FillVideoDescriptor(VideoDescriptor& VDesc) const
}
//
-// end AS_DCP_MPEG2_Parser.cpp
+// end MPEG2_Parser.cpp
//