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

多媒体编程

开发平台:

Visual C++

  1. /* ***** BEGIN LICENSE BLOCK *****
  2. *
  3. * $Id: dirac_encoder.cpp,v 1.1 2005/01/30 05:11:41 gabest Exp $ $Name:  $
  4. *
  5. * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  6. *
  7. * The contents of this file are subject to the Mozilla Public License
  8. * Version 1.1 (the "License"); you may not use this file except in compliance
  9. * with the License. You may obtain a copy of the License at
  10. * http://www.mozilla.org/MPL/
  11. *
  12. * Software distributed under the License is distributed on an "AS IS" basis,
  13. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
  14. * the specific language governing rights and limitations under the License.
  15. *
  16. * The Original Code is BBC Research and Development code.
  17. *
  18. * The Initial Developer of the Original Code is the British Broadcasting
  19. * Corporation.
  20. * Portions created by the Initial Developer are Copyright (C) 2004.
  21. * All Rights Reserved.
  22. *
  23. * Contributor(s): Anuradha Suraparaju (Original Author)
  24. *
  25. * Alternatively, the contents of this file may be used under the terms of
  26. * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
  27. * Public License Version 2.1 (the "LGPL"), in which case the provisions of
  28. * the GPL or the LGPL are applicable instead of those above. If you wish to
  29. * allow use of your version of this file only under the terms of the either
  30. * the GPL or LGPL and not to allow others to use your version of this file
  31. * under the MPL, indicate your decision by deleting the provisions above
  32. * and replace them with the notice and other provisions required by the GPL
  33. * or LGPL. If you do not delete the provisions above, a recipient may use
  34. * your version of this file under the terms of any one of the MPL, the GPL
  35. * or the LGPL.
  36. * ***** END LICENSE BLOCK ***** */
  37. #include <cstring>
  38. #include <sstream>
  39. #include <fstream>
  40. #include <queue>
  41. #include <libdirac_common/dirac_assertions.h>
  42. #include <libdirac_common/common.h>
  43. #include <libdirac_common/frame.h>
  44. #include <libdirac_common/pic_io.h>
  45. #include <libdirac_encoder/dirac_encoder.h>
  46. #include <libdirac_encoder/seq_compress.h>
  47. using namespace dirac;
  48. template <class T >
  49. void copy_2dArray (const TwoDArray<T> & in, T *out)
  50. {
  51.     for (int j=0 ; j<in.LengthY() ; ++j)
  52.     {
  53.         for (int i=0 ; i<in.LengthX() ; ++i)
  54.         {
  55.             // out[j*in.LengthX() + i] =  in[j][i];
  56.             *out++ =  in[j][i];
  57.         }// i
  58.     }// j
  59. }
  60. void copy_2dArray (const TwoDArray<PredMode> & in, int *out)
  61. {
  62.     for (int j=0 ; j<in.LengthY() ; ++j)
  63.     {
  64.         for (int i=0 ; i<in.LengthX() ; ++i)
  65.         {
  66.             // out[j*in.LengthX() + i] =  in[j][i];
  67.             *out++ =  in[j][i];
  68.         }// i
  69.     }// j
  70. }
  71. void copy_2dArray (const TwoDArray<bool> & in, int *out)
  72. {
  73.     for (int j=0 ; j<in.LengthY() ; ++j)
  74.     {
  75.         for (int i=0 ; i<in.LengthX() ; ++i)
  76.         {
  77.             // out[j*in.LengthX() + i] =  in[j][i];
  78.             *out++ =  in[j][i];
  79.         }// i
  80.     }// j
  81. }
  82. void copy_mv ( const MvArray& mv, dirac_mv_t *dmv)
  83. {
  84.     for (int j=0 ; j<mv.LengthY() ; ++j)
  85.     {
  86.         for (int i=0 ; i<mv.LengthX() ; ++i)
  87.         {
  88.             //dmv[j*mv.LengthX() + i].x = mv[j][i].x;
  89.             //dmv[j*mv.LengthX() + i].y = mv[j][i].y;
  90.             (*dmv).x = mv[j][i].x;
  91.             (*dmv).y = mv[j][i].y;
  92.             dmv++;
  93.         }// i
  94.     }// j
  95. }
  96. void copy_mv_cost (const TwoDArray<MvCostData> &pc, dirac_mv_cost_t *dpc)
  97. {
  98.     for (int j=0 ; j<pc.LengthY() ; ++j)
  99.     {
  100.         for (int i=0 ; i<pc.LengthX() ; ++i)
  101.         {
  102.             //dpc[j*pc.LengthX() + i].SAD = pc[j][i].SAD;
  103.             //dpc[j*pc.LengthX() + i].mvcost = pc[j][i].mvcost;
  104.             (*dpc).SAD = pc[j][i].SAD;
  105.             (*dpc).mvcost = pc[j][i].mvcost;
  106.             dpc++;
  107.         }// i
  108.     }// j
  109. }
  110. /*
  111.     Function that allocates the locally managed instrumentation data
  112. */
  113. void alloc_instr_data(dirac_instr_t *instr)
  114. {
  115.     instr->mb_split_mode = new int [instr->mb_ylen*instr->mb_xlen];
  116.     memset (instr->mb_split_mode, 0, sizeof(int)*instr->mb_ylen*instr->mb_xlen);
  117.     instr->mb_common_mode = new int [instr->mb_ylen*instr->mb_xlen];
  118.     memset (instr->mb_common_mode, 0, 
  119.                     sizeof(int)*instr->mb_ylen*instr->mb_xlen);
  120.     instr->mb_costs = new float [instr->mb_ylen*instr->mb_xlen];
  121.     memset (instr->mb_costs, 0, sizeof(float)*instr->mb_ylen*instr->mb_xlen);
  122.     instr->pred_mode = new int [instr->mv_ylen * instr->mv_xlen];
  123.     memset (instr->pred_mode, 0, sizeof(int)*instr->mv_ylen*instr->mv_xlen);
  124.         
  125.     instr->intra_costs = new float [instr->mv_ylen * instr->mv_xlen];
  126.     memset (instr->intra_costs, 0, sizeof(float)*instr->mv_ylen*instr->mv_xlen);
  127.         
  128.     instr->bipred_costs = new dirac_mv_cost_t [instr->mv_ylen * instr->mv_xlen];
  129.     memset (instr->bipred_costs, 0, sizeof(dirac_mv_cost_t)*instr->mv_ylen*instr->mv_xlen);
  130.         
  131.     instr->dc_ycomp = new short [instr->mv_ylen * instr->mv_xlen];
  132.     memset (instr->dc_ycomp, 0, sizeof(short)*instr->mv_ylen*instr->mv_xlen);
  133.         
  134.     instr->dc_ucomp = new short [instr->mv_ylen * instr->mv_xlen];
  135.     memset (instr->dc_ucomp, 0, sizeof(short)*instr->mv_ylen*instr->mv_xlen);
  136.         
  137.     instr->dc_vcomp = new short [instr->mv_ylen * instr->mv_xlen];
  138.     memset (instr->dc_vcomp, 0, sizeof(short)*instr->mv_ylen*instr->mv_xlen);
  139.         
  140.     for (int i = 0; i < 2; i++)
  141.     {
  142.         instr->mv[i] = new dirac_mv_t[instr->mv_ylen * instr->mv_xlen];
  143.         memset (instr->mv[i], 0, 
  144.             sizeof(dirac_mv_t)*instr->mv_ylen*instr->mv_xlen);
  145.     }
  146.         
  147.     for (int i = 0; i < 2; i++)
  148.     {
  149.         instr->pred_costs[i] = new dirac_mv_cost_t[instr->mv_ylen * instr->mv_xlen];
  150.         memset (instr->pred_costs[i], 0, 
  151.             sizeof(dirac_mv_cost_t)*instr->mv_ylen*instr->mv_xlen);
  152.     }
  153. }
  154. /*
  155.     Function that frees the locally managed instrumentation data
  156. */
  157. void dealloc_instr_data(dirac_instr_t *instr)
  158. {
  159.     if (instr->mb_split_mode)
  160.         delete [] instr->mb_split_mode;
  161.     if (instr->mb_common_mode)
  162.         delete [] instr->mb_common_mode;
  163.     if (instr->mb_costs)
  164.         delete [] instr->mb_costs;
  165.     if (instr->pred_mode)
  166.         delete [] instr->pred_mode;
  167.     if (instr->intra_costs)
  168.         delete [] instr->intra_costs;
  169.     if (instr->bipred_costs)
  170.         delete [] instr->bipred_costs;
  171.     if (instr->dc_ycomp)
  172.         delete [] instr->dc_ycomp;
  173.     if (instr->dc_ucomp)
  174.         delete [] instr->dc_ucomp;
  175.     if (instr->dc_vcomp)
  176.         delete [] instr->dc_vcomp;
  177.     for (int i = 0; i < 2; i++)
  178.     {
  179.         if (instr->mv[i])
  180.             delete [] instr->mv[i];
  181.     }
  182.     for (int i = 0; i < 2; i++)
  183.     {
  184.         if (instr->pred_costs[i])
  185.             delete [] instr->pred_costs[i];
  186.     }
  187. }
  188. /*
  189.     Wrapper class around the SequenceCompressor Class. This class is used 
  190.     by the "C" encoder interface
  191. */
  192. class DiracEncoder
  193. {
  194. public:
  195.     // constructor
  196.     DiracEncoder(const dirac_encoder_context_t *enc_ctx, bool verbose);
  197.     // destructor
  198.     ~DiracEncoder();
  199.     // Load the next frame of uncompressed data into the SequenceCompressor
  200.     bool LoadNextFrame(unsigned char *data, int size);
  201.     // Compress the next frame of data
  202.     int CompressNextFrame();
  203.     // Set the encode frame in encoder to the encoded frame data
  204.     int GetEncodedData(dirac_encoder_t *encoder);
  205.     
  206.     // Set the locally decoded frame data in encoder
  207.     int GetDecodedData (dirac_encoder_t *encoder);
  208.     // Set the instrumentation data in encoder
  209.     void GetInstrumentationData (dirac_encoder_t *encoder);
  210.     // Set the end of sequence infomration in encoder
  211.     int GetSequenceEnd(dirac_encoder_t *encoder);
  212.     // Set the buffer to hold the locally decoded frame
  213.     void SetDecodeBuffer (unsigned char *buffer, int buffer_size);
  214.     // Return the sequence parameters
  215.     const SeqParams& GetSeqParams() const { return m_sparams; }
  216.     // Return the encoder parameters
  217.     const EncoderParams& GetEncParams() const { return m_encparams; }
  218. private:
  219.     // Set the sequence parameters
  220.     void SetSequenceParams (const dirac_encoder_context_t *enc_ctx);
  221.     
  222.     // Set the encoder parameters
  223.     void SetEncoderParams (const dirac_encoder_context_t *enc_ctx);
  224.     // Get the frame statistics
  225.     void GetFrameStats(dirac_encoder_t *encoder);
  226.     // Get the seuqence statistics
  227.     void GetSequenceStats(dirac_encoder_t *encoder);
  228. private:
  229.     // sequence compressor
  230.     SequenceCompressor *m_comp;
  231.     // sequence parameters
  232.     SeqParams m_sparams;
  233.     // encoder parameters
  234.     EncoderParams m_encparams;
  235.     // stream to hold the compressed frame
  236.     std::ostringstream m_comp_stream;
  237.     // locally encoded frame in coded order
  238.     const Frame *m_enc_frame;
  239.     // locally encoded frame ME data
  240.     const MEData *m_enc_medata;
  241.     // locally decoded frame number in display order
  242.     int m_decfnum;
  243.     //locally decoded frame type
  244.     FrameSort m_decfsort;
  245.     // locally decoded frame number in display order
  246.     int m_show_fnum;
  247.     // total number of frame loaded so far
  248.     int m_num_loaded_frames;
  249.     // total number of frames encoded so far
  250.     int m_num_coded_frames;
  251.     // verbose flag
  252.     bool m_verbose;
  253.     // input stream for uncompressed input frame
  254.     MemoryStreamInput m_inp_ptr;
  255.     // output stream for locally decoded frame
  256.     MemoryStreamOutput m_out_ptr;
  257.     // buffer to hold locally decoded frame. Set by SetDecodeBuffer
  258.     unsigned char *m_dec_buf;
  259.     // size of buffer to hold locally decoded data. Set by SetDecodeBuffer
  260.     int m_dec_bufsize;
  261.     // Flag that determines if locally decoded frames are to be returned. Set
  262.     // in Constructor
  263.     bool m_return_decoded_frames;
  264.     // Flag that determines if instrumentation data is to be returned. Set
  265.     // in Constructor
  266.     bool m_return_instr_data;
  267. };
  268. /*
  269.     Instrumentation callback. This function is passed as a parameter to the
  270.     SequenceCompressor constructor. It is called by the 
  271.     FrameCompressor::Compress function once the frame is successfully compressed
  272. */
  273. void DiracEncoder::GetInstrumentationData (dirac_encoder_t *encoder)
  274. {
  275.     dirac_ASSERT (encoder != NULL);
  276.     dirac_instr_t *instr = &encoder->instr;
  277.     dirac_instr_t old_instr = *instr;
  278.     if (!m_return_instr_data)
  279.         return;
  280.     const FrameParams& fparams = m_enc_frame->GetFparams();
  281.     const FrameSort fsort = fparams.FSort();
  282.     instr->fnum = fparams.FrameNum();
  283.     instr->ftype = fsort;
  284.     instr->num_refs = 0;
  285.     encoder->instr_data_avail = 1;
  286.     if (fsort == I_frame)
  287.     {
  288.         // no MV data for Intra coded data
  289.         return;
  290.     }
  291.     TESTM (m_enc_medata != NULL, "ME data available");
  292.     // Reference info
  293.     instr->num_refs = fparams.Refs().size();
  294.     dirac_ASSERTM (instr->num_refs <= 2, "Max # reference frames is 2");
  295.     for (int i=0; i<instr->num_refs; ++i)
  296.         instr->refs[i] = fparams.Refs()[i];
  297.     // Block separation params
  298.     instr->ybsep = m_encparams.LumaBParams(2).Ybsep();
  299.     instr->xbsep = m_encparams.LumaBParams(2).Xbsep();
  300.     // Num macroblocks
  301.     instr->mb_ylen = m_enc_medata->MBSplit().LengthY();
  302.     instr->mb_xlen = m_enc_medata->MBSplit().LengthX();
  303.     // Motion vector array dimensions
  304.     instr->mv_ylen = m_enc_medata->Vectors(1).LengthY();
  305.     instr->mv_xlen = m_enc_medata->Vectors(1).LengthX();
  306.     if (old_instr.mb_ylen != instr->mb_ylen || 
  307.         old_instr.mb_xlen != instr->mb_xlen ||
  308.         old_instr.mv_ylen != instr->mv_ylen || 
  309.         old_instr.mv_xlen != instr->mv_xlen)
  310.     {
  311.         dealloc_instr_data(instr);
  312.         alloc_instr_data(instr);
  313.     }
  314.     copy_2dArray (m_enc_medata->MBSplit(), instr->mb_split_mode);
  315.     copy_2dArray (m_enc_medata->MBCommonMode(), instr->mb_common_mode);
  316.     copy_2dArray (m_enc_medata->MBCosts(), instr->mb_costs);
  317.     copy_2dArray (m_enc_medata->Mode(), instr->pred_mode);
  318.     copy_2dArray (m_enc_medata->IntraCosts(), instr->intra_costs);
  319.     // FIXME: Always allocating for bipred_costs even though no data available
  320.     //  Since medata is always created assuming two references
  321.     // if (instr->num_refs > 1)
  322.     {
  323.         copy_mv_cost (m_enc_medata->BiPredCosts(), instr->bipred_costs);
  324.     }
  325.     copy_2dArray (m_enc_medata->DC( Y_COMP ), instr->dc_ycomp);
  326.     if (m_enc_medata->DC().Length() == 3 && 
  327.         encoder->enc_ctx.seq_params.chroma != Yonly)
  328.     {
  329.         copy_2dArray (m_enc_medata->DC( U_COMP ), instr->dc_ucomp);
  330.         copy_2dArray (m_enc_medata->DC( V_COMP ), instr->dc_vcomp);
  331.     }
  332.     // FIXME: Always allocating for bipred_costs even though no data available
  333.     //  Since medata is always created assuming two references
  334.     // for (int i=1; i<=instr->num_refs; ++i)
  335.     for (int i=1; i<=2; ++i)
  336.     {
  337.         copy_mv (m_enc_medata->Vectors(i), instr->mv[i-1]);
  338.         copy_mv_cost (m_enc_medata->PredCosts(i), instr->pred_costs[i-1]);
  339.     }
  340. }
  341. DiracEncoder::DiracEncoder(const dirac_encoder_context_t *enc_ctx, 
  342.                            bool verbose) :
  343.     m_show_fnum(-1),
  344.     m_num_loaded_frames(0),
  345.     m_num_coded_frames(0),
  346.     m_verbose(verbose),
  347.     m_dec_buf(0),
  348.     m_dec_bufsize(0),
  349.     m_return_decoded_frames(enc_ctx->decode_flag > 0),
  350.     m_return_instr_data(enc_ctx->instr_flag > 0)
  351. {
  352.     // Setup sequence parameters
  353.     SetSequenceParams (enc_ctx);
  354.     // Setup encoder parameters
  355.     m_encparams.SetVerbose( verbose );
  356.     SetEncoderParams (enc_ctx);
  357.     // Set up the input data stream (uncompressed data)
  358.     m_inp_ptr.SetSequenceParams(m_sparams);
  359.     // Set up the output data stream (locally decoded frame)
  360.     m_out_ptr.SetSequenceParams(m_sparams);
  361.     
  362.     // initialise the sequence compressor
  363.     m_comp = new SequenceCompressor (&m_inp_ptr, &m_comp_stream, m_encparams);
  364. }
  365. void DiracEncoder::SetDecodeBuffer (unsigned char *buffer, int buffer_size)
  366. {
  367.     m_dec_buf = buffer;
  368.     m_dec_bufsize = buffer_size;
  369.     m_return_decoded_frames = true;
  370. }
  371. DiracEncoder::~DiracEncoder()
  372. {
  373.     delete m_comp;
  374. }
  375. void DiracEncoder::SetSequenceParams (const dirac_encoder_context_t *enc_ctx)
  376. {
  377.     m_sparams.SetCFormat( enc_ctx->seq_params.chroma );
  378.     m_sparams.SetXl( enc_ctx->seq_params.width );
  379.     m_sparams.SetYl( enc_ctx->seq_params.height );
  380.     m_sparams.SetInterlace( enc_ctx->seq_params.interlace );
  381.     m_sparams.SetTopFieldFirst( enc_ctx->seq_params.topfieldfirst );
  382.     m_sparams.SetFrameRate( enc_ctx->seq_params.frame_rate.numerator /
  383.                             enc_ctx->seq_params.frame_rate.denominator );
  384. }
  385. void DiracEncoder::SetEncoderParams (const dirac_encoder_context_t *enc_ctx)
  386. {
  387.     TEST (enc_ctx != NULL);
  388.     OLBParams bparams(12, 12, 8, 8);
  389.     m_encparams.SetQf(enc_ctx->enc_params.qf);
  390.     m_encparams.SetL1Sep(enc_ctx->enc_params.L1_sep);
  391.     m_encparams.SetNumL1(enc_ctx->enc_params.num_L1);
  392.     m_encparams.SetCPD(enc_ctx->enc_params.cpd);
  393.     m_encparams.SetUFactor(3.0f);
  394.     m_encparams.SetVFactor(1.75f);
  395.     bparams.SetYblen( enc_ctx->enc_params.yblen );
  396.     bparams.SetXbsep( enc_ctx->enc_params.xblen );
  397.     bparams.SetYbsep( enc_ctx->enc_params.ybsep );
  398.     bparams.SetXbsep( enc_ctx->enc_params.xbsep );
  399.     // Now rationalise the GOP options
  400.     // this stuff should really be done in a constructor!
  401.     if (m_encparams.NumL1()<0)
  402.     {
  403.         //don't have a proper GOP
  404.         m_encparams.SetL1Sep( std::max(1 , m_encparams.L1Sep()) );
  405.     }
  406.     else if (m_encparams.NumL1() == 0)
  407.     {
  408.         //have I-frame only coding
  409.         m_encparams.SetL1Sep(0);
  410.     }
  411.     m_encparams.SetOrigXl( enc_ctx->seq_params.width );
  412.     m_encparams.SetOrigYl( enc_ctx->seq_params.height );
  413.     m_encparams.SetBlockSizes( bparams , enc_ctx->seq_params.chroma );
  414. }
  415. bool DiracEncoder::LoadNextFrame (unsigned char *data, int size)
  416. {
  417.     TESTM (m_comp->Finished() != true, "Did not reach end of sequence");
  418.     m_inp_ptr.SetMembufReference(data, size);
  419.     if (m_comp->LoadNextFrame())
  420.     {
  421.         m_num_loaded_frames++;
  422.         return true;
  423.     }
  424.     return false;
  425. }
  426. int DiracEncoder::CompressNextFrame ()
  427. {
  428.     TESTM (m_comp->Finished() != true, "Did not reach end of sequence");
  429.     if (!m_num_loaded_frames)
  430.         return 0;
  431.     Frame &myframe = m_comp->CompressNextFrame();
  432.     m_enc_frame = m_comp->GetFrameEncoded();
  433.     m_enc_medata = m_comp->GetMEData();
  434.     m_decfnum = -1;
  435.     if (m_return_decoded_frames && 
  436.             myframe.GetFparams().FrameNum() != m_show_fnum)
  437.     {
  438.         int ret_val;
  439.         m_show_fnum = myframe.GetFparams().FrameNum();
  440.         TEST (! (m_return_decoded_frames && !m_dec_buf) );
  441.         if (m_return_decoded_frames && m_dec_buf)
  442.         {
  443.             // write locally decoded frame to decode buffer
  444.             m_out_ptr.SetMembufReference(m_dec_buf, m_dec_bufsize);
  445.             ret_val = m_out_ptr.WriteNextFrame(myframe);
  446.             if (ret_val)
  447.             {
  448.                 m_decfnum = m_show_fnum;
  449.                 m_decfsort = myframe.GetFparams().FSort();
  450.             }
  451.         }
  452.     }
  453.     int size = m_comp_stream.str().size();
  454.     if (size > 0)
  455.     {
  456.         m_num_coded_frames++;
  457.         TESTM (m_enc_frame != 0, "Encoder frame available");
  458.     }
  459.     return size;
  460. }
  461. void DiracEncoder::GetFrameStats(dirac_encoder_t *encoder)
  462. {
  463.     const FrameOutputManager& foutput = m_encparams.BitsOut().FrameOutput();
  464.     dirac_enc_framestats_t *fstats = &encoder->enc_fstats;
  465.     fstats->mv_bits = foutput.MVBytes() * 8;
  466.     fstats->mv_hdr_bits = foutput.MVBytes() * 8;
  467.     fstats->ycomp_bits = foutput.ComponentBytes( Y_COMP ) * 8;
  468.     fstats->ycomp_hdr_bits = foutput.ComponentHeadBytes( Y_COMP ) * 8;
  469.     fstats->ucomp_bits = foutput.ComponentBytes( U_COMP ) * 8;
  470.     fstats->ucomp_hdr_bits = foutput.ComponentHeadBytes( U_COMP ) * 8;
  471.     fstats->vcomp_bits = foutput.ComponentBytes( V_COMP ) * 8;
  472.     fstats->vcomp_hdr_bits = foutput.ComponentHeadBytes( V_COMP ) * 8;
  473.     fstats->frame_bits = foutput.FrameBytes() * 8;
  474.     fstats->frame_hdr_bits = foutput.FrameHeadBytes() * 8;
  475. }
  476. int DiracEncoder::GetEncodedData (dirac_encoder_t *encoder)
  477. {
  478.     int size = 0;
  479.     dirac_enc_data_t *encdata = &encoder->enc_buf;
  480.     size = m_comp_stream.str().size();
  481.     if (size > 0)
  482.     {
  483.         if (encdata->size < size )
  484.         {
  485.             return -1;
  486.         }
  487.         memmove (encdata->buffer, m_comp_stream.str().c_str(),  size);
  488.         encoder->enc_fparams.fnum = m_enc_frame->GetFparams().FrameNum();
  489.         encoder->enc_fparams.ftype = m_enc_frame->GetFparams().FSort();
  490.         // Get frame statistics
  491.         GetFrameStats (encoder);
  492.         encdata->size = size;
  493.         GetInstrumentationData(encoder);
  494.         encoder->encoded_frame_avail = 1;
  495.         m_comp_stream.str("");
  496.     }
  497.     else
  498.     {
  499.         encdata->size = 0;
  500.     }
  501.     return size;
  502. }
  503. int DiracEncoder::GetDecodedData (dirac_encoder_t *encoder)
  504. {
  505.     dirac_frameparams_t *fp = &encoder->dec_fparams;
  506.     int ret_stat = (m_decfnum != -1);
  507.     if (m_return_decoded_frames && m_decfnum != -1)
  508.     {
  509.             fp->ftype = m_decfsort;
  510.             fp->fnum = m_decfnum;
  511.             encoder->decoded_frame_avail = 1;
  512.             m_decfnum = -1;
  513.     }
  514.     return ret_stat;
  515. }
  516. void DiracEncoder::GetSequenceStats(dirac_encoder_t *encoder)
  517. {
  518.     dirac_enc_seqstats_t *sstats = &encoder->enc_seqstats;
  519.     dirac_seqparams_t *sparams = &encoder->enc_ctx.seq_params;
  520.     sstats->seq_bits = m_encparams.BitsOut().SequenceBytes() * 8;
  521.     sstats->seq_hdr_bits = m_encparams.BitsOut().SequenceHeadBytes() * 8;
  522.     sstats->mv_bits = m_encparams.BitsOut().MVBytes() * 8;
  523.     sstats->ycomp_bits = m_encparams.BitsOut().ComponentBytes( Y_COMP ) * 8;
  524.     sstats->ucomp_bits = m_encparams.BitsOut().ComponentBytes( U_COMP ) * 8;
  525.     sstats->vcomp_bits = m_encparams.BitsOut().ComponentBytes( V_COMP ) * 8;
  526.     sstats->bit_rate = (sstats->seq_bits * sparams->frame_rate.numerator)/
  527.                         (sparams->frame_rate.denominator * m_num_coded_frames);
  528. }
  529. int DiracEncoder::GetSequenceEnd (dirac_encoder_t *encoder)
  530. {
  531.     dirac_enc_data_t *encdata = &encoder->enc_buf;
  532.     m_comp_stream.str("");
  533.     m_comp->EndSequence();
  534.     int size = m_comp_stream.str().size();
  535.     if (size > 0)
  536.     {
  537.         if (encdata->size < size )
  538.         {
  539.             return -1;
  540.         }
  541.         memmove (encdata->buffer, m_comp_stream.str().c_str(),  size);
  542.         GetSequenceStats(encoder);
  543.         m_comp_stream.str("");
  544.         encdata->size = size;
  545.     }
  546.     else
  547.     {
  548.         encdata->size = 0;
  549.     }
  550.     return size;
  551. }
  552. static bool InitialiseEncoder (const dirac_encoder_context_t *enc_ctx, bool verbose, dirac_encoder_t *encoder)
  553. {
  554.     TEST (enc_ctx != NULL);
  555.     TEST (encoder != NULL);
  556.     
  557.     if (enc_ctx->seq_params.width == 0 || enc_ctx->seq_params.height == 0)
  558.         return false;
  559.     if (enc_ctx->seq_params.chroma < Yonly || 
  560.             enc_ctx->seq_params.chroma > formatNK)
  561.         return false;
  562.     if (!enc_ctx->seq_params.frame_rate.numerator || 
  563.             !enc_ctx->seq_params.frame_rate.denominator)
  564.         return false;
  565.     memmove (&encoder->enc_ctx, enc_ctx, sizeof(dirac_encoder_context_t));
  566.     encoder->dec_buf.id = 0;
  567.     switch ( enc_ctx->seq_params.chroma )
  568.     {
  569.     case Yonly:
  570.          encoder->enc_ctx.seq_params.chroma_width = 0;
  571.          encoder->enc_ctx.seq_params.chroma_height = 0;
  572.         break;
  573.     case format411:
  574.          encoder->enc_ctx.seq_params.chroma_width = enc_ctx->seq_params.width/4;
  575.          encoder->enc_ctx.seq_params.chroma_height = enc_ctx->seq_params.height;
  576.          break;
  577.     case format420:
  578.          encoder->enc_ctx.seq_params.chroma_width = enc_ctx->seq_params.width/2;
  579.          encoder->enc_ctx.seq_params.chroma_height = enc_ctx->seq_params.height/2;
  580.          break;
  581.     case format422:
  582.          encoder->enc_ctx.seq_params.chroma_width = enc_ctx->seq_params.width/2;
  583.          encoder->enc_ctx.seq_params.chroma_height = enc_ctx->seq_params.height;
  584.          break;
  585.     case format444:
  586.     default:
  587.          encoder->enc_ctx.seq_params.chroma_width = enc_ctx->seq_params.width;
  588.          encoder->enc_ctx.seq_params.chroma_height = enc_ctx->seq_params.height;
  589.          break;
  590.     }
  591.     try
  592.     {
  593.         DiracEncoder *comp = new DiracEncoder (&encoder->enc_ctx, verbose);
  594.     
  595.         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);
  596.         encoder->dec_buf.buf[0] = new unsigned char [bufsize];
  597.         encoder->dec_buf.buf[1] = encoder->dec_buf.buf[0] + 
  598.                 (encoder->enc_ctx.seq_params.width * encoder->enc_ctx.seq_params.height);
  599.         encoder->dec_buf.buf[2] = encoder->dec_buf.buf[1] + 
  600.                 (encoder->enc_ctx.seq_params.chroma_width*encoder->enc_ctx.seq_params.chroma_height);
  601.     
  602.         encoder->compressor = comp;
  603.         if (encoder->enc_ctx.decode_flag)
  604.         {
  605.             comp->SetDecodeBuffer (encoder->dec_buf.buf[0], bufsize);
  606.         }
  607.     }
  608.     catch (...)
  609.     {
  610.         return false;
  611.     }
  612.     return true;
  613. }
  614. static void SetSequenceParameters (dirac_encoder_context_t *enc_ctx, dirac_encoder_presets_t preset)
  615. {
  616.     TEST (enc_ctx != NULL);
  617.     dirac_seqparams_t &sparams = enc_ctx->seq_params;
  618.     sparams.chroma = format420;
  619.     switch (preset)
  620.     {
  621.     case SD576:
  622.         sparams.width = 720;
  623.         sparams.height = 576;
  624.         sparams.frame_rate.numerator = 25;
  625.         sparams.frame_rate.denominator = 1;
  626.         sparams.interlace = 1;
  627.         sparams.topfieldfirst = 1;
  628.         break;
  629.     case HD720:
  630.         sparams.width = 1280;
  631.         sparams.height = 720;
  632.         sparams.frame_rate.numerator = 50;
  633.         sparams.frame_rate.denominator = 1;
  634.         sparams.interlace = 0;
  635.         sparams.topfieldfirst = 0;
  636.         break;
  637.     case HD1080:
  638.         sparams.width = 1920;
  639.         sparams.height = 1080;
  640.         sparams.frame_rate.numerator = 25;
  641.         sparams.frame_rate.denominator = 1;
  642.         sparams.interlace = 1;
  643.         sparams.topfieldfirst = 1;
  644.         break;
  645.     case CIF:
  646.     default:
  647.         sparams.width = 352;
  648.         sparams.height = 288;
  649.         sparams.frame_rate.numerator = 13;
  650.         sparams.frame_rate.denominator = 1;
  651.         sparams.interlace = 0;
  652.         sparams.topfieldfirst = 0;
  653.         break;
  654.     }
  655. }
  656. static void SetEncoderParameters (dirac_encoder_context_t *enc_ctx, dirac_encoder_presets_t preset)
  657. {
  658.     TEST (enc_ctx != NULL);
  659.     dirac_encparams_t &encparams = enc_ctx->enc_params;
  660.     encparams.qf = 7.0f;
  661.     switch (preset)
  662.     {
  663.     case SD576:
  664.         encparams.L1_sep = 3;
  665.         encparams.num_L1 = 3;
  666.         encparams.cpd = 32.0f;
  667.         encparams.xblen = 12;
  668.         encparams.yblen = 12;
  669.         encparams.xbsep = 8;
  670.         encparams.ybsep = 8;
  671.         break;
  672.     case HD720:
  673.         encparams.L1_sep = 3;
  674.         encparams.num_L1 = 7;
  675.         encparams.cpd = 20.0f;
  676.         encparams.xblen = 16;
  677.         encparams.yblen = 16;
  678.         encparams.xbsep = 10;
  679.         encparams.ybsep = 12;
  680.         break;
  681.     case HD1080:
  682.         encparams.L1_sep = 3;
  683.         encparams.num_L1 = 3;
  684.         encparams.cpd = 32.0f;
  685.         encparams.xblen = 20;
  686.         encparams.yblen = 20;
  687.         encparams.xbsep = 16;
  688.         encparams.ybsep = 16;
  689.         break;
  690.     case CIF:
  691.     default:
  692.         encparams.L1_sep = 3;
  693.         encparams.num_L1 = 11;
  694.         encparams.cpd = 20.0f;
  695.         encparams.xblen = 12;
  696.         encparams.yblen = 12;
  697.         encparams.xbsep = 8;
  698.         encparams.ybsep = 8;
  699.         break;
  700.     }
  701. }
  702. #ifdef __cplusplus
  703. extern "C" {
  704. #endif
  705. extern DllExport void dirac_encoder_context_init ( dirac_encoder_context_t *enc_ctx, dirac_encoder_presets_t preset)
  706. {
  707.     TEST (enc_ctx != NULL);
  708.     memset (enc_ctx, 0, sizeof(dirac_encoder_context_t));
  709.     SetSequenceParameters (enc_ctx, preset);
  710.     SetEncoderParameters (enc_ctx, preset);
  711. }
  712. extern DllExport dirac_encoder_t *dirac_encoder_init (const dirac_encoder_context_t *enc_ctx, int verbose)
  713. {
  714.     /* Allocate for encoder */
  715.     dirac_encoder_t *encoder = new dirac_encoder_t;
  716.     memset (encoder, 0, sizeof(dirac_encoder_t));
  717.     /* initialse the encoder context */
  718.     if (!InitialiseEncoder(enc_ctx, verbose>0, encoder))
  719.     {
  720.         delete encoder;
  721.         return NULL;
  722.     }
  723.     encoder->encoded_frame_avail = encoder->decoded_frame_avail = 0;
  724.     encoder->instr_data_avail = 0;
  725.     return encoder;
  726. }
  727. extern DllExport int dirac_encoder_load (dirac_encoder_t *encoder, unsigned char *uncdata, int uncdata_size)
  728. {
  729.     TEST (encoder != NULL);
  730.     TEST (encoder->compressor != NULL);
  731.     DiracEncoder *compressor = (DiracEncoder *)encoder->compressor;
  732.     int ret_stat = 0;
  733.     try
  734.     {
  735.         if ( compressor->LoadNextFrame (uncdata, uncdata_size))
  736.         {
  737.             ret_stat = uncdata_size;
  738.         }
  739.     }
  740.     catch (...)
  741.     {
  742.         if (compressor->GetEncParams().Verbose())
  743.             std::cerr << "dirac_encoder_load failed" << std::endl;
  744.         ret_stat = -1;
  745.     }
  746.     return ret_stat;
  747. }
  748. extern DllExport dirac_encoder_state_t 
  749.       dirac_encoder_output (dirac_encoder_t *encoder)
  750. {
  751.     TEST (encoder != NULL);
  752.     TEST (encoder->compressor != NULL);
  753.     TEST (encoder->enc_buf.size != 0);
  754.     TEST (encoder->enc_buf.buffer != NULL);
  755.     DiracEncoder *compressor = (DiracEncoder *)encoder->compressor;
  756.     dirac_encoder_state_t ret_stat = ENC_STATE_BUFFER;
  757.     encoder->encoded_frame_avail = 0;
  758.     encoder->decoded_frame_avail = 0;
  759.     encoder->instr_data_avail = 0;
  760.     try
  761.     {
  762.         compressor->CompressNextFrame();
  763.         if (compressor->GetEncodedData (encoder) < 0)
  764.             ret_stat = ENC_STATE_INVALID;
  765.         else
  766.         {
  767.             if (encoder->enc_buf.size > 0)
  768.             {
  769.                 ret_stat = ENC_STATE_AVAIL;
  770.             }
  771.     
  772.             if (encoder->enc_ctx.decode_flag)
  773.                 compressor->GetDecodedData(encoder);
  774.         }
  775.     }
  776.     catch (...)
  777.     {
  778.         if (compressor->GetEncParams().Verbose())
  779.             std::cerr << "GetEncodedData failed..." << std::endl;
  780.         ret_stat = ENC_STATE_INVALID;
  781.     }
  782.     return ret_stat;
  783. }
  784. extern DllExport int dirac_encoder_end_sequence (dirac_encoder_t *encoder)
  785. {
  786.     TEST (encoder != NULL);
  787.     TEST (encoder->compressor != NULL);
  788.     DiracEncoder *compressor = (DiracEncoder *)encoder->compressor;
  789.     int ret_stat;
  790.     encoder->encoded_frame_avail = 0;
  791.     encoder->decoded_frame_avail = 0;
  792.     encoder->instr_data_avail = 0;
  793.     try
  794.     {
  795.         ret_stat = compressor->GetSequenceEnd (encoder);
  796.         encoder->end_of_sequence = 1;
  797.         if (compressor->GetDecodedData(encoder))
  798.         {
  799.             encoder->decoded_frame_avail = 1;
  800.         }
  801.     }
  802.     catch (...)
  803.     {
  804.         if (compressor->GetEncParams().Verbose())
  805.             std::cerr << "GetSequenceEnd failed..." << std::endl;
  806.         ret_stat = -1;
  807.     }
  808.     return ret_stat;
  809. }
  810. extern DllExport void dirac_encoder_close (dirac_encoder_t *encoder)
  811. {
  812.     TEST (encoder != NULL);
  813.     TEST (encoder->compressor != NULL);
  814.     
  815.     delete (DiracEncoder *)(encoder->compressor);
  816.     if (encoder->enc_ctx.instr_flag)
  817.     {
  818.         dealloc_instr_data(&encoder->instr);
  819.     }
  820.     if (encoder->enc_ctx.decode_flag)
  821.     {
  822.         delete [] encoder->dec_buf.buf[0];
  823.     }
  824.     delete encoder;
  825. }
  826. #ifdef __cplusplus
  827. }
  828. #endif