/* ***** BEGIN LICENSE BLOCK ***** * * $Id: frame_decompress.cpp,v 1.26 2007/04/26 13:56:31 asuraparaju Exp $ $Name: Dirac_0_7_0 $ * * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for * the specific language governing rights and limitations under the License. * * The Original Code is BBC Research and Development code. * * The Initial Developer of the Original Code is the British Broadcasting * Corporation. * Portions created by the Initial Developer are Copyright (C) 2004. * All Rights Reserved. * * Contributor(s): Thomas Davies (Original Author), * Scott R Ladd, * Anuradha Suraparaju, * Andrew Kennedy, * Tim Borer * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser * Public License Version 2.1 (the "LGPL"), in which case the provisions of * the GPL or the LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the either * the GPL or LGPL and not to allow others to use your version of this file * under the MPL, indicate your decision by deleting the provisions above * and replace them with the notice and other provisions required by the GPL * or LGPL. If you do not delete the provisions above, a recipient may use * your version of this file under the terms of any one of the MPL, the GPL * or the LGPL. * ***** END LICENSE BLOCK ***** */ //Decompression of frames ///////////////////////// #include #include #include #include #include #include #include using namespace dirac; #include #include using std::vector; using std::auto_ptr; FrameDecompressor::FrameDecompressor(DecoderParams& decp, ChromaFormat cf, unsigned int vd) : m_decparams(decp), m_cformat(cf), m_video_depth(vd) { } FrameDecompressor::~FrameDecompressor() { } bool FrameDecompressor::Decompress(ParseUnitByteIO& parseunit_byteio, FrameBuffer& my_buffer, int au_fnum) { // get current byte position //int start_pos = parseunit_byteio.GetReadBytePosition(); try { // read frame data FrameByteIO frame_byteio(m_fparams, parseunit_byteio, au_fnum); frame_byteio.Input(); FrameSort fs; if (m_fparams.GetFrameType() == INTRA_FRAME) fs.SetIntra(); else fs.SetInter(); if (m_fparams.GetReferenceType() == REFERENCE_FRAME) fs.SetRef(); else fs.SetNonRef(); m_fparams.SetFSort(fs); // Check if the frame can be decoded if (m_fparams.FSort().IsInter()) { const std::vector& refs = m_fparams.Refs(); for (unsigned int i = 0; i < refs.size(); ++i) { if ( !my_buffer.IsFrameAvail(refs[i]) ) { return false; } } } m_skipped=false; if ( !m_skipped ) {//if we're not m_skipped then we can decode the rest of the frame if ( m_decparams.Verbose() ) { std::cout<1 ) std::cout<<" and "< mv_data; // unsigned int num_mv_bits; if ( fsort.IsInter() ) { //do all the MV stuff DecompressMVData( mv_data, frame_byteio ); } // Read the transform header TransformByteIO transform_byteio(frame_byteio, m_fparams, m_decparams); transform_byteio.Input(); if (m_fparams.FSort().IsIntra() && m_decparams.ZeroTransform()) { DIRAC_THROW_EXCEPTION( ERR_UNSUPPORTED_STREAM_DATA, "Intra frames cannot have Zero-Residual", SEVERITY_FRAME_ERROR); } // Set frame dimensions based on the transform depth. If zero residual // then use the actual picture dimensions PushFrame(my_buffer); //Reference to the frame being decoded Frame& my_frame = my_buffer.GetFrame(m_fparams.FrameNum()); if (!m_decparams.ZeroTransform()) { //decode components CompDecompress( &transform_byteio, my_buffer,m_fparams.FrameNum() , Y_COMP ); CompDecompress( &transform_byteio, my_buffer , m_fparams.FrameNum() , U_COMP ); CompDecompress( &transform_byteio, my_buffer , m_fparams.FrameNum() , V_COMP ); } if ( fsort.IsInter() ) //motion compensate to add the data back in if we don't have an I frame MotionCompensator::CompensateFrame( m_decparams , ADD , my_buffer , m_fparams.FrameNum() , *(mv_data.get()) ); my_frame.Clip(); if (m_decparams.Verbose()) std::cout<& retd_list = m_fparams.RetiredFrames(); for (size_t i = 0; i < retd_list.size(); ++i) { if ( my_buffer.IsFrameAvail(retd_list[i]) && my_buffer.GetFrame(retd_list[i]).GetFparams().FSort().IsRef() ) { my_buffer.Clean(retd_list[i]); if ( m_decparams.Verbose() ) std::cout<& mv_data, FrameByteIO& frame_byteio ) { MvDataByteIO mvdata_byteio (frame_byteio, m_fparams, m_decparams); // Read in the frame prediction parameters mvdata_byteio.Input(); SetMVBlocks(); mv_data.reset(new MvData( m_decparams.XNumMB() , m_decparams.YNumMB(), m_fparams.NumRefs() )); // decode mv data if (m_decparams.Verbose()) std::cout<Input(); // Read the mode data num_bits = mvdata_byteio.SplitModeData()->DataBlockSize(); SplitModeCodec smode_decoder( mvdata_byteio.SplitModeData()->DataBlock(), TOTAL_MV_CTXS); smode_decoder.Decompress( *(mv_data.get()) , num_bits); // Read in the prediction mode data header mvdata_byteio.PredModeData()->Input(); // Read the mode data num_bits = mvdata_byteio.PredModeData()->DataBlockSize(); PredModeCodec pmode_decoder( mvdata_byteio.PredModeData()->DataBlock(), TOTAL_MV_CTXS); pmode_decoder.Decompress( *(mv_data.get()) , num_bits); // Read in the MV1 horizontal data header mvdata_byteio.MV1HorizData()->Input(); // Read the MV1 horizontal data num_bits = mvdata_byteio.MV1HorizData()->DataBlockSize(); VectorElementCodec vdecoder1h( mvdata_byteio.MV1HorizData()->DataBlock(), 1, HORIZONTAL, TOTAL_MV_CTXS); vdecoder1h.Decompress( *(mv_data.get()) , num_bits); // Read in the MV1 vertical data header mvdata_byteio.MV1VertData()->Input(); // Read the MV1 data num_bits = mvdata_byteio.MV1VertData()->DataBlockSize(); VectorElementCodec vdecoder1v( mvdata_byteio.MV1VertData()->DataBlock(), 1, VERTICAL, TOTAL_MV_CTXS); vdecoder1v.Decompress( *(mv_data.get()) , num_bits); if ( (mv_data.get())->NumRefs()>1 ) { // Read in the MV2 horizontal data header mvdata_byteio.MV2HorizData()->Input(); // Read the MV2 horizontal data num_bits = mvdata_byteio.MV2HorizData()->DataBlockSize(); VectorElementCodec vdecoder2h( mvdata_byteio.MV2HorizData()->DataBlock(), 2, HORIZONTAL, TOTAL_MV_CTXS); vdecoder2h.Decompress( *(mv_data.get()) , num_bits); // Read in the MV2 vertical data header mvdata_byteio.MV2VertData()->Input(); // Read the MV2 vertical data num_bits = mvdata_byteio.MV2VertData()->DataBlockSize(); VectorElementCodec vdecoder2v( mvdata_byteio.MV2VertData()->DataBlock(), 2, VERTICAL, TOTAL_MV_CTXS); vdecoder2v.Decompress( *(mv_data.get()) , num_bits); } // Read in the Y DC data header mvdata_byteio.YDCData()->Input(); // Read the Y DC data num_bits = mvdata_byteio.YDCData()->DataBlockSize(); DCCodec ydc_decoder( mvdata_byteio.YDCData()->DataBlock(), Y_COMP, TOTAL_MV_CTXS); ydc_decoder.Decompress( *(mv_data.get()) , num_bits); // Read in the U DC data header mvdata_byteio.UDCData()->Input(); // Read the U DC data num_bits = mvdata_byteio.UDCData()->DataBlockSize(); DCCodec udc_decoder( mvdata_byteio.YDCData()->DataBlock(), U_COMP, TOTAL_MV_CTXS); udc_decoder.Decompress( *(mv_data.get()) , num_bits); // Read in the Y DC data header mvdata_byteio.YDCData()->Input(); // Read the Y DC data num_bits = mvdata_byteio.YDCData()->DataBlockSize(); DCCodec vdc_decoder( mvdata_byteio.VDCData()->DataBlock(), V_COMP, TOTAL_MV_CTXS); vdc_decoder.Decompress( *(mv_data.get()) , num_bits); }