dirac_cppparser.cpp
上传用户:xjjlds
上传日期:2015-12-05
资源大小:22823k
文件大小:13k
源码类别:

多媒体编程

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2. *
  3. * $Id: dirac_cppparser.cpp,v 1.2 2005/01/30 05:11:41 gabest Exp $ $Name:  $
  4. *
  5. * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  6. *
  7. * The contents of this file are subject to the Mozilla Public License
  8. * Version 1.1 (the "License"); you may not use this file except in compliance
  9. * with the License. You may obtain a copy of the License at
  10. * http://www.mozilla.org/MPL/
  11. *
  12. * Software distributed under the License is distributed on an "AS IS" basis,
  13. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
  14. * the specific language governing rights and limitations under the License.
  15. *
  16. * The Original Code is BBC Research and Development code.
  17. *
  18. * The Initial Developer of the Original Code is the British Broadcasting
  19. * Corporation.
  20. * Portions created by the Initial Developer are Copyright (C) 2004.
  21. * All Rights Reserved.
  22. *
  23. * Contributor(s): Anuradha Suraparaju (Original Author)
  24. *
  25. * Alternatively, the contents of this file may be used under the terms of
  26. * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
  27. * Public License Version 2.1 (the "LGPL"), in which case the provisions of
  28. * the GPL or the LGPL are applicable instead of those above. If you wish to
  29. * allow use of your version of this file only under the terms of the either
  30. * the GPL or LGPL and not to allow others to use your version of this file
  31. * under the MPL, indicate your decision by deleting the provisions above
  32. * and replace them with the notice and other provisions required by the GPL
  33. * or LGPL. If you do not delete the provisions above, a recipient may use
  34. * your version of this file under the terms of any one of the MPL, the GPL
  35. * or the LGPL.
  36. * ***** END LICENSE BLOCK ***** */
  37. #include <sstream>
  38. #include <cstdio>
  39. #include <cstring>
  40. #include <libdirac_common/dirac_assertions.h> 
  41. #include <libdirac_decoder/dirac_cppparser.h>
  42. #include <libdirac_decoder/seq_decompress.h>
  43. #include <libdirac_common/frame.h> 
  44. using namespace dirac;
  45. InputStreamBuffer::InputStreamBuffer()
  46. {
  47.     m_chunk_buffer = new char[m_buffer_size];
  48.     
  49.     setg (m_chunk_buffer,  //beginning of read area
  50.           m_chunk_buffer,  //read position
  51.           m_chunk_buffer); //end position
  52. }
  53. std::ios::pos_type InputStreamBuffer::Rewind()
  54. {
  55.     return Seek(0, std::ios::beg);
  56. }
  57. std::ios::pos_type InputStreamBuffer::Tell()
  58. {
  59.     return gptr() - eback();
  60. }
  61. std::ios::pos_type InputStreamBuffer::Seek(std::ios::pos_type bytes, std::ios::seekdir dir)
  62. {
  63.     char *new_pos;
  64.     switch (dir)
  65.     {
  66.     case std::ios::beg:
  67.         new_pos  = eback() + bytes;
  68.         break;
  69.     case std::ios::end:
  70.         new_pos  = egptr() + bytes;
  71.         break;
  72.     default:
  73.         new_pos  = gptr() + bytes;
  74.         break;
  75.     }
  76.     if (new_pos > egptr() || new_pos < eback())
  77.         return -1;
  78.     setg(eback(), //start of read 
  79.         new_pos, //current read position
  80.         egptr()); //end of stream positon
  81.     return 0;
  82. }
  83. void InputStreamBuffer::Copy(char *start, int bytes)
  84. {
  85.     //std::cerr << "eback=" << m_chunk_buffer - eback() 
  86.      //         << "gptr=" << gptr() -m_chunk_buffer
  87.       //        << "egptr=" << egptr() - m_chunk_buffer << endl;
  88.     int bytes_left = m_buffer_size - (egptr() - m_chunk_buffer);
  89.     if (bytes_left < bytes)
  90.     {
  91.         char *temp =  new char [m_buffer_size + bytes];
  92.         memcpy (temp, m_chunk_buffer, m_buffer_size);
  93.         setg (temp, temp+(gptr()-m_chunk_buffer), temp + (egptr() - m_chunk_buffer));
  94.         delete [] m_chunk_buffer;
  95.         m_chunk_buffer = temp;
  96.     }
  97.     //std::cerr << "eback=" << m_chunk_buffer - eback() 
  98.      //         << "gptr=" << gptr() -m_chunk_buffer
  99.       //        << "egptr=" << egptr() - m_chunk_buffer << endl;
  100.     memcpy (egptr(), start, bytes);
  101.     setg(m_chunk_buffer, gptr(), egptr()+bytes);
  102.     //std::cerr << "eback=" << m_chunk_buffer - eback() 
  103.      //         << "gptr=" << gptr() -m_chunk_buffer
  104.       //        << "egptr=" << egptr() - m_chunk_buffer << endl;
  105. }
  106. void InputStreamBuffer::PurgeProcessedData()
  107. {
  108.     //std::cerr << "eback=" << m_chunk_buffer - eback() 
  109.      //         << "gptr=" << gptr() -m_chunk_buffer
  110.       //        << "egptr=" << egptr() - m_chunk_buffer << endl;
  111.     if (gptr() != m_chunk_buffer)
  112.     {
  113.         memmove (m_chunk_buffer, gptr(), egptr() - gptr());
  114.         setg(m_chunk_buffer, m_chunk_buffer, m_chunk_buffer+(egptr() - gptr()));
  115.     }
  116.     //std::cerr << "eback=" << m_chunk_buffer - eback() 
  117.      //         << "gptr=" << gptr() -m_chunk_buffer
  118.       //        << "egptr=" << egptr() - m_chunk_buffer << endl;
  119. }
  120. InputStreamBuffer::~InputStreamBuffer()
  121. {
  122.     delete [] m_chunk_buffer;
  123. }
  124. DiracParser::DiracParser(bool verbose) : 
  125.     m_state(STATE_BUFFER), 
  126.     m_next_state(STATE_SEQUENCE), 
  127.     m_show_fnum(-1), 
  128.     m_decomp(0), 
  129.     m_skip(false), 
  130.     m_skip_type(L2_frame), 
  131.     m_verbose(verbose),
  132.     m_found_start(false), 
  133.     m_found_end(false), 
  134.     m_shift (0xffffffff)
  135. {
  136.     m_istr = new std::istream(&m_sbuf);
  137. }
  138. DiracParser::~DiracParser()
  139. {
  140.     delete m_istr;
  141.     delete m_decomp;
  142. }
  143. void DiracParser::SetBuffer (char *start, char *end)
  144. {
  145.     TEST (end > start);
  146.     m_sbuf.Copy(start, end - start);
  147. }
  148. DecoderState DiracParser::Parse()
  149. {
  150.     while(true)
  151.     {
  152.         m_state = SeekChunk();
  153.         switch (m_state)
  154.         {
  155.         case STATE_BUFFER:
  156.                 return m_state;
  157.         case STATE_SEQUENCE:
  158.             if (m_next_state == m_state)
  159.             {
  160.                 if (m_decomp)
  161.                     delete m_decomp;
  162.                 m_decomp = new SequenceDecompressor (m_istr, m_verbose);
  163.                 if (m_decomp->GetSeqParams().BitstreamVersion() != BITSTREAM_VERSION)
  164.                 {
  165.                     std::ostringstream errstr;
  166.                     errstr << "Input Bitstream version " << m_decomp->GetSeqParams().BitstreamVersion() << " supported";
  167.                     REPORTM(false, errstr.str().c_str());
  168.                     return STATE_INVALID;
  169.                 }
  170.                 InitStateVars();
  171.                 return m_state;
  172.             }
  173.             else
  174.                 m_state = STATE_BUFFER;
  175.             
  176.             break;
  177.     
  178.         case STATE_PICTURE_START:
  179.             if (m_next_state == m_state)
  180.             {
  181.                 m_decomp->ReadNextFrameHeader();
  182.                 m_next_state = STATE_PICTURE_DECODE;
  183.                 m_sbuf.PurgeProcessedData();
  184.                 return m_state;
  185.             }
  186.             else
  187.             {
  188.                 m_state = STATE_BUFFER;
  189.             }
  190.             break;
  191.         case STATE_PICTURE_DECODE:
  192.         {
  193.             Frame &my_frame = m_decomp->DecompressNextFrame(m_skip);
  194.             if (m_skip)
  195.             {
  196.                 // Go pass start code so that we skip frame
  197.                 m_sbuf.Seek(5);
  198.             }
  199.             else
  200.             {
  201.                 int framenum_decoded = my_frame.GetFparams().FrameNum();
  202.                 if (framenum_decoded != m_show_fnum)
  203.                 {
  204.                     m_show_fnum = my_frame.GetFparams().FrameNum();
  205.                     if (m_verbose)
  206.                     {
  207.                         std::cerr << "Frame " << m_show_fnum << " available" << std::endl;
  208.                     }
  209.                     m_state = STATE_PICTURE_AVAIL;
  210.                 }
  211.             }
  212.             InitStateVars();
  213.             if (m_state == STATE_PICTURE_AVAIL)
  214.                 return m_state;
  215.             break;
  216.         }
  217.         case STATE_SEQUENCE_END:
  218.         {
  219.             //push last frame in sequence out
  220.             m_sbuf.Seek(5);
  221.             Frame &my_frame = m_decomp->DecompressNextFrame(m_skip);
  222.             if (!m_skip)
  223.             {
  224.                 if (my_frame.GetFparams().FrameNum() != m_show_fnum)
  225.                 {
  226.                     m_show_fnum = my_frame.GetFparams().FrameNum();
  227.                     if (m_verbose)
  228.                     {
  229.                         std::cerr << "Frame " << m_show_fnum << " available" << std::endl;
  230.                     }
  231.                     m_state = STATE_PICTURE_AVAIL;
  232.                     m_next_state = STATE_SEQUENCE_END;
  233.                 }
  234.                 else
  235.                 {
  236.                     InitStateVars();
  237.                 }
  238.             }
  239.             else
  240.             {
  241.                 InitStateVars();
  242.             }
  243.             return m_state;
  244.                 
  245.             break;
  246.         }
  247.         default:
  248.             return STATE_INVALID;
  249.         }
  250.     }
  251.     return m_state;
  252. }
  253. const SeqParams& DiracParser::GetSeqParams() const
  254. {
  255.     return m_decomp->GetSeqParams();
  256. }
  257. const FrameParams& DiracParser::GetNextFrameParams() const
  258. {
  259.     return m_decomp->GetNextFrameParams();
  260. }
  261. const Frame& DiracParser::GetNextFrame() const
  262. {
  263.     return m_decomp->GetNextFrame();
  264. }
  265. const Frame& DiracParser::GetLastFrame() const
  266. {
  267.     return  m_decomp->DecompressNextFrame();
  268. }
  269. void DiracParser::SetSkip(bool skip)
  270. {
  271.     const FrameParams& fparams = m_decomp->GetNextFrameParams();
  272.     // FIXME: need to change this logic once bitstream is finalised. so that
  273.     // we skip to next RAP when an L1 frame is skipped
  274.     if (skip == false)
  275.     {
  276.         if (m_skip_type == L2_frame)
  277.             m_skip = false;
  278.         else if (m_skip_type == L1_frame || m_skip_type == I_frame)
  279.         {
  280.             if (fparams.FSort() == L2_frame || fparams.FSort() == L1_frame)
  281.                 m_skip = true;
  282.             else
  283.             {
  284.                 m_skip_type = L2_frame;
  285.                 m_skip = false;
  286.             }
  287.         }
  288.     }
  289.     else
  290.     {
  291.         m_skip = true;
  292.         if (m_skip_type != fparams.FSort())
  293.         {
  294.             switch (fparams.FSort())
  295.             {
  296.             case L2_frame:
  297.                 break;
  298.             case L1_frame:
  299.                 if (m_skip_type != I_frame)
  300.                     m_skip_type = L1_frame;
  301.                 break;
  302.             case I_frame:
  303.                 m_skip_type = I_frame;
  304.                 break;
  305.             default:
  306.                 dirac_ASSERTM(false, "Frame type must be I or L1 or L2");
  307.                 break;
  308.             }
  309.         }
  310.     }
  311. }
  312. DecoderState DiracParser::SeekChunk()
  313. {
  314.     char byte;
  315.     if (!m_found_start)
  316.     {
  317.         while (m_sbuf.sgetn(&byte, 1))
  318.         {
  319.             //Find start of next chunk to be processed
  320.             if (m_shift == START_CODE_PREFIX)
  321.             {
  322.                 switch ((unsigned char)byte)
  323.                 {
  324.                 case NOT_START_CODE:
  325.                     m_shift = 0xffffffff;
  326.                     continue;
  327.                 case RAP_START_CODE:
  328.                     m_next_state = STATE_SEQUENCE;
  329.                     break;
  330.                 case IFRAME_START_CODE:
  331.                 case L1FRAME_START_CODE:
  332.                 case L2FRAME_START_CODE:
  333.                     m_next_state = STATE_PICTURE_START;
  334.                     break;
  335.                 case SEQ_END_CODE:
  336.                     m_next_state = STATE_SEQUENCE_END;
  337.                     break;
  338.                 default:
  339.                     dirac_ASSERTM (false, "Should never have reached here!!!");
  340.                     break;
  341.                 }
  342.                 m_found_start = true;
  343.                 m_sbuf.Seek(-5);
  344.                 m_sbuf.PurgeProcessedData();
  345.                 m_sbuf.Seek(5);
  346.                 m_shift = 0xffffffff;
  347.                 break;
  348.             }
  349.             m_shift = (m_shift << 8) | byte;
  350.         }
  351.         if (!m_found_start)
  352.         {
  353.             m_next_state =  STATE_BUFFER;
  354.         }
  355.     }
  356.     if (m_found_start && !m_found_end && m_next_state != STATE_SEQUENCE_END)
  357.     {
  358.         while (m_sbuf.sgetn(&byte, 1))
  359.         {
  360.             //Find start of next chunk to be processed
  361.             if (m_shift == START_CODE_PREFIX)
  362.             {
  363.                 switch ((unsigned char)byte)
  364.                 {
  365.                 case NOT_START_CODE:
  366.                     m_shift = 0xffffffff;
  367.                     continue;
  368.                 case RAP_START_CODE:
  369.                     break;
  370.                 case IFRAME_START_CODE:
  371.                 case L1FRAME_START_CODE:
  372.                 case L2FRAME_START_CODE:
  373.                     break;
  374.                 case SEQ_END_CODE:
  375.                     break;
  376.                 default:
  377.                     dirac_ASSERTM (false, "Should never have reached here!!!");
  378.                     break;
  379.                 }
  380.                 m_found_end = true;
  381.                 break;
  382.             }
  383.             m_shift = (m_shift << 8) | byte;
  384.         } 
  385.         if (!m_found_end)
  386.         {
  387.             if (m_next_state != STATE_SEQUENCE_END)
  388.                 return STATE_BUFFER;
  389.         }
  390.     }
  391.     if (m_found_start && m_found_end)
  392.     {
  393.         m_sbuf.Rewind();
  394.         m_shift = 0xffffffff;
  395.     }
  396.     return m_next_state;
  397. }
  398. void DiracParser::InitStateVars()
  399. {
  400.     m_shift = 0xffffffff;
  401.     m_found_start = false;
  402.     m_found_end = false;
  403. }