Bump patch version post tag.
[asdcplib.git] / src / MPEG2_Parser.cpp
index bba10b1ab29215ab89c132cd96454db9af45f860..89abbfd30a790cdcdc498fc30990b6829b0bd551 100755 (executable)
@@ -1,5 +1,5 @@
 /*
-Copyright (c) 2004-2006, John Hurst
+Copyright (c) 2004-2011, John Hurst
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -54,6 +54,23 @@ enum ParserState_t {
     ST_SLICE,
 };
 
+const char*
+StringParserState(ParserState_t state)
+{
+  switch ( state )
+    {
+    case ST_INIT:  return "INIT";
+    case ST_SEQ:   return "SEQ";
+    case ST_PIC:   return "PIC";
+    case ST_GOP:   return "GOP";
+    case ST_EXT:   return "EXT";
+    case ST_SLICE: return "SLICE";
+    }
+
+  return "*UNKNOWN*";
+}
+
+
 
 //
 class h__ParserState
@@ -74,11 +91,12 @@ class h__ParserState
       switch ( m_State )
        {
        case ST_INIT:
+       case ST_EXT:
          m_State = ST_SEQ;
          return RESULT_OK;
        }
       
-      DefaultLogSink().Error("SEQ follows 0x%02x\n", m_State);
+      DefaultLogSink().Error("SEQ follows %s\n", StringParserState(m_State));
       return RESULT_STATE;
     }
 
@@ -94,7 +112,7 @@ class h__ParserState
          return RESULT_OK;
        }
       
-      DefaultLogSink().Error("Slice follows 0x%02x\n", m_State);
+      DefaultLogSink().Error("Slice follows %s\n", StringParserState(m_State));
       return RESULT_STATE;
     }
 
@@ -112,7 +130,7 @@ class h__ParserState
          return RESULT_OK;
        }
       
-      DefaultLogSink().Error("PIC follows 0x%02x\n", m_State);
+      DefaultLogSink().Error("PIC follows %s\n", StringParserState(m_State));
       return RESULT_STATE;
     }
 
@@ -128,7 +146,7 @@ class h__ParserState
        return RESULT_OK;
       }
     
-    DefaultLogSink().Error("GOP follows 0x%02x\n", m_State);
+    DefaultLogSink().Error("GOP follows %s\n", StringParserState(m_State));
     return RESULT_STATE;
   }
 
@@ -145,7 +163,7 @@ class h__ParserState
          return RESULT_OK;
       }
 
-    DefaultLogSink().Error("EXT follows 0x%02x\n", m_State);
+    DefaultLogSink().Error("EXT follows %s\n", StringParserState(m_State));
     return RESULT_STATE;
   }
 };
@@ -288,9 +306,9 @@ public:
        return RESULT_FALSE;
       }
 
-    Accessor::Picture PIC(b);
-    m_TemporalRef = PIC.TemporalRef();
-    m_FrameType = PIC.FrameType();
+    Accessor::Picture pic(b);
+    m_TemporalRef = pic.TemporalRef();
+    m_FrameType = pic.FrameType();
     m_FrameSize += s;
     return m_State.Goto_PIC();
   }
@@ -350,10 +368,10 @@ class ASDCP::MPEG2::Parser::h__Parser
   ASDCP_NO_COPY_CONSTRUCT(h__Parser);
 
 public:
-  h__Parser() : m_TmpBuffer(VESReadSize*2) {}
+  h__Parser() : m_TmpBuffer(VESReadSize*8) {}
   ~h__Parser() { Close(); }
 
-  Result_t OpenRead(const char* filename);
+  Result_t OpenRead(const std::string& filename);
   void     Close();
   Result_t Reset();
   Result_t ReadFrame(FrameBuffer&);
@@ -381,9 +399,8 @@ ASDCP::MPEG2::Parser::h__Parser::Close()
 
 //
 ASDCP::Result_t
-ASDCP::MPEG2::Parser::h__Parser::OpenRead(const char* filename)
+ASDCP::MPEG2::Parser::h__Parser::OpenRead(const std::string& filename)
 {
-  ASDCP_TEST_NULL_STR(filename)
   ui32_t read_count = 0;
 
   Result_t result = m_FileReader.OpenRead(filename);
@@ -399,7 +416,10 @@ 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 || ! ( p[3] == SEQ_START || p[3] == PIC_START ) )
+      ui32_t i = 0;
+      while ( p[i] == 0 ) i++;
+
+      if ( i < 2 || p[i] != 1 || ! ( p[i+1] == SEQ_START || p[i+1] == PIC_START ) )
        {
          DefaultLogSink().Error("Frame buffer does not begin with a PIC or SEQ start code.\n");
          return RESULT_RAW_FORMAT;
@@ -414,13 +434,15 @@ ASDCP::MPEG2::Parser::h__Parser::OpenRead(const char* filename)
 
   if ( ASDCP_SUCCESS(result) )
     {
+      ui64_t tmp = m_FileReader.Size() / 65536; // a gross approximation
+      m_ParamsDelegate.m_VDesc.ContainerDuration = (ui32_t) tmp;
       m_Parser.SetDelegate(&m_ParserDelegate);
       m_FileReader.Seek(0);
     }
 
   if ( ASDCP_FAILURE(result) )
     {
-      DefaultLogSink().Error("Unable to identify a wrapping mode for the essence in file \"%s\"\n", filename);
+      DefaultLogSink().Error("Unable to identify a wrapping mode for the essence in file \"%s\"\n", filename.c_str());
       m_FileReader.Close();
     }
 
@@ -543,7 +565,7 @@ ASDCP::MPEG2::Parser::~Parser()
 // Opens the stream for reading, parses enough data to provide a complete
 // set of stream metadata for the MXFWriter below.
 ASDCP::Result_t
-ASDCP::MPEG2::Parser::OpenRead(const char* filename) const
+ASDCP::MPEG2::Parser::OpenRead(const std::string& filename) const
 {
   const_cast<ASDCP::MPEG2::Parser*>(this)->m_Parser = new h__Parser;