- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# 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