dirac_cppparser.cpp

00001 /* ***** BEGIN LICENSE BLOCK *****
00002 *
00003 * $Id: dirac_cppparser.cpp,v 1.2 2005/01/30 05:11:41 gabest Exp $ $Name:  $
00004 *
00005 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00006 *
00007 * The contents of this file are subject to the Mozilla Public License
00008 * Version 1.1 (the "License"); you may not use this file except in compliance
00009 * with the License. You may obtain a copy of the License at
00010 * http://www.mozilla.org/MPL/
00011 *
00012 * Software distributed under the License is distributed on an "AS IS" basis,
00013 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
00014 * the specific language governing rights and limitations under the License.
00015 *
00016 * The Original Code is BBC Research and Development code.
00017 *
00018 * The Initial Developer of the Original Code is the British Broadcasting
00019 * Corporation.
00020 * Portions created by the Initial Developer are Copyright (C) 2004.
00021 * All Rights Reserved.
00022 *
00023 * Contributor(s): Anuradha Suraparaju (Original Author)
00024 *
00025 * Alternatively, the contents of this file may be used under the terms of
00026 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
00027 * Public License Version 2.1 (the "LGPL"), in which case the provisions of
00028 * the GPL or the LGPL are applicable instead of those above. If you wish to
00029 * allow use of your version of this file only under the terms of the either
00030 * the GPL or LGPL and not to allow others to use your version of this file
00031 * under the MPL, indicate your decision by deleting the provisions above
00032 * and replace them with the notice and other provisions required by the GPL
00033 * or LGPL. If you do not delete the provisions above, a recipient may use
00034 * your version of this file under the terms of any one of the MPL, the GPL
00035 * or the LGPL.
00036 * ***** END LICENSE BLOCK ***** */
00037 
00038 #include <sstream>
00039 #include <cstdio>
00040 #include <cstring>
00041 #include <libdirac_common/dirac_assertions.h> 
00042 #include <libdirac_decoder/dirac_cppparser.h>
00043 #include <libdirac_decoder/seq_decompress.h>
00044 #include <libdirac_common/frame.h> 
00045 using namespace dirac;
00046 
00047 
00048 InputStreamBuffer::InputStreamBuffer()
00049 {
00050     m_chunk_buffer = new char[m_buffer_size];
00051     
00052     setg (m_chunk_buffer,  //beginning of read area
00053           m_chunk_buffer,  //read position
00054           m_chunk_buffer); //end position
00055 }
00056 
00057 std::ios::pos_type InputStreamBuffer::Rewind()
00058 {
00059     return Seek(0, std::ios::beg);
00060 }
00061 
00062 std::ios::pos_type InputStreamBuffer::Tell()
00063 {
00064     return gptr() - eback();
00065 }
00066 
00067 std::ios::pos_type InputStreamBuffer::Seek(std::ios::pos_type bytes, std::ios::seekdir dir)
00068 {
00069     char *new_pos;
00070 
00071     switch (dir)
00072     {
00073     case std::ios::beg:
00074         new_pos  = eback() + bytes;
00075         break;
00076     case std::ios::end:
00077         new_pos  = egptr() + bytes;
00078         break;
00079     default:
00080         new_pos  = gptr() + bytes;
00081         break;
00082     }
00083     if (new_pos > egptr() || new_pos < eback())
00084         return -1;
00085 
00086     setg(eback(), //start of read 
00087         new_pos, //current read position
00088         egptr()); //end of stream positon
00089 
00090     return 0;
00091 }
00092 
00093 void InputStreamBuffer::Copy(char *start, int bytes)
00094 {
00095     //std::cerr << "eback=" << m_chunk_buffer - eback() 
00096      //         << "gptr=" << gptr() -m_chunk_buffer
00097       //        << "egptr=" << egptr() - m_chunk_buffer << endl;
00098 
00099     int bytes_left = m_buffer_size - (egptr() - m_chunk_buffer);
00100     if (bytes_left < bytes)
00101     {
00102         char *temp =  new char [m_buffer_size + bytes];
00103         memcpy (temp, m_chunk_buffer, m_buffer_size);
00104         setg (temp, temp+(gptr()-m_chunk_buffer), temp + (egptr() - m_chunk_buffer));
00105         delete [] m_chunk_buffer;
00106         m_chunk_buffer = temp;
00107     }
00108     //std::cerr << "eback=" << m_chunk_buffer - eback() 
00109      //         << "gptr=" << gptr() -m_chunk_buffer
00110       //        << "egptr=" << egptr() - m_chunk_buffer << endl;
00111 
00112     memcpy (egptr(), start, bytes);
00113     setg(m_chunk_buffer, gptr(), egptr()+bytes);
00114 
00115     //std::cerr << "eback=" << m_chunk_buffer - eback() 
00116      //         << "gptr=" << gptr() -m_chunk_buffer
00117       //        << "egptr=" << egptr() - m_chunk_buffer << endl;
00118 }
00119 
00120 void InputStreamBuffer::PurgeProcessedData()
00121 {
00122     //std::cerr << "eback=" << m_chunk_buffer - eback() 
00123      //         << "gptr=" << gptr() -m_chunk_buffer
00124       //        << "egptr=" << egptr() - m_chunk_buffer << endl;
00125 
00126     if (gptr() != m_chunk_buffer)
00127     {
00128         memmove (m_chunk_buffer, gptr(), egptr() - gptr());
00129         setg(m_chunk_buffer, m_chunk_buffer, m_chunk_buffer+(egptr() - gptr()));
00130     }
00131     //std::cerr << "eback=" << m_chunk_buffer - eback() 
00132      //         << "gptr=" << gptr() -m_chunk_buffer
00133       //        << "egptr=" << egptr() - m_chunk_buffer << endl;
00134 }
00135 
00136 InputStreamBuffer::~InputStreamBuffer()
00137 {
00138     delete [] m_chunk_buffer;
00139 }
00140 
00141 
00142 DiracParser::DiracParser(bool verbose) : 
00143     m_state(STATE_BUFFER), 
00144     m_next_state(STATE_SEQUENCE), 
00145     m_show_fnum(-1), 
00146     m_decomp(0), 
00147     m_skip(false), 
00148     m_skip_type(L2_frame), 
00149     m_verbose(verbose),
00150     m_found_start(false), 
00151     m_found_end(false), 
00152     m_shift (0xffffffff)
00153 {
00154     m_istr = new std::istream(&m_sbuf);
00155 }
00156 
00157 DiracParser::~DiracParser()
00158 {
00159     delete m_istr;
00160     delete m_decomp;
00161 }
00162 
00163 void DiracParser::SetBuffer (char *start, char *end)
00164 {
00165     TEST (end > start);
00166     m_sbuf.Copy(start, end - start);
00167 
00168 }
00169 
00170 DecoderState DiracParser::Parse()
00171 {
00172 
00173     while(true)
00174     {
00175         m_state = SeekChunk();
00176         switch (m_state)
00177         {
00178         case STATE_BUFFER:
00179                 return m_state;
00180 
00181         case STATE_SEQUENCE:
00182             if (m_next_state == m_state)
00183             {
00184                 if (m_decomp)
00185                     delete m_decomp;
00186 
00187                 m_decomp = new SequenceDecompressor (m_istr, m_verbose);
00188                 if (m_decomp->GetSeqParams().BitstreamVersion() != BITSTREAM_VERSION)
00189                 {
00190                     std::ostringstream errstr;
00191                     errstr << "Input Bitstream version " << m_decomp->GetSeqParams().BitstreamVersion() << " supported";
00192                     REPORTM(false, errstr.str().c_str());
00193                     return STATE_INVALID;
00194                 }
00195                 InitStateVars();
00196                 return m_state;
00197             }
00198             else
00199                 m_state = STATE_BUFFER;
00200             
00201             break;
00202     
00203         case STATE_PICTURE_START:
00204             if (m_next_state == m_state)
00205             {
00206                 m_decomp->ReadNextFrameHeader();
00207                 m_next_state = STATE_PICTURE_DECODE;
00208                 m_sbuf.PurgeProcessedData();
00209                 return m_state;
00210             }
00211             else
00212             {
00213                 m_state = STATE_BUFFER;
00214             }
00215             break;
00216 
00217         case STATE_PICTURE_DECODE:
00218         {
00219             Frame &my_frame = m_decomp->DecompressNextFrame(m_skip);
00220             if (m_skip)
00221             {
00222                 // Go pass start code so that we skip frame
00223                 m_sbuf.Seek(5);
00224             }
00225             else
00226             {
00227                 int framenum_decoded = my_frame.GetFparams().FrameNum();
00228                 if (framenum_decoded != m_show_fnum)
00229                 {
00230                     m_show_fnum = my_frame.GetFparams().FrameNum();
00231                     if (m_verbose)
00232                     {
00233                         std::cerr << "Frame " << m_show_fnum << " available" << std::endl;
00234                     }
00235                     m_state = STATE_PICTURE_AVAIL;
00236                 }
00237             }
00238             InitStateVars();
00239             if (m_state == STATE_PICTURE_AVAIL)
00240                 return m_state;
00241 
00242             break;
00243         }
00244         case STATE_SEQUENCE_END:
00245         {
00246             //push last frame in sequence out
00247             m_sbuf.Seek(5);
00248             Frame &my_frame = m_decomp->DecompressNextFrame(m_skip);
00249             if (!m_skip)
00250             {
00251                 if (my_frame.GetFparams().FrameNum() != m_show_fnum)
00252                 {
00253                     m_show_fnum = my_frame.GetFparams().FrameNum();
00254                     if (m_verbose)
00255                     {
00256                         std::cerr << "Frame " << m_show_fnum << " available" << std::endl;
00257                     }
00258                     m_state = STATE_PICTURE_AVAIL;
00259                     m_next_state = STATE_SEQUENCE_END;
00260                 }
00261                 else
00262                 {
00263                     InitStateVars();
00264                 }
00265             }
00266             else
00267             {
00268                 InitStateVars();
00269             }
00270             return m_state;
00271                 
00272             break;
00273         }
00274         default:
00275             return STATE_INVALID;
00276         }
00277     }
00278     return m_state;
00279 }
00280 
00281 const SeqParams& DiracParser::GetSeqParams() const
00282 {
00283     return m_decomp->GetSeqParams();
00284 }
00285 
00286 const FrameParams& DiracParser::GetNextFrameParams() const
00287 {
00288     return m_decomp->GetNextFrameParams();
00289 }
00290 
00291 const Frame& DiracParser::GetNextFrame() const
00292 {
00293     return m_decomp->GetNextFrame();
00294 }
00295 
00296 const Frame& DiracParser::GetLastFrame() const
00297 {
00298     return  m_decomp->DecompressNextFrame();
00299 }
00300 
00301 void DiracParser::SetSkip(bool skip)
00302 {
00303     const FrameParams& fparams = m_decomp->GetNextFrameParams();
00304     // FIXME: need to change this logic once bitstream is finalised. so that
00305     // we skip to next RAP when an L1 frame is skipped
00306     if (skip == false)
00307     {
00308         if (m_skip_type == L2_frame)
00309             m_skip = false;
00310 
00311         else if (m_skip_type == L1_frame || m_skip_type == I_frame)
00312         {
00313             if (fparams.FSort() == L2_frame || fparams.FSort() == L1_frame)
00314                 m_skip = true;
00315             else
00316             {
00317                 m_skip_type = L2_frame;
00318                 m_skip = false;
00319             }
00320         }
00321     }
00322     else
00323     {
00324         m_skip = true;
00325         if (m_skip_type != fparams.FSort())
00326         {
00327             switch (fparams.FSort())
00328             {
00329             case L2_frame:
00330                 break;
00331 
00332             case L1_frame:
00333                 if (m_skip_type != I_frame)
00334                     m_skip_type = L1_frame;
00335                 break;
00336             case I_frame:
00337                 m_skip_type = I_frame;
00338                 break;
00339 
00340             default:
00341                 dirac_ASSERTM(false, "Frame type must be I or L1 or L2");
00342                 break;
00343             }
00344         }
00345     }
00346 }
00347 
00348 
00349 DecoderState DiracParser::SeekChunk()
00350 {
00351     char byte;
00352     if (!m_found_start)
00353     {
00354         while (m_sbuf.sgetn(&byte, 1))
00355         {
00356             //Find start of next chunk to be processed
00357             if (m_shift == START_CODE_PREFIX)
00358             {
00359                 switch ((unsigned char)byte)
00360                 {
00361                 case NOT_START_CODE:
00362                     m_shift = 0xffffffff;
00363                     continue;
00364 
00365                 case RAP_START_CODE:
00366                     m_next_state = STATE_SEQUENCE;
00367                     break;
00368 
00369                 case IFRAME_START_CODE:
00370                 case L1FRAME_START_CODE:
00371                 case L2FRAME_START_CODE:
00372                     m_next_state = STATE_PICTURE_START;
00373                     break;
00374 
00375                 case SEQ_END_CODE:
00376                     m_next_state = STATE_SEQUENCE_END;
00377                     break;
00378                 default:
00379                     dirac_ASSERTM (false, "Should never have reached here!!!");
00380                     break;
00381                 }
00382                 m_found_start = true;
00383                 m_sbuf.Seek(-5);
00384                 m_sbuf.PurgeProcessedData();
00385                 m_sbuf.Seek(5);
00386                 m_shift = 0xffffffff;
00387                 break;
00388             }
00389             m_shift = (m_shift << 8) | byte;
00390         }
00391 
00392         if (!m_found_start)
00393         {
00394             m_next_state =  STATE_BUFFER;
00395         }
00396     }
00397 
00398     if (m_found_start && !m_found_end && m_next_state != STATE_SEQUENCE_END)
00399     {
00400         while (m_sbuf.sgetn(&byte, 1))
00401         {
00402             //Find start of next chunk to be processed
00403             if (m_shift == START_CODE_PREFIX)
00404             {
00405                 switch ((unsigned char)byte)
00406                 {
00407                 case NOT_START_CODE:
00408                     m_shift = 0xffffffff;
00409                     continue;
00410 
00411                 case RAP_START_CODE:
00412                     break;
00413 
00414                 case IFRAME_START_CODE:
00415                 case L1FRAME_START_CODE:
00416                 case L2FRAME_START_CODE:
00417                     break;
00418 
00419                 case SEQ_END_CODE:
00420                     break;
00421 
00422                 default:
00423                     dirac_ASSERTM (false, "Should never have reached here!!!");
00424                     break;
00425                 }
00426                 m_found_end = true;
00427                 break;
00428 
00429             }
00430             m_shift = (m_shift << 8) | byte;
00431         } 
00432 
00433         if (!m_found_end)
00434         {
00435             if (m_next_state != STATE_SEQUENCE_END)
00436                 return STATE_BUFFER;
00437         }
00438     }
00439 
00440     if (m_found_start && m_found_end)
00441     {
00442         m_sbuf.Rewind();
00443         m_shift = 0xffffffff;
00444     }
00445     return m_next_state;
00446 }
00447 
00448 void DiracParser::InitStateVars()
00449 {
00450     m_shift = 0xffffffff;
00451     m_found_start = false;
00452     m_found_end = false;
00453 }

Generated on Tue Dec 13 14:47:15 2005 for guliverkli by  doxygen 1.4.5