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

多媒体编程

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2. *
  3. * $Id: frame_buffer.cpp,v 1.2 2005/01/30 05:11:40 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): Thomas Davies (Original Author), Scott R Ladd
  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 <libdirac_common/frame_buffer.h>
  38. #include <algorithm>
  39. using namespace dirac;
  40. //Simple constructor for general operation
  41. FrameBuffer::FrameBuffer(ChromaFormat cf,int xlen,int ylen): 
  42.     m_fparams(cf,xlen,ylen),
  43.     m_num_L1(0),
  44.     m_L1_sep(1),
  45.     m_gop_len(0)
  46. {}    
  47. //Constructor for coding with an initial I-frame only    
  48. FrameBuffer::FrameBuffer(ChromaFormat cf,int L1sep, int xlen, int ylen):
  49.     m_fparams(cf,xlen,ylen),
  50.     m_num_L1(0),
  51.     m_L1_sep(L1sep),
  52.     m_gop_len(0)
  53. {}
  54. //Constructor setting GOP parameters for use with a standard GOP
  55. FrameBuffer::FrameBuffer(ChromaFormat cf,int numL1,int L1sep,int xlen,int ylen): 
  56.     m_fparams(cf,xlen,ylen),
  57.     m_num_L1(numL1),
  58.     m_L1_sep(L1sep)
  59. {    
  60.     if (m_num_L1>0)
  61.     {// conventional GOP coding
  62.         m_gop_len = (m_num_L1+1)*m_L1_sep;
  63.     }
  64.     else if (m_num_L1==0)
  65.     {// I-frame only coding
  66.         m_gop_len = 1;
  67.         m_L1_sep = 0;
  68.     }
  69.     else
  70.     {// don't have a proper GOP, only an initial I-frame
  71.         m_gop_len = 0;
  72.     }    
  73. }    
  74. //Copy constructor. Why anyone would need this I don't know.
  75. FrameBuffer::FrameBuffer(const FrameBuffer& cpy)
  76.     {
  77.     // first delete all frames in the current buffer
  78.     for (size_t i=0 ; i<m_frame_data.size() ; ++i)
  79.     {
  80.         delete m_frame_data[i];
  81.     }//i
  82.     // next create new arrays, copying from the initialising buffer
  83.     m_frame_data.resize(cpy.m_frame_data.size());
  84.     for (size_t i=0 ; i<m_frame_data.size() ; ++i){
  85.         m_frame_data[i] = new Frame( *(cpy.m_frame_data[i]) );
  86.     }//i
  87.     // now copy the map
  88.     m_fnum_map = cpy.m_fnum_map;
  89.     // and the internal frame parameters
  90.     m_fparams = cpy.m_fparams;
  91. }
  92. //Assignment=. Not sure why this would be used either.
  93. FrameBuffer& FrameBuffer::operator=(const FrameBuffer& rhs){
  94.     if (&rhs!=this)
  95.     {
  96.         // delete all the frames in the lhs buffer
  97.         for (size_t i=0 ; i<m_frame_data.size() ; ++i)
  98.         {
  99.             delete m_frame_data[i];
  100.         }//i
  101.         // next create new arrays, copying from the rhs
  102.         m_frame_data.resize(rhs.m_frame_data.size());
  103.         for (size_t i=0 ; i<m_frame_data.size() ; ++i)
  104.         {
  105.             m_frame_data[i] = new Frame( *(rhs.m_frame_data[i]) );
  106.         }//i
  107.         // now copy the map
  108.         m_fnum_map = rhs.m_fnum_map;
  109.         // and the internal frame parameters
  110.         m_fparams = rhs.m_fparams;
  111.     }
  112.     return *this;
  113. }
  114. //Destructor
  115. FrameBuffer::~FrameBuffer()
  116. {
  117.     for (size_t i=0 ; i<m_frame_data.size() ;++i)
  118.         delete m_frame_data[i];
  119. }
  120. Frame& FrameBuffer::GetFrame( unsigned int fnum )
  121. {//get frame with a given frame number, NOT with a given position in the buffer.
  122.  //If the frame number does not occur, the first frame in the buffer is returned.
  123.     std::map<unsigned int,unsigned int>::iterator it = m_fnum_map.find(fnum);
  124.     unsigned int pos = 0;    
  125.     if (it != m_fnum_map.end()) 
  126.         pos = it->second;    
  127.     return *(m_frame_data[pos]);
  128. }
  129. const Frame& FrameBuffer::GetFrame( unsigned int fnum ) const
  130. {    //as above, but const version
  131.     std::map<unsigned int,unsigned int>::const_iterator it = m_fnum_map.find(fnum);
  132.     unsigned int pos=0;
  133.     if (it != m_fnum_map.end()) 
  134.         pos = it->second;
  135.     return *(m_frame_data[pos]);
  136. }
  137. PicArray& FrameBuffer::GetComponent( unsigned int fnum , CompSort c)
  138. {//as GetFrame, but returns corresponding component
  139.     std::map<unsigned int,unsigned int>::iterator it = m_fnum_map.find(fnum);
  140.     unsigned int pos = 0;
  141.     if (it!=m_fnum_map.end()) 
  142.         pos = it->second;
  143.     if (c == U_COMP) 
  144.         return m_frame_data[pos]->Udata();
  145.     else if (c == V_COMP) 
  146.         return m_frame_data[pos]->Vdata();
  147.     else 
  148.         return m_frame_data[pos]->Ydata();
  149. }
  150. const PicArray& FrameBuffer::GetComponent( unsigned int fnum , CompSort c ) const 
  151. {//as above, but const version
  152.  
  153.     std::map<unsigned int,unsigned int>::const_iterator it = m_fnum_map.find(fnum);
  154.     unsigned int pos;
  155.     if (it!=m_fnum_map.end()) 
  156.         pos = it->second;
  157.     if (c==U_COMP) 
  158.         return m_frame_data[pos]->Udata();
  159.     else if (c==V_COMP) 
  160.         return m_frame_data[pos]->Vdata();
  161.     else 
  162.         return m_frame_data[pos]->Ydata();
  163. }
  164. // as GetFrame, but returns corresponding upconverted component
  165. PicArray& FrameBuffer::GetUpComponent(unsigned int fnum, CompSort c){
  166.     std::map<unsigned int,unsigned int>::iterator it = m_fnum_map.find(fnum);
  167.     unsigned int pos = 0;
  168.     if (it!=m_fnum_map.end())
  169.         pos = it->second;
  170.     if (c == U_COMP) 
  171.         return m_frame_data[pos]->UpUdata();
  172.     else if (c == V_COMP) 
  173.         return m_frame_data[pos]->UpVdata();
  174.     else 
  175.         return m_frame_data[pos]->UpYdata();
  176. }
  177. const PicArray& FrameBuffer::GetUpComponent(unsigned int fnum, CompSort c) const {//as above, but const version
  178.     std::map<unsigned int,unsigned int>::const_iterator it=m_fnum_map.find(fnum);
  179.     unsigned int pos = 0;
  180.     if (it!=m_fnum_map.end())
  181.         pos = it->second;
  182.     if (c == U_COMP) 
  183.         return m_frame_data[pos]->UpUdata();
  184.     else if (c == V_COMP) 
  185.         return m_frame_data[pos]->UpVdata();
  186.     else 
  187.         return m_frame_data[pos]->UpYdata();
  188. }
  189. void FrameBuffer::PushFrame(unsigned int frame_num)
  190. {// Put a new frame onto the top of the stack using built-in frame parameters
  191.  // with frame number frame_num
  192.     m_fparams.SetFrameNum(frame_num);
  193.     Frame* fptr = new Frame(m_fparams);
  194.     // add the frame to the buffer
  195.     m_frame_data.push_back(fptr);
  196.     
  197.     // put the frame number into the index table
  198.     std::pair<unsigned int,unsigned int> temp_pair(m_fparams.FrameNum() , m_frame_data.size()-1);
  199.     m_fnum_map.insert(temp_pair);
  200. }
  201. void FrameBuffer::PushFrame( const FrameParams& fp )
  202. {// Put a new frame onto the top of the stack
  203.     Frame* fptr = new Frame(fp);
  204.     // add the frame to the buffer
  205.     m_frame_data.push_back(fptr);
  206.     // put the frame number into the index table
  207.     std::pair<unsigned int,unsigned int> temp_pair(fp.FrameNum() , m_frame_data.size()-1);
  208.     m_fnum_map.insert(temp_pair);
  209. }
  210. void FrameBuffer::PushFrame( const Frame& frame )
  211. {
  212.     // Put a copy of a new frame onto the top of the stack
  213.     Frame* fptr = new Frame( frame );
  214.     // Add the frame to the buffer
  215.     m_frame_data.push_back(fptr);
  216.     // Put the frame number into the index table
  217.     std::pair<unsigned int,unsigned int> tmp_pair(frame.GetFparams().FrameNum() ,
  218.                                                    m_frame_data.size()-1);
  219.     m_fnum_map.insert(tmp_pair);
  220. }
  221. void FrameBuffer::PushFrame(StreamPicInput* picin,const FrameParams& fp)
  222. {
  223.     //Read a frame onto the top of the stack
  224.     PushFrame(fp);
  225.     picin->ReadNextFrame( *(m_frame_data[m_frame_data.size()-1]) );
  226. }
  227. void FrameBuffer::PushFrame(StreamPicInput* picin, unsigned int fnum)
  228. {
  229.    //Read a frame onto the top of the stack    
  230.     SetFrameParams( fnum );
  231.     PushFrame( picin , m_fparams );
  232. }
  233. void FrameBuffer::Remove(unsigned int pos)
  234. {//remove frame fnum from the buffer, shifting everything above down
  235.     std::pair<unsigned int,unsigned int>* tmp_pair;
  236.     if (pos<m_frame_data.size())
  237.     {
  238.         delete m_frame_data[pos];
  239.         m_frame_data.erase(m_frame_data.begin()+pos,m_frame_data.begin()+pos+1);
  240.          //make a new map
  241.         m_fnum_map.clear();
  242.         for (size_t i=0 ; i<m_frame_data.size() ; ++i)
  243.         {
  244.             tmp_pair = new std::pair<unsigned int,unsigned int>( m_frame_data[i]->GetFparams().FrameNum() , i);
  245.             m_fnum_map.insert(*tmp_pair);
  246.             delete tmp_pair;
  247.         }//i
  248.     }
  249. }
  250. void FrameBuffer::Clean(int fnum)
  251. {// clean out all frames that have expired
  252.     for (size_t i=0 ; i<m_frame_data.size() ; ++i)
  253.     {
  254.         if ((m_frame_data[i]->GetFparams().FrameNum() + m_frame_data[i]->GetFparams().ExpiryTime() ) <= fnum)
  255.             Remove(i);
  256.     }//i
  257. }
  258. void FrameBuffer::SetFrameParams( unsigned int fnum )
  259. {    
  260.     // Set the frame parameters, given the GOP set-up and the frame number in display order
  261.     // This function can be ignored by setting the frame parameters directly if required
  262.     m_fparams.SetFrameNum( fnum );
  263.     m_fparams.Refs().clear();    
  264.     if ( m_gop_len>0 )
  265.     {
  266.         if ( fnum % m_gop_len == 0)
  267.         {
  268.             m_fparams.SetFSort( I_frame );
  269.             // I frame expires after we've coded the next I frame
  270.             m_fparams.SetExpiryTime( m_gop_len );
  271.         }
  272.         else if (fnum % m_L1_sep == 0)
  273.         {
  274.             m_fparams.SetFSort( L1_frame );
  275.             // Ref the previous I or L1 frame
  276.             m_fparams.Refs().push_back( fnum - m_L1_sep );
  277.             // if we don't have the first L1 frame ...
  278.             if ((fnum-m_L1_sep) % m_gop_len>0)
  279.                 // ... other ref is the prior I frame
  280.                 m_fparams.Refs().push_back( ( fnum/m_gop_len ) * m_gop_len  );
  281.             // Expires after the next L1 or I frame            
  282.             m_fparams.SetExpiryTime( m_L1_sep );
  283.         }
  284.         else
  285.         {
  286.             m_fparams.SetFSort( L2_frame );
  287.             // Refs are the next or previous I or L1 frame
  288.             m_fparams.Refs().push_back((fnum/m_L1_sep)*m_L1_sep);
  289.             m_fparams.Refs().push_back(((fnum/m_L1_sep)+1)*m_L1_sep);
  290.             m_fparams.SetExpiryTime( 1 );  
  291.             // ( L2 frames could expire directly after being coded, but putting in a delay of 1
  292.             // allows for frame-skipping to be done, since the frame will still be around to
  293.             // be used if the next frame is skipped. )
  294.         }
  295.     }    
  296.     else{        
  297.         if (fnum==0)
  298.         {
  299.             m_fparams.SetFSort( I_frame );
  300.             m_fparams.SetExpiryTime( 1<<30 );//ie never
  301.         }
  302.         else if (fnum % m_L1_sep==0)
  303.         {
  304.             m_fparams.SetFSort( L1_frame );
  305.             m_fparams.Refs().push_back(0);//frame 0 is the I frame
  306.             if (fnum != m_L1_sep)//we don't have the first L1 frame    
  307.                 m_fparams.Refs().push_back(fnum-m_L1_sep);//other ref is the prior L1 frame
  308.             //expires after the next L1 or I frame                        
  309.             m_fparams.SetExpiryTime( m_L1_sep );
  310.         }
  311.         else
  312.         {
  313.             m_fparams.SetFSort( L2_frame );
  314.             m_fparams.Refs().push_back((fnum/m_L1_sep)*m_L1_sep);
  315.             m_fparams.Refs().push_back(((fnum/m_L1_sep)+1)*m_L1_sep);
  316.             m_fparams.SetExpiryTime( 1 );    //L2 frames could expire directly after being coded, but putting in a delay of 1
  317.                                         //allows for frame-skipping to be done, since the frame will still be around to
  318.                                         //be used if the next frame is skipped.
  319.         }
  320.     }
  321. }