dirac_encoder.cpp

00001 /* ***** BEGIN LICENSE BLOCK *****
00002 *
00003 * $Id: dirac_encoder.cpp,v 1.1 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 <cstring>
00039 #include <sstream>
00040 #include <fstream>
00041 #include <queue>
00042 #include <libdirac_common/dirac_assertions.h>
00043 #include <libdirac_common/common.h>
00044 #include <libdirac_common/frame.h>
00045 #include <libdirac_common/pic_io.h>
00046 #include <libdirac_encoder/dirac_encoder.h>
00047 #include <libdirac_encoder/seq_compress.h>
00048 using namespace dirac;
00049 
00050 template <class T >
00051 void copy_2dArray (const TwoDArray<T> & in, T *out)
00052 {
00053     for (int j=0 ; j<in.LengthY() ; ++j)
00054     {
00055         for (int i=0 ; i<in.LengthX() ; ++i)
00056         {
00057             // out[j*in.LengthX() + i] =  in[j][i];
00058             *out++ =  in[j][i];
00059         }// i
00060     }// j
00061 }
00062 
00063 void copy_2dArray (const TwoDArray<PredMode> & in, int *out)
00064 {
00065     for (int j=0 ; j<in.LengthY() ; ++j)
00066     {
00067         for (int i=0 ; i<in.LengthX() ; ++i)
00068         {
00069             // out[j*in.LengthX() + i] =  in[j][i];
00070             *out++ =  in[j][i];
00071         }// i
00072     }// j
00073 }
00074 
00075 void copy_2dArray (const TwoDArray<bool> & in, int *out)
00076 {
00077     for (int j=0 ; j<in.LengthY() ; ++j)
00078     {
00079         for (int i=0 ; i<in.LengthX() ; ++i)
00080         {
00081             // out[j*in.LengthX() + i] =  in[j][i];
00082             *out++ =  in[j][i];
00083         }// i
00084     }// j
00085 }
00086 
00087 void copy_mv ( const MvArray& mv, dirac_mv_t *dmv)
00088 {
00089     for (int j=0 ; j<mv.LengthY() ; ++j)
00090     {
00091         for (int i=0 ; i<mv.LengthX() ; ++i)
00092         {
00093             //dmv[j*mv.LengthX() + i].x = mv[j][i].x;
00094             //dmv[j*mv.LengthX() + i].y = mv[j][i].y;
00095             (*dmv).x = mv[j][i].x;
00096             (*dmv).y = mv[j][i].y;
00097             dmv++;
00098         }// i
00099     }// j
00100 }
00101 
00102 void copy_mv_cost (const TwoDArray<MvCostData> &pc, dirac_mv_cost_t *dpc)
00103 {
00104     for (int j=0 ; j<pc.LengthY() ; ++j)
00105     {
00106         for (int i=0 ; i<pc.LengthX() ; ++i)
00107         {
00108             //dpc[j*pc.LengthX() + i].SAD = pc[j][i].SAD;
00109             //dpc[j*pc.LengthX() + i].mvcost = pc[j][i].mvcost;
00110             (*dpc).SAD = pc[j][i].SAD;
00111             (*dpc).mvcost = pc[j][i].mvcost;
00112             dpc++;
00113         }// i
00114     }// j
00115 }
00116 
00117 /*
00118     Function that allocates the locally managed instrumentation data
00119 */
00120 void alloc_instr_data(dirac_instr_t *instr)
00121 {
00122     instr->mb_split_mode = new int [instr->mb_ylen*instr->mb_xlen];
00123     memset (instr->mb_split_mode, 0, sizeof(int)*instr->mb_ylen*instr->mb_xlen);
00124 
00125     instr->mb_common_mode = new int [instr->mb_ylen*instr->mb_xlen];
00126     memset (instr->mb_common_mode, 0, 
00127                     sizeof(int)*instr->mb_ylen*instr->mb_xlen);
00128 
00129     instr->mb_costs = new float [instr->mb_ylen*instr->mb_xlen];
00130     memset (instr->mb_costs, 0, sizeof(float)*instr->mb_ylen*instr->mb_xlen);
00131 
00132     instr->pred_mode = new int [instr->mv_ylen * instr->mv_xlen];
00133     memset (instr->pred_mode, 0, sizeof(int)*instr->mv_ylen*instr->mv_xlen);
00134         
00135     instr->intra_costs = new float [instr->mv_ylen * instr->mv_xlen];
00136     memset (instr->intra_costs, 0, sizeof(float)*instr->mv_ylen*instr->mv_xlen);
00137         
00138     instr->bipred_costs = new dirac_mv_cost_t [instr->mv_ylen * instr->mv_xlen];
00139     memset (instr->bipred_costs, 0, sizeof(dirac_mv_cost_t)*instr->mv_ylen*instr->mv_xlen);
00140         
00141     instr->dc_ycomp = new short [instr->mv_ylen * instr->mv_xlen];
00142     memset (instr->dc_ycomp, 0, sizeof(short)*instr->mv_ylen*instr->mv_xlen);
00143         
00144     instr->dc_ucomp = new short [instr->mv_ylen * instr->mv_xlen];
00145     memset (instr->dc_ucomp, 0, sizeof(short)*instr->mv_ylen*instr->mv_xlen);
00146         
00147     instr->dc_vcomp = new short [instr->mv_ylen * instr->mv_xlen];
00148     memset (instr->dc_vcomp, 0, sizeof(short)*instr->mv_ylen*instr->mv_xlen);
00149         
00150     for (int i = 0; i < 2; i++)
00151     {
00152         instr->mv[i] = new dirac_mv_t[instr->mv_ylen * instr->mv_xlen];
00153         memset (instr->mv[i], 0, 
00154             sizeof(dirac_mv_t)*instr->mv_ylen*instr->mv_xlen);
00155     }
00156         
00157     for (int i = 0; i < 2; i++)
00158     {
00159         instr->pred_costs[i] = new dirac_mv_cost_t[instr->mv_ylen * instr->mv_xlen];
00160         memset (instr->pred_costs[i], 0, 
00161             sizeof(dirac_mv_cost_t)*instr->mv_ylen*instr->mv_xlen);
00162     }
00163 }
00164 
00165 /*
00166     Function that frees the locally managed instrumentation data
00167 */
00168 void dealloc_instr_data(dirac_instr_t *instr)
00169 {
00170     if (instr->mb_split_mode)
00171         delete [] instr->mb_split_mode;
00172 
00173     if (instr->mb_common_mode)
00174         delete [] instr->mb_common_mode;
00175 
00176     if (instr->mb_costs)
00177         delete [] instr->mb_costs;
00178 
00179     if (instr->pred_mode)
00180         delete [] instr->pred_mode;
00181 
00182     if (instr->intra_costs)
00183         delete [] instr->intra_costs;
00184 
00185     if (instr->bipred_costs)
00186         delete [] instr->bipred_costs;
00187 
00188     if (instr->dc_ycomp)
00189         delete [] instr->dc_ycomp;
00190 
00191     if (instr->dc_ucomp)
00192         delete [] instr->dc_ucomp;
00193 
00194     if (instr->dc_vcomp)
00195         delete [] instr->dc_vcomp;
00196 
00197     for (int i = 0; i < 2; i++)
00198     {
00199         if (instr->mv[i])
00200             delete [] instr->mv[i];
00201     }
00202     for (int i = 0; i < 2; i++)
00203     {
00204         if (instr->pred_costs[i])
00205             delete [] instr->pred_costs[i];
00206     }
00207 }
00208 
00209 /*
00210     Wrapper class around the SequenceCompressor Class. This class is used 
00211     by the "C" encoder interface
00212 */
00213 class DiracEncoder
00214 {
00215 public:
00216     // constructor
00217     DiracEncoder(const dirac_encoder_context_t *enc_ctx, bool verbose);
00218     // destructor
00219     ~DiracEncoder();
00220 
00221     // Load the next frame of uncompressed data into the SequenceCompressor
00222     bool LoadNextFrame(unsigned char *data, int size);
00223     // Compress the next frame of data
00224     int CompressNextFrame();
00225 
00226     // Set the encode frame in encoder to the encoded frame data
00227     int GetEncodedData(dirac_encoder_t *encoder);
00228     
00229     // Set the locally decoded frame data in encoder
00230     int GetDecodedData (dirac_encoder_t *encoder);
00231 
00232     // Set the instrumentation data in encoder
00233     void GetInstrumentationData (dirac_encoder_t *encoder);
00234 
00235     // Set the end of sequence infomration in encoder
00236     int GetSequenceEnd(dirac_encoder_t *encoder);
00237 
00238     // Set the buffer to hold the locally decoded frame
00239     void SetDecodeBuffer (unsigned char *buffer, int buffer_size);
00240 
00241     // Return the sequence parameters
00242     const SeqParams& GetSeqParams() const { return m_sparams; }
00243 
00244     // Return the encoder parameters
00245     const EncoderParams& GetEncParams() const { return m_encparams; }
00246 
00247 private:
00248 
00249     // Set the sequence parameters
00250     void SetSequenceParams (const dirac_encoder_context_t *enc_ctx);
00251     
00252     // Set the encoder parameters
00253     void SetEncoderParams (const dirac_encoder_context_t *enc_ctx);
00254 
00255     // Get the frame statistics
00256     void GetFrameStats(dirac_encoder_t *encoder);
00257 
00258     // Get the seuqence statistics
00259     void GetSequenceStats(dirac_encoder_t *encoder);
00260 
00261 private:
00262     // sequence compressor
00263     SequenceCompressor *m_comp;
00264     // sequence parameters
00265     SeqParams m_sparams;
00266     // encoder parameters
00267     EncoderParams m_encparams;
00268     // stream to hold the compressed frame
00269     std::ostringstream m_comp_stream;
00270     // locally encoded frame in coded order
00271     const Frame *m_enc_frame;
00272     // locally encoded frame ME data
00273     const MEData *m_enc_medata;
00274     // locally decoded frame number in display order
00275     int m_decfnum;
00276     //locally decoded frame type
00277     FrameSort m_decfsort;
00278     // locally decoded frame number in display order
00279     int m_show_fnum;
00280     // total number of frame loaded so far
00281     int m_num_loaded_frames;
00282     // total number of frames encoded so far
00283     int m_num_coded_frames;
00284     // verbose flag
00285     bool m_verbose;
00286     // input stream for uncompressed input frame
00287     MemoryStreamInput m_inp_ptr;
00288     // output stream for locally decoded frame
00289     MemoryStreamOutput m_out_ptr;
00290     // buffer to hold locally decoded frame. Set by SetDecodeBuffer
00291     unsigned char *m_dec_buf;
00292     // size of buffer to hold locally decoded data. Set by SetDecodeBuffer
00293     int m_dec_bufsize;
00294     // Flag that determines if locally decoded frames are to be returned. Set
00295     // in Constructor
00296     bool m_return_decoded_frames;
00297     // Flag that determines if instrumentation data is to be returned. Set
00298     // in Constructor
00299     bool m_return_instr_data;
00300 };
00301 
00302 /*
00303     Instrumentation callback. This function is passed as a parameter to the
00304     SequenceCompressor constructor. It is called by the 
00305     FrameCompressor::Compress function once the frame is successfully compressed
00306 */
00307 void DiracEncoder::GetInstrumentationData (dirac_encoder_t *encoder)
00308 {
00309     dirac_ASSERT (encoder != NULL);
00310     dirac_instr_t *instr = &encoder->instr;
00311     dirac_instr_t old_instr = *instr;
00312 
00313     if (!m_return_instr_data)
00314         return;
00315 
00316     const FrameParams& fparams = m_enc_frame->GetFparams();
00317     const FrameSort fsort = fparams.FSort();
00318 
00319     instr->fnum = fparams.FrameNum();
00320     instr->ftype = fsort;
00321     instr->num_refs = 0;
00322     encoder->instr_data_avail = 1;
00323 
00324     if (fsort == I_frame)
00325     {
00326         // no MV data for Intra coded data
00327         return;
00328     }
00329 
00330     TESTM (m_enc_medata != NULL, "ME data available");
00331 
00332     // Reference info
00333     instr->num_refs = fparams.Refs().size();
00334     dirac_ASSERTM (instr->num_refs <= 2, "Max # reference frames is 2");
00335 
00336     for (int i=0; i<instr->num_refs; ++i)
00337         instr->refs[i] = fparams.Refs()[i];
00338 
00339     // Block separation params
00340     instr->ybsep = m_encparams.LumaBParams(2).Ybsep();
00341     instr->xbsep = m_encparams.LumaBParams(2).Xbsep();
00342 
00343     // Num macroblocks
00344     instr->mb_ylen = m_enc_medata->MBSplit().LengthY();
00345     instr->mb_xlen = m_enc_medata->MBSplit().LengthX();
00346 
00347     // Motion vector array dimensions
00348     instr->mv_ylen = m_enc_medata->Vectors(1).LengthY();
00349     instr->mv_xlen = m_enc_medata->Vectors(1).LengthX();
00350 
00351     if (old_instr.mb_ylen != instr->mb_ylen || 
00352         old_instr.mb_xlen != instr->mb_xlen ||
00353         old_instr.mv_ylen != instr->mv_ylen || 
00354         old_instr.mv_xlen != instr->mv_xlen)
00355     {
00356         dealloc_instr_data(instr);
00357         alloc_instr_data(instr);
00358     }
00359 
00360     copy_2dArray (m_enc_medata->MBSplit(), instr->mb_split_mode);
00361     copy_2dArray (m_enc_medata->MBCommonMode(), instr->mb_common_mode);
00362     copy_2dArray (m_enc_medata->MBCosts(), instr->mb_costs);
00363     copy_2dArray (m_enc_medata->Mode(), instr->pred_mode);
00364     copy_2dArray (m_enc_medata->IntraCosts(), instr->intra_costs);
00365 
00366     // FIXME: Always allocating for bipred_costs even though no data available
00367     //  Since medata is always created assuming two references
00368     // if (instr->num_refs > 1)
00369     {
00370         copy_mv_cost (m_enc_medata->BiPredCosts(), instr->bipred_costs);
00371     }
00372 
00373     copy_2dArray (m_enc_medata->DC( Y_COMP ), instr->dc_ycomp);
00374     if (m_enc_medata->DC().Length() == 3 && 
00375         encoder->enc_ctx.seq_params.chroma != Yonly)
00376     {
00377         copy_2dArray (m_enc_medata->DC( U_COMP ), instr->dc_ucomp);
00378         copy_2dArray (m_enc_medata->DC( V_COMP ), instr->dc_vcomp);
00379     }
00380 
00381     // FIXME: Always allocating for bipred_costs even though no data available
00382     //  Since medata is always created assuming two references
00383     // for (int i=1; i<=instr->num_refs; ++i)
00384     for (int i=1; i<=2; ++i)
00385     {
00386         copy_mv (m_enc_medata->Vectors(i), instr->mv[i-1]);
00387         copy_mv_cost (m_enc_medata->PredCosts(i), instr->pred_costs[i-1]);
00388     }
00389 }
00390 
00391 DiracEncoder::DiracEncoder(const dirac_encoder_context_t *enc_ctx, 
00392                            bool verbose) :
00393     m_show_fnum(-1),
00394     m_num_loaded_frames(0),
00395     m_num_coded_frames(0),
00396     m_verbose(verbose),
00397     m_dec_buf(0),
00398     m_dec_bufsize(0),
00399     m_return_decoded_frames(enc_ctx->decode_flag > 0),
00400     m_return_instr_data(enc_ctx->instr_flag > 0)
00401 {
00402     // Setup sequence parameters
00403     SetSequenceParams (enc_ctx);
00404     // Setup encoder parameters
00405     m_encparams.SetVerbose( verbose );
00406     SetEncoderParams (enc_ctx);
00407 
00408     // Set up the input data stream (uncompressed data)
00409     m_inp_ptr.SetSequenceParams(m_sparams);
00410     // Set up the output data stream (locally decoded frame)
00411     m_out_ptr.SetSequenceParams(m_sparams);
00412     
00413     // initialise the sequence compressor
00414     m_comp = new SequenceCompressor (&m_inp_ptr, &m_comp_stream, m_encparams);
00415 }
00416 
00417 void DiracEncoder::SetDecodeBuffer (unsigned char *buffer, int buffer_size)
00418 {
00419     m_dec_buf = buffer;
00420     m_dec_bufsize = buffer_size;
00421     m_return_decoded_frames = true;
00422 }
00423 
00424 DiracEncoder::~DiracEncoder()
00425 {
00426     delete m_comp;
00427 }
00428 
00429 void DiracEncoder::SetSequenceParams (const dirac_encoder_context_t *enc_ctx)
00430 {
00431     m_sparams.SetCFormat( enc_ctx->seq_params.chroma );
00432     m_sparams.SetXl( enc_ctx->seq_params.width );
00433     m_sparams.SetYl( enc_ctx->seq_params.height );
00434     m_sparams.SetInterlace( enc_ctx->seq_params.interlace );
00435     m_sparams.SetTopFieldFirst( enc_ctx->seq_params.topfieldfirst );
00436     m_sparams.SetFrameRate( enc_ctx->seq_params.frame_rate.numerator /
00437                             enc_ctx->seq_params.frame_rate.denominator );
00438 }
00439 
00440 void DiracEncoder::SetEncoderParams (const dirac_encoder_context_t *enc_ctx)
00441 {
00442     TEST (enc_ctx != NULL);
00443     OLBParams bparams(12, 12, 8, 8);
00444 
00445     m_encparams.SetQf(enc_ctx->enc_params.qf);
00446     m_encparams.SetL1Sep(enc_ctx->enc_params.L1_sep);
00447     m_encparams.SetNumL1(enc_ctx->enc_params.num_L1);
00448     m_encparams.SetCPD(enc_ctx->enc_params.cpd);
00449     m_encparams.SetUFactor(3.0f);
00450     m_encparams.SetVFactor(1.75f);
00451     bparams.SetYblen( enc_ctx->enc_params.yblen );
00452     bparams.SetXbsep( enc_ctx->enc_params.xblen );
00453     bparams.SetYbsep( enc_ctx->enc_params.ybsep );
00454     bparams.SetXbsep( enc_ctx->enc_params.xbsep );
00455 
00456     // Now rationalise the GOP options
00457     // this stuff should really be done in a constructor!
00458     if (m_encparams.NumL1()<0)
00459     {
00460         //don't have a proper GOP
00461         m_encparams.SetL1Sep( std::max(1 , m_encparams.L1Sep()) );
00462     }
00463     else if (m_encparams.NumL1() == 0)
00464     {
00465         //have I-frame only coding
00466         m_encparams.SetL1Sep(0);
00467     }
00468     m_encparams.SetOrigXl( enc_ctx->seq_params.width );
00469     m_encparams.SetOrigYl( enc_ctx->seq_params.height );
00470     m_encparams.SetBlockSizes( bparams , enc_ctx->seq_params.chroma );
00471 }
00472 
00473 
00474 bool DiracEncoder::LoadNextFrame (unsigned char *data, int size)
00475 {
00476     TESTM (m_comp->Finished() != true, "Did not reach end of sequence");
00477     m_inp_ptr.SetMembufReference(data, size);
00478     if (m_comp->LoadNextFrame())
00479     {
00480         m_num_loaded_frames++;
00481         return true;
00482     }
00483     return false;
00484 }
00485 
00486 int DiracEncoder::CompressNextFrame ()
00487 {
00488     TESTM (m_comp->Finished() != true, "Did not reach end of sequence");
00489 
00490     if (!m_num_loaded_frames)
00491         return 0;
00492 
00493     Frame &myframe = m_comp->CompressNextFrame();
00494 
00495     m_enc_frame = m_comp->GetFrameEncoded();
00496     m_enc_medata = m_comp->GetMEData();
00497 
00498     m_decfnum = -1;
00499     if (m_return_decoded_frames && 
00500             myframe.GetFparams().FrameNum() != m_show_fnum)
00501     {
00502         int ret_val;
00503         m_show_fnum = myframe.GetFparams().FrameNum();
00504         TEST (! (m_return_decoded_frames && !m_dec_buf) );
00505         if (m_return_decoded_frames && m_dec_buf)
00506         {
00507             // write locally decoded frame to decode buffer
00508             m_out_ptr.SetMembufReference(m_dec_buf, m_dec_bufsize);
00509             ret_val = m_out_ptr.WriteNextFrame(myframe);
00510 
00511             if (ret_val)
00512             {
00513                 m_decfnum = m_show_fnum;
00514                 m_decfsort = myframe.GetFparams().FSort();
00515             }
00516         }
00517     }
00518 
00519     int size = m_comp_stream.str().size();
00520     if (size > 0)
00521     {
00522         m_num_coded_frames++;
00523         TESTM (m_enc_frame != 0, "Encoder frame available");
00524     }
00525     return size;
00526 }
00527 
00528 void DiracEncoder::GetFrameStats(dirac_encoder_t *encoder)
00529 {
00530     const FrameOutputManager& foutput = m_encparams.BitsOut().FrameOutput();
00531     dirac_enc_framestats_t *fstats = &encoder->enc_fstats;
00532 
00533     fstats->mv_bits = foutput.MVBytes() * 8;
00534     fstats->mv_hdr_bits = foutput.MVBytes() * 8;
00535 
00536     fstats->ycomp_bits = foutput.ComponentBytes( Y_COMP ) * 8;
00537     fstats->ycomp_hdr_bits = foutput.ComponentHeadBytes( Y_COMP ) * 8;
00538 
00539     fstats->ucomp_bits = foutput.ComponentBytes( U_COMP ) * 8;
00540     fstats->ucomp_hdr_bits = foutput.ComponentHeadBytes( U_COMP ) * 8;
00541 
00542     fstats->vcomp_bits = foutput.ComponentBytes( V_COMP ) * 8;
00543     fstats->vcomp_hdr_bits = foutput.ComponentHeadBytes( V_COMP ) * 8;
00544 
00545     fstats->frame_bits = foutput.FrameBytes() * 8;
00546     fstats->frame_hdr_bits = foutput.FrameHeadBytes() * 8;
00547 }
00548 
00549 int DiracEncoder::GetEncodedData (dirac_encoder_t *encoder)
00550 {
00551     int size = 0;
00552     dirac_enc_data_t *encdata = &encoder->enc_buf;
00553 
00554     size = m_comp_stream.str().size();
00555     if (size > 0)
00556     {
00557         if (encdata->size < size )
00558         {
00559             return -1;
00560         }
00561         memmove (encdata->buffer, m_comp_stream.str().c_str(),  size);
00562         encoder->enc_fparams.fnum = m_enc_frame->GetFparams().FrameNum();
00563         encoder->enc_fparams.ftype = m_enc_frame->GetFparams().FSort();
00564 
00565         // Get frame statistics
00566         GetFrameStats (encoder);
00567         encdata->size = size;
00568 
00569         GetInstrumentationData(encoder);
00570         encoder->encoded_frame_avail = 1;
00571 
00572         m_comp_stream.str("");
00573     }
00574     else
00575     {
00576         encdata->size = 0;
00577     }
00578     return size;
00579 }
00580 
00581 int DiracEncoder::GetDecodedData (dirac_encoder_t *encoder)
00582 {
00583     dirac_frameparams_t *fp = &encoder->dec_fparams;
00584 
00585     int ret_stat = (m_decfnum != -1);
00586     if (m_return_decoded_frames && m_decfnum != -1)
00587     {
00588             fp->ftype = m_decfsort;
00589             fp->fnum = m_decfnum;
00590             encoder->decoded_frame_avail = 1;
00591             m_decfnum = -1;
00592     }
00593     return ret_stat;
00594 }
00595 
00596 void DiracEncoder::GetSequenceStats(dirac_encoder_t *encoder)
00597 {
00598     dirac_enc_seqstats_t *sstats = &encoder->enc_seqstats;
00599     dirac_seqparams_t *sparams = &encoder->enc_ctx.seq_params;
00600 
00601     sstats->seq_bits = m_encparams.BitsOut().SequenceBytes() * 8;
00602     sstats->seq_hdr_bits = m_encparams.BitsOut().SequenceHeadBytes() * 8;
00603 
00604     sstats->mv_bits = m_encparams.BitsOut().MVBytes() * 8;
00605     sstats->ycomp_bits = m_encparams.BitsOut().ComponentBytes( Y_COMP ) * 8;
00606     sstats->ucomp_bits = m_encparams.BitsOut().ComponentBytes( U_COMP ) * 8;
00607     sstats->vcomp_bits = m_encparams.BitsOut().ComponentBytes( V_COMP ) * 8;
00608 
00609     sstats->bit_rate = (sstats->seq_bits * sparams->frame_rate.numerator)/
00610                         (sparams->frame_rate.denominator * m_num_coded_frames);
00611 }
00612 
00613 int DiracEncoder::GetSequenceEnd (dirac_encoder_t *encoder)
00614 {
00615     dirac_enc_data_t *encdata = &encoder->enc_buf;
00616     m_comp_stream.str("");
00617     m_comp->EndSequence();
00618     int size = m_comp_stream.str().size();
00619     if (size > 0)
00620     {
00621         if (encdata->size < size )
00622         {
00623             return -1;
00624         }
00625         memmove (encdata->buffer, m_comp_stream.str().c_str(),  size);
00626         GetSequenceStats(encoder);
00627         m_comp_stream.str("");
00628         encdata->size = size;
00629     }
00630     else
00631     {
00632         encdata->size = 0;
00633     }
00634     return size;
00635 }
00636 
00637 static bool InitialiseEncoder (const dirac_encoder_context_t *enc_ctx, bool verbose, dirac_encoder_t *encoder)
00638 {
00639     TEST (enc_ctx != NULL);
00640     TEST (encoder != NULL);
00641     
00642     if (enc_ctx->seq_params.width == 0 || enc_ctx->seq_params.height == 0)
00643         return false;
00644 
00645     if (enc_ctx->seq_params.chroma < Yonly || 
00646             enc_ctx->seq_params.chroma > formatNK)
00647         return false;
00648 
00649     if (!enc_ctx->seq_params.frame_rate.numerator || 
00650             !enc_ctx->seq_params.frame_rate.denominator)
00651         return false;
00652 
00653     memmove (&encoder->enc_ctx, enc_ctx, sizeof(dirac_encoder_context_t));
00654 
00655     encoder->dec_buf.id = 0;
00656 
00657     switch ( enc_ctx->seq_params.chroma )
00658     {
00659     case Yonly:
00660          encoder->enc_ctx.seq_params.chroma_width = 0;
00661          encoder->enc_ctx.seq_params.chroma_height = 0;
00662         break;
00663     case format411:
00664          encoder->enc_ctx.seq_params.chroma_width = enc_ctx->seq_params.width/4;
00665          encoder->enc_ctx.seq_params.chroma_height = enc_ctx->seq_params.height;
00666          break;
00667     case format420:
00668          encoder->enc_ctx.seq_params.chroma_width = enc_ctx->seq_params.width/2;
00669          encoder->enc_ctx.seq_params.chroma_height = enc_ctx->seq_params.height/2;
00670          break;
00671     case format422:
00672          encoder->enc_ctx.seq_params.chroma_width = enc_ctx->seq_params.width/2;
00673          encoder->enc_ctx.seq_params.chroma_height = enc_ctx->seq_params.height;
00674          break;
00675     case format444:
00676     default:
00677          encoder->enc_ctx.seq_params.chroma_width = enc_ctx->seq_params.width;
00678          encoder->enc_ctx.seq_params.chroma_height = enc_ctx->seq_params.height;
00679          break;
00680     }
00681 
00682     try
00683     {
00684         DiracEncoder *comp = new DiracEncoder (&encoder->enc_ctx, verbose);
00685     
00686         int bufsize = (encoder->enc_ctx.seq_params.width * encoder->enc_ctx.seq_params.height)+ 2*(encoder->enc_ctx.seq_params.chroma_width*encoder->enc_ctx.seq_params.chroma_height);
00687 
00688         encoder->dec_buf.buf[0] = new unsigned char [bufsize];
00689         encoder->dec_buf.buf[1] = encoder->dec_buf.buf[0] + 
00690                 (encoder->enc_ctx.seq_params.width * encoder->enc_ctx.seq_params.height);
00691         encoder->dec_buf.buf[2] = encoder->dec_buf.buf[1] + 
00692                 (encoder->enc_ctx.seq_params.chroma_width*encoder->enc_ctx.seq_params.chroma_height);
00693     
00694         encoder->compressor = comp;
00695         if (encoder->enc_ctx.decode_flag)
00696         {
00697             comp->SetDecodeBuffer (encoder->dec_buf.buf[0], bufsize);
00698         }
00699     }
00700     catch (...)
00701     {
00702         return false;
00703     }
00704     return true;
00705 }
00706 
00707 static void SetSequenceParameters (dirac_encoder_context_t *enc_ctx, dirac_encoder_presets_t preset)
00708 {
00709     TEST (enc_ctx != NULL);
00710     dirac_seqparams_t &sparams = enc_ctx->seq_params;
00711 
00712     sparams.chroma = format420;
00713     switch (preset)
00714     {
00715     case SD576:
00716         sparams.width = 720;
00717         sparams.height = 576;
00718         sparams.frame_rate.numerator = 25;
00719         sparams.frame_rate.denominator = 1;
00720         sparams.interlace = 1;
00721         sparams.topfieldfirst = 1;
00722         break;
00723     case HD720:
00724         sparams.width = 1280;
00725         sparams.height = 720;
00726         sparams.frame_rate.numerator = 50;
00727         sparams.frame_rate.denominator = 1;
00728         sparams.interlace = 0;
00729         sparams.topfieldfirst = 0;
00730         break;
00731     case HD1080:
00732         sparams.width = 1920;
00733         sparams.height = 1080;
00734         sparams.frame_rate.numerator = 25;
00735         sparams.frame_rate.denominator = 1;
00736         sparams.interlace = 1;
00737         sparams.topfieldfirst = 1;
00738         break;
00739     case CIF:
00740     default:
00741         sparams.width = 352;
00742         sparams.height = 288;
00743         sparams.frame_rate.numerator = 13;
00744         sparams.frame_rate.denominator = 1;
00745         sparams.interlace = 0;
00746         sparams.topfieldfirst = 0;
00747         break;
00748     }
00749 }
00750 
00751 static void SetEncoderParameters (dirac_encoder_context_t *enc_ctx, dirac_encoder_presets_t preset)
00752 {
00753     TEST (enc_ctx != NULL);
00754 
00755     dirac_encparams_t &encparams = enc_ctx->enc_params;
00756 
00757     encparams.qf = 7.0f;
00758 
00759     switch (preset)
00760     {
00761     case SD576:
00762         encparams.L1_sep = 3;
00763         encparams.num_L1 = 3;
00764         encparams.cpd = 32.0f;
00765         encparams.xblen = 12;
00766         encparams.yblen = 12;
00767         encparams.xbsep = 8;
00768         encparams.ybsep = 8;
00769         break;
00770     case HD720:
00771         encparams.L1_sep = 3;
00772         encparams.num_L1 = 7;
00773         encparams.cpd = 20.0f;
00774         encparams.xblen = 16;
00775         encparams.yblen = 16;
00776         encparams.xbsep = 10;
00777         encparams.ybsep = 12;
00778         break;
00779     case HD1080:
00780         encparams.L1_sep = 3;
00781         encparams.num_L1 = 3;
00782         encparams.cpd = 32.0f;
00783         encparams.xblen = 20;
00784         encparams.yblen = 20;
00785         encparams.xbsep = 16;
00786         encparams.ybsep = 16;
00787         break;
00788     case CIF:
00789     default:
00790         encparams.L1_sep = 3;
00791         encparams.num_L1 = 11;
00792         encparams.cpd = 20.0f;
00793         encparams.xblen = 12;
00794         encparams.yblen = 12;
00795         encparams.xbsep = 8;
00796         encparams.ybsep = 8;
00797         break;
00798     }
00799 }
00800 #ifdef __cplusplus
00801 extern "C" {
00802 #endif
00803 
00804 extern DllExport void dirac_encoder_context_init ( dirac_encoder_context_t *enc_ctx, dirac_encoder_presets_t preset)
00805 {
00806     TEST (enc_ctx != NULL);
00807     memset (enc_ctx, 0, sizeof(dirac_encoder_context_t));
00808     SetSequenceParameters (enc_ctx, preset);
00809     SetEncoderParameters (enc_ctx, preset);
00810 }
00811 
00812 extern DllExport dirac_encoder_t *dirac_encoder_init (const dirac_encoder_context_t *enc_ctx, int verbose)
00813 {
00814     /* Allocate for encoder */
00815     dirac_encoder_t *encoder = new dirac_encoder_t;
00816 
00817     memset (encoder, 0, sizeof(dirac_encoder_t));
00818 
00819     /* initialse the encoder context */
00820     if (!InitialiseEncoder(enc_ctx, verbose>0, encoder))
00821     {
00822         delete encoder;
00823         return NULL;
00824     }
00825 
00826     encoder->encoded_frame_avail = encoder->decoded_frame_avail = 0;
00827     encoder->instr_data_avail = 0;
00828 
00829 
00830     return encoder;
00831 }
00832 
00833 extern DllExport int dirac_encoder_load (dirac_encoder_t *encoder, unsigned char *uncdata, int uncdata_size)
00834 {
00835     TEST (encoder != NULL);
00836     TEST (encoder->compressor != NULL);
00837     DiracEncoder *compressor = (DiracEncoder *)encoder->compressor;
00838     int ret_stat = 0;
00839     try
00840     {
00841         if ( compressor->LoadNextFrame (uncdata, uncdata_size))
00842         {
00843             ret_stat = uncdata_size;
00844         }
00845     }
00846     catch (...)
00847     {
00848         if (compressor->GetEncParams().Verbose())
00849             std::cerr << "dirac_encoder_load failed" << std::endl;
00850         ret_stat = -1;
00851     }
00852     return ret_stat;
00853 }
00854 
00855 extern DllExport dirac_encoder_state_t 
00856       dirac_encoder_output (dirac_encoder_t *encoder)
00857 {
00858     TEST (encoder != NULL);
00859     TEST (encoder->compressor != NULL);
00860     TEST (encoder->enc_buf.size != 0);
00861     TEST (encoder->enc_buf.buffer != NULL);
00862     DiracEncoder *compressor = (DiracEncoder *)encoder->compressor;
00863     dirac_encoder_state_t ret_stat = ENC_STATE_BUFFER;
00864 
00865     encoder->encoded_frame_avail = 0;
00866     encoder->decoded_frame_avail = 0;
00867     encoder->instr_data_avail = 0;
00868 
00869     try
00870     {
00871         compressor->CompressNextFrame();
00872         if (compressor->GetEncodedData (encoder) < 0)
00873             ret_stat = ENC_STATE_INVALID;
00874         else
00875         {
00876             if (encoder->enc_buf.size > 0)
00877             {
00878                 ret_stat = ENC_STATE_AVAIL;
00879             }
00880     
00881             if (encoder->enc_ctx.decode_flag)
00882                 compressor->GetDecodedData(encoder);
00883         }
00884     }
00885     catch (...)
00886     {
00887         if (compressor->GetEncParams().Verbose())
00888             std::cerr << "GetEncodedData failed..." << std::endl;
00889 
00890         ret_stat = ENC_STATE_INVALID;
00891     }
00892     return ret_stat;
00893 }
00894 
00895 extern DllExport int dirac_encoder_end_sequence (dirac_encoder_t *encoder)
00896 {
00897     TEST (encoder != NULL);
00898     TEST (encoder->compressor != NULL);
00899     DiracEncoder *compressor = (DiracEncoder *)encoder->compressor;
00900     int ret_stat;
00901 
00902     encoder->encoded_frame_avail = 0;
00903     encoder->decoded_frame_avail = 0;
00904     encoder->instr_data_avail = 0;
00905 
00906     try
00907     {
00908         ret_stat = compressor->GetSequenceEnd (encoder);
00909         encoder->end_of_sequence = 1;
00910 
00911         if (compressor->GetDecodedData(encoder))
00912         {
00913             encoder->decoded_frame_avail = 1;
00914         }
00915     }
00916     catch (...)
00917     {
00918         if (compressor->GetEncParams().Verbose())
00919             std::cerr << "GetSequenceEnd failed..." << std::endl;
00920         ret_stat = -1;
00921     }
00922     return ret_stat;
00923 }
00924 
00925 extern DllExport void dirac_encoder_close (dirac_encoder_t *encoder)
00926 {
00927     TEST (encoder != NULL);
00928     TEST (encoder->compressor != NULL);
00929     
00930     delete (DiracEncoder *)(encoder->compressor);
00931 
00932     if (encoder->enc_ctx.instr_flag)
00933     {
00934         dealloc_instr_data(&encoder->instr);
00935     }
00936 
00937     if (encoder->enc_ctx.decode_flag)
00938     {
00939         delete [] encoder->dec_buf.buf[0];
00940     }
00941     delete encoder;
00942 }
00943 
00944 
00945 #ifdef __cplusplus
00946 }
00947 #endif

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