1 /* ***** BEGIN LICENSE BLOCK *****
2 *
3 * $Id: dirac_encoder.cpp,v 1.57 2008/11/18 23:25:54 asuraparaju Exp $ $Name: Dirac_1_0_2 $
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 *                 Andrew Kennedy
25 *                 Thomas Davies
26 *                 Myo Tun (Brunel University)
27 *
28 * Alternatively, the contents of this file may be used under the terms of
29 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
30 * Public License Version 2.1 (the "LGPL"), in which case the provisions of
31 * the GPL or the LGPL are applicable instead of those above. If you wish to
32 * allow use of your version of this file only under the terms of the either
33 * the GPL or LGPL and not to allow others to use your version of this file
34 * under the MPL, indicate your decision by deleting the provisions above
35 * and replace them with the notice and other provisions required by the GPL
36 * or LGPL. If you do not delete the provisions above, a recipient may use
37 * your version of this file under the terms of any one of the MPL, the GPL
38 * or the LGPL.
39 * ***** END LICENSE BLOCK ***** */
40 
41 #include <cstring>
42 #include <sstream>
43 #include <fstream>
44 #include <queue>
45 #include <string>
46 #include <libdirac_common/dirac_assertions.h>
47 #include <libdirac_common/common.h>
48 #include <libdirac_common/picture.h>
49 #include <libdirac_common/pic_io.h>
50 #include <libdirac_encoder/dirac_encoder.h>
51 #include <libdirac_encoder/seq_compress.h>
52 #include <libdirac_byteio/dirac_byte_stream.h>
53 #include <libdirac_common/video_format_defaults.h>
54 #include <libdirac_common/dirac_exception.h>
55 
56 using namespace dirac;
57 using namespace std;
58 
59 template <class T, class S >
copy_2dArray(const TwoDArray<T> & in,S * out)60 void copy_2dArray (const TwoDArray<T> & in, S *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++ =  S( in[j][i] );
68         }// i
69     }// j
70 }
71 
copy_2dArray(const TwoDArray<PredMode> & in,int * out)72 void copy_2dArray (const TwoDArray<PredMode> & in, int *out)
73 {
74     for (int j=0 ; j<in.LengthY() ; ++j)
75     {
76         for (int i=0 ; i<in.LengthX() ; ++i)
77         {
78             // out[j*in.LengthX() + i] =  in[j][i];
79             *out++ =  in[j][i];
80         }// i
81     }// j
82 }
83 
copy_2dArray(const TwoDArray<bool> & in,int * out)84 void copy_2dArray (const TwoDArray<bool> & in, int *out)
85 {
86     for (int j=0 ; j<in.LengthY() ; ++j)
87     {
88         for (int i=0 ; i<in.LengthX() ; ++i)
89         {
90             // out[j*in.LengthX() + i] =  in[j][i];
91             *out++ =  in[j][i];
92         }// i
93     }// j
94 }
95 
copy_mv(const MvArray & mv,dirac_mv_t * dmv)96 void copy_mv ( const MvArray& mv, dirac_mv_t *dmv)
97 {
98     for (int j=0 ; j<mv.LengthY() ; ++j)
99     {
100         for (int i=0 ; i<mv.LengthX() ; ++i)
101         {
102             //dmv[j*mv.LengthX() + i].x = mv[j][i].x;
103             //dmv[j*mv.LengthX() + i].y = mv[j][i].y;
104             (*dmv).x = mv[j][i].x;
105             (*dmv).y = mv[j][i].y;
106             dmv++;
107         }// i
108     }// j
109 }
110 
copy_mv_cost(const TwoDArray<MvCostData> & pc,dirac_mv_cost_t * dpc)111 void copy_mv_cost (const TwoDArray<MvCostData> &pc, dirac_mv_cost_t *dpc)
112 {
113     for (int j=0 ; j<pc.LengthY() ; ++j)
114     {
115         for (int i=0 ; i<pc.LengthX() ; ++i)
116         {
117             //dpc[j*pc.LengthX() + i].SAD = pc[j][i].SAD;
118             //dpc[j*pc.LengthX() + i].mvcost = pc[j][i].mvcost;
119             (*dpc).SAD = pc[j][i].SAD;
120             (*dpc).mvcost = pc[j][i].mvcost;
121             dpc++;
122         }// i
123     }// j
124 }
125 
126 /*
127     Function that allocates the locally managed instrumentation data
128 */
alloc_instr_data(dirac_instr_t * instr)129 void alloc_instr_data(dirac_instr_t *instr)
130 {
131     instr->sb_split_mode = new int [instr->sb_ylen*instr->sb_xlen];
132     memset (instr->sb_split_mode, 0, sizeof(int)*instr->sb_ylen*instr->sb_xlen);
133 
134     instr->sb_costs = new float [instr->sb_ylen*instr->sb_xlen];
135     memset (instr->sb_costs, 0, sizeof(float)*instr->sb_ylen*instr->sb_xlen);
136 
137     instr->pred_mode = new int [instr->mv_ylen * instr->mv_xlen];
138     memset (instr->pred_mode, 0, sizeof(int)*instr->mv_ylen*instr->mv_xlen);
139 
140     instr->intra_costs = new float [instr->mv_ylen * instr->mv_xlen];
141     memset (instr->intra_costs, 0, sizeof(float)*instr->mv_ylen*instr->mv_xlen);
142 
143     instr->bipred_costs = new dirac_mv_cost_t [instr->mv_ylen * instr->mv_xlen];
144     memset (instr->bipred_costs, 0, sizeof(dirac_mv_cost_t)*instr->mv_ylen*instr->mv_xlen);
145 
146     instr->dc_ycomp = new short [instr->mv_ylen * instr->mv_xlen];
147     memset (instr->dc_ycomp, 0, sizeof(short)*instr->mv_ylen*instr->mv_xlen);
148 
149     instr->dc_ucomp = new short [instr->mv_ylen * instr->mv_xlen];
150     memset (instr->dc_ucomp, 0, sizeof(short)*instr->mv_ylen*instr->mv_xlen);
151 
152     instr->dc_vcomp = new short [instr->mv_ylen * instr->mv_xlen];
153     memset (instr->dc_vcomp, 0, sizeof(short)*instr->mv_ylen*instr->mv_xlen);
154 
155     for (int i = 0; i < 2; i++)
156     {
157         instr->mv[i] = new dirac_mv_t[instr->mv_ylen * instr->mv_xlen];
158         memset (instr->mv[i], 0,
159             sizeof(dirac_mv_t)*instr->mv_ylen*instr->mv_xlen);
160     }
161 
162     for (int i = 0; i < 2; i++)
163     {
164         instr->pred_costs[i] = new dirac_mv_cost_t[instr->mv_ylen * instr->mv_xlen];
165         memset (instr->pred_costs[i], 0,
166             sizeof(dirac_mv_cost_t)*instr->mv_ylen*instr->mv_xlen);
167     }
168 }
169 
170 /*
171     Function that frees the locally managed instrumentation data
172 */
dealloc_instr_data(dirac_instr_t * instr)173 void dealloc_instr_data(dirac_instr_t *instr)
174 {
175     if (instr->sb_split_mode)
176         delete [] instr->sb_split_mode;
177 
178     if (instr->sb_costs)
179         delete [] instr->sb_costs;
180 
181     if (instr->pred_mode)
182         delete [] instr->pred_mode;
183 
184     if (instr->intra_costs)
185         delete [] instr->intra_costs;
186 
187     if (instr->bipred_costs)
188         delete [] instr->bipred_costs;
189 
190     if (instr->dc_ycomp)
191         delete [] instr->dc_ycomp;
192 
193     if (instr->dc_ucomp)
194         delete [] instr->dc_ucomp;
195 
196     if (instr->dc_vcomp)
197         delete [] instr->dc_vcomp;
198 
199     for (int i = 0; i < 2; i++)
200     {
201         if (instr->mv[i])
202             delete [] instr->mv[i];
203     }
204     for (int i = 0; i < 2; i++)
205     {
206         if (instr->pred_costs[i])
207             delete [] instr->pred_costs[i];
208     }
209 }
210 
211 /*
212     Wrapper class around the SequenceCompressor Class. This class is used
213     by the "C" encoder interface
214 */
215 class DiracEncoder
216 {
217 public:
218     // constructor
219     DiracEncoder(const dirac_encoder_context_t *enc_ctx, bool verbose);
220     // destructor
221     ~DiracEncoder();
222 
223     // Load the next frame of uncompressed data into the SequenceCompressor
224     bool LoadNextFrame(unsigned char *data, int size);
225     // Compress the next picture (frame/field) of data
226     int CompressNextPicture();
227 
228     // Set the encode frame in encoder to the encoded frame data
229     int GetEncodedData(dirac_encoder_t *encoder);
230 
231     // Set the locally decoded frame data in encoder
232     int GetDecodedData (dirac_encoder_t *encoder);
233 
234     // Set the instrumentation data in encoder
235     void GetInstrumentationData (dirac_encoder_t *encoder);
236 
237     // Set the end of sequence infomration in encoder
238     int GetSequenceEnd(dirac_encoder_t *encoder);
239 
240     // Set the buffer to hold the locally decoded frame
241     void SetDecodeBuffer (unsigned char *buffer, int buffer_size);
242 
243     // Return the encoder parameters
GetEncParams() const244     const EncoderParams& GetEncParams() const { return m_encparams; }
245 
246     // Return the source parameters
GetSrcParams() const247     const SourceParams& GetSrcParams() const { return m_srcparams; }
248 
249     // Return the pts offset
GetPTSOffset() const250     int GetPTSOffset() const { return m_seqcomp->PTSOffset(); }
251 
252     // Signal End of Sequence
SignalEOS()253     void SignalEOS() { m_eos_signalled = true; m_seqcomp->SignalEOS(); }
254 
255     //  End of Sequence
EOS()256     bool EOS() { return m_eos_signalled == true; }
257 
258 private:
259 
260     // Set the encoder parameters
261     void SetEncoderParams (const dirac_encoder_context_t *enc_ctx);
262 
263     // Set the source parameters
264     void SetSourceParams (const dirac_encoder_context_t *enc_ctx);
265 
266     // Get the picture statistics
267     void GetPictureStats(dirac_encoder_t *encoder);
268 
269     // Get the seuqence statistics
270     void GetSequenceStats(dirac_encoder_t *encoder,
271                           const DiracByteStats& dirac_seq_stats);
272 
273 private:
274     // sequence compressor
275     SequenceCompressor *m_seqcomp;
276     // Source parameters
277     SourceParams m_srcparams;
278     // encoder parameters
279     EncoderParams m_encparams;
280     // locally encoded picture in coded order
281     const EncPicture *m_enc_picture;
282     // locally encoded frame ME data
283     const MEData *m_enc_medata;
284     // locally decoded picture number in display order
285     int m_decpnum;
286     //locally decoded picture type
287     PictureSort m_decpsort;
288     // locally decoded picture number in display order
289     int m_show_pnum;
290     // total number of frames/fields loaded so far
291     int m_num_loaded_pictures;
292     // total number of frames/fields encoded so far
293     int m_num_coded_pictures;
294     // verbose flag
295     bool m_verbose;
296     // input stream for uncompressed input pictures
297     MemoryStreamInput *m_inp_ptr;
298     // output stream for locally decoded pictures
299     MemoryStreamOutput *m_out_ptr;
300     // buffer to hold locally decoded frame. Set by SetDecodeBuffer
301     unsigned char *m_dec_buf;
302     // size of buffer to hold locally decoded data. Set by SetDecodeBuffer
303     int m_dec_bufsize;
304     // Flag that determines if locally decoded pictures are to be returned. Set
305     // in Constructor
306     bool m_return_decoded_pictures;
307     // Flag that determines if instrumentation data is to be returned. Set
308     // in Constructor
309     bool m_return_instr_data;
310 
311     // Output destination for compressed data in bitstream format
312     DiracByteStream m_dirac_byte_stream;
313 
314        //Rate Control parameters
315     // Total Number of bits for a GOP
316     int m_gop_bits;
317 
318     // Total Number GOPs in the input sequence
319     int m_gop_count;
320 
321     // To count the number of pictures for calculating the GOP bit rate
322     int m_picture_count;
323 
324     // field 1 stats if interlaced
325     dirac_enc_picstats_t m_field1_stats;
326 
327     // End of sequence flag. Set to true when user app signals end of
328     // sequence
329     bool m_eos_signalled;
330 
331 };
332 
333 /*
334     Instrumentation callback. This function is passed as a parameter to the
335     SequenceCompressor constructor. It is called by the
336     FrameCompressor::Compress function once the frame is successfully compressed
337 */
GetInstrumentationData(dirac_encoder_t * encoder)338 void DiracEncoder::GetInstrumentationData (dirac_encoder_t *encoder)
339 {
340     ASSERT (encoder != NULL);
341     dirac_instr_t *instr = &encoder->instr;
342     dirac_instr_t old_instr = *instr;
343 
344     if (!m_return_instr_data || m_enc_picture == NULL)
345         return;
346 
347     const PictureParams& pparams = m_enc_picture->GetPparams();
348     const PictureSort psort = pparams.PicSort();
349 
350     instr->pnum = pparams.PictureNum();
351     instr->ptype = psort.IsIntra() ? INTRA_PICTURE : INTER_PICTURE;
352     instr->rtype = psort.IsRef() ? REFERENCE_PICTURE : NON_REFERENCE_PICTURE;
353     instr->num_refs = 0;
354     encoder->instr_data_avail = 1;
355 
356     if (psort.IsIntra())
357     {
358         // no MV data for Intra coded data
359         return;
360     }
361 
362     TESTM (m_enc_medata != NULL, "ME data available");
363 
364     // Reference info
365     instr->num_refs = pparams.Refs().size();
366     ASSERTM (instr->num_refs <= 2, "Max # reference frames is 2");
367 
368     for (int i=0; i<instr->num_refs; ++i)
369         instr->refs[i] = pparams.Refs()[i];
370 
371     // Block separation params
372     instr->ybsep = m_encparams.GetPicPredParams().LumaBParams(2).Ybsep();
373     instr->xbsep = m_encparams.GetPicPredParams().LumaBParams(2).Xbsep();
374 
375     // Num superblocks
376     instr->sb_ylen = m_enc_medata->SBSplit().LengthY();
377     instr->sb_xlen = m_enc_medata->SBSplit().LengthX();
378 
379     // Motion vector array dimensions
380     instr->mv_ylen = m_enc_medata->Vectors(1).LengthY();
381     instr->mv_xlen = m_enc_medata->Vectors(1).LengthX();
382 
383     if (old_instr.sb_ylen != instr->sb_ylen ||
384         old_instr.sb_xlen != instr->sb_xlen ||
385         old_instr.mv_ylen != instr->mv_ylen ||
386         old_instr.mv_xlen != instr->mv_xlen)
387     {
388         dealloc_instr_data(instr);
389         alloc_instr_data(instr);
390     }
391 
392     copy_2dArray (m_enc_medata->SBSplit(), instr->sb_split_mode);
393     copy_2dArray (m_enc_medata->SBCosts(), instr->sb_costs);
394     copy_2dArray (m_enc_medata->Mode(), instr->pred_mode);
395     copy_2dArray (m_enc_medata->IntraCosts(), instr->intra_costs);
396 
397     if (instr->num_refs > 1)
398     {
399         copy_mv_cost (m_enc_medata->BiPredCosts(), instr->bipred_costs);
400     }
401 
402     copy_2dArray (m_enc_medata->DC( Y_COMP ), instr->dc_ycomp);
403     if (m_enc_medata->DC().Length() == 3)
404     {
405         copy_2dArray (m_enc_medata->DC( U_COMP ), instr->dc_ucomp);
406         copy_2dArray (m_enc_medata->DC( V_COMP ), instr->dc_vcomp);
407     }
408 
409     for (int i=1; i<=instr->num_refs; ++i)
410     {
411         copy_mv (m_enc_medata->Vectors(i), instr->mv[i-1]);
412         copy_mv_cost (m_enc_medata->PredCosts(i), instr->pred_costs[i-1]);
413     }
414 }
415 
DiracEncoder(const dirac_encoder_context_t * enc_ctx,bool verbose)416 DiracEncoder::DiracEncoder(const dirac_encoder_context_t *enc_ctx,
417                            bool verbose) :
418     m_srcparams(static_cast<VideoFormat>(enc_ctx->enc_params.video_format), true),
419     m_encparams(static_cast<VideoFormat>(enc_ctx->enc_params.video_format), INTER_PICTURE, 2, true),
420     m_show_pnum(-1),
421     m_num_loaded_pictures(0),
422     m_num_coded_pictures(0),
423     m_verbose(verbose),
424     m_dec_buf(0),
425     m_dec_bufsize(0),
426     m_return_decoded_pictures(enc_ctx->decode_flag > 0),
427     m_return_instr_data(enc_ctx->instr_flag > 0),
428        m_gop_bits(0),
429     m_gop_count(0),
430     m_picture_count(0),
431     m_eos_signalled(false)
432 {
433     // Setup source parameters
434     SetSourceParams (enc_ctx);
435     // Setup encoder parameters
436     m_encparams.SetVerbose( verbose );
437     SetEncoderParams (enc_ctx);
438 
439     // Set up the input data stream (uncompressed data)
440     m_inp_ptr = new MemoryStreamInput(m_srcparams, m_encparams.FieldCoding());
441     // Set up the output data stream (locally decoded frame)
442     m_out_ptr = new MemoryStreamOutput(m_srcparams, m_encparams.FieldCoding());
443 
444     // initialise the sequence compressor
445     if (!m_encparams.FieldCoding())
446     {
447         m_seqcomp = new FrameSequenceCompressor (m_inp_ptr->GetStream(), m_encparams, m_dirac_byte_stream);
448     }
449     else
450     {
451         m_seqcomp = new FieldSequenceCompressor (m_inp_ptr->GetStream(), m_encparams, m_dirac_byte_stream);
452     }
453 }
454 
SetDecodeBuffer(unsigned char * buffer,int buffer_size)455 void DiracEncoder::SetDecodeBuffer (unsigned char *buffer, int buffer_size)
456 {
457     m_dec_buf = buffer;
458     m_dec_bufsize = buffer_size;
459     m_return_decoded_pictures = true;
460 }
461 
~DiracEncoder()462 DiracEncoder::~DiracEncoder()
463 {
464     delete m_seqcomp;
465     delete m_inp_ptr;
466     delete m_out_ptr;
467 }
468 
SetSourceParams(const dirac_encoder_context_t * enc_ctx)469 void DiracEncoder::SetSourceParams (const dirac_encoder_context_t *enc_ctx)
470 {
471     m_srcparams.SetCFormat( enc_ctx->src_params.chroma );
472     m_srcparams.SetXl( enc_ctx->src_params.width );
473     m_srcparams.SetYl( enc_ctx->src_params.height );
474 
475     m_srcparams.SetCleanWidth( m_srcparams.Xl() );
476     m_srcparams.SetCleanHeight( m_srcparams.Yl() );
477     m_srcparams.SetLeftOffset( 0 );
478     m_srcparams.SetTopOffset( 0 );
479 
480     m_srcparams.SetSourceSampling( enc_ctx->src_params.source_sampling );
481     if (m_srcparams.FrameRate().m_num != (unsigned int)enc_ctx->src_params.frame_rate.numerator ||
482         m_srcparams.FrameRate().m_denom != (unsigned int)enc_ctx->src_params.frame_rate.denominator)
483     {
484         m_srcparams.SetFrameRate( enc_ctx->src_params.frame_rate.numerator,
485                             enc_ctx->src_params.frame_rate.denominator );
486     }
487     if (m_srcparams.PixelAspectRatio().m_num != (unsigned int)enc_ctx->src_params.pix_asr.numerator ||
488         m_srcparams.PixelAspectRatio().m_denom != (unsigned int)enc_ctx->src_params.pix_asr.denominator)
489     {
490         m_srcparams.SetPixelAspectRatio( enc_ctx->src_params.pix_asr.numerator,
491                             enc_ctx->src_params.pix_asr.denominator );
492     }
493     // TO DO: CLEAN AREA and signal range
494     // FIXME: Dirac currently support 8BIT_VIDEO only. Accept from command line
495     // when Dirac supports multiple signal ranges.
496     m_srcparams.SetSignalRange(SIGNAL_RANGE_8BIT_VIDEO);
497 
498 }
499 
SetEncoderParams(const dirac_encoder_context_t * enc_ctx)500 void DiracEncoder::SetEncoderParams (const dirac_encoder_context_t *enc_ctx)
501 {
502     TEST (enc_ctx != NULL);
503     OLBParams bparams(12, 12, 8, 8);
504 
505     m_encparams.SetLocalDecode(enc_ctx->decode_flag);
506     m_encparams.SetXl( enc_ctx->src_params.width );
507     m_encparams.SetYl( enc_ctx->src_params.height );
508     m_encparams.SetChromaXl( enc_ctx->src_params.chroma_width );
509     m_encparams.SetChromaYl( enc_ctx->src_params.chroma_height );
510 
511     if (enc_ctx->enc_params.picture_coding_mode > 1)
512     {
513         std::ostringstream errstr;
514 
515         errstr << "Picture coding mode "
516                << enc_ctx->enc_params.picture_coding_mode
517                << " out of supported range [0-1]";
518         DIRAC_THROW_EXCEPTION(
519             ERR_INVALID_INIT_DATA,
520             errstr.str(),
521             SEVERITY_TERMINATE);
522     }
523 
524     m_encparams.SetPictureCodingMode(enc_ctx->enc_params.picture_coding_mode);
525     if (m_encparams.FieldCoding())
526     {
527         // Change coding dimensions to field dimensions
528         m_encparams.SetYl( enc_ctx->src_params.height>>1 );
529         m_encparams.SetChromaYl( enc_ctx->src_params.chroma_height >> 1);
530     }
531 
532     unsigned int luma_depth = static_cast<unsigned int> (
533             std::log((double)m_srcparams.LumaExcursion())/std::log(2.0) + 1 );
534     m_encparams.SetLumaDepth(luma_depth);
535 
536     unsigned int chroma_depth = static_cast<unsigned int> (
537             std::log((double)m_srcparams.ChromaExcursion())/std::log(2.0) + 1 );
538     m_encparams.SetChromaDepth(chroma_depth);
539 
540     m_encparams.SetFullSearch(enc_ctx->enc_params.full_search);
541     m_encparams.SetCombinedME(enc_ctx->enc_params.combined_me);
542     m_encparams.SetXRangeME(enc_ctx->enc_params.x_range_me);
543     m_encparams.SetYRangeME(enc_ctx->enc_params.y_range_me);
544     m_encparams.SetCPD(enc_ctx->enc_params.cpd);
545     m_encparams.SetQf(enc_ctx->enc_params.qf);
546     m_encparams.SetTargetRate(enc_ctx->enc_params.trate);
547     m_encparams.SetLossless(enc_ctx->enc_params.lossless);
548     m_encparams.SetL1Sep(enc_ctx->enc_params.L1_sep);
549     m_encparams.SetNumL1(enc_ctx->enc_params.num_L1);
550     m_encparams.SetPrefilter(enc_ctx->enc_params.prefilter,
551                              enc_ctx->enc_params.prefilter_strength);
552     m_encparams.SetUFactor(1.5f);
553     m_encparams.SetVFactor(0.75f);
554     m_encparams.GetPicPredParams().SetMVPrecision(enc_ctx->enc_params.mv_precision);
555     m_encparams.SetUsingAC(enc_ctx->enc_params.using_ac);
556     bparams.SetYblen( enc_ctx->enc_params.yblen );
557     bparams.SetXblen( enc_ctx->enc_params.xblen );
558     bparams.SetYbsep( enc_ctx->enc_params.ybsep );
559     bparams.SetXbsep( enc_ctx->enc_params.xbsep );
560 
561     // Now rationalise the GOP options
562     // this stuff should really be done in a constructor!
563     if (m_encparams.NumL1()<0)
564     {
565         //don't have a proper GOP
566         m_encparams.SetL1Sep( std::max(1 , m_encparams.L1Sep()) );
567     }
568     else if (m_encparams.NumL1() == 0)
569     {
570         //have I-frame only coding
571         m_encparams.SetL1Sep(0);
572     }
573     m_encparams.GetPicPredParams().SetBlockSizes( bparams , enc_ctx->src_params.chroma );
574 
575     // Set transforms parameters
576     m_encparams.SetIntraTransformFilter(enc_ctx->enc_params.intra_wlt_filter);
577     m_encparams.SetInterTransformFilter(enc_ctx->enc_params.inter_wlt_filter);
578     m_encparams.SetSpatialPartition(enc_ctx->enc_params.spatial_partition);
579 
580     m_encparams.SetTransformDepth(enc_ctx->enc_params.wlt_depth);
581     m_encparams.SetCodeBlockMode(enc_ctx->enc_params.spatial_partition && enc_ctx->enc_params.multi_quants ? QUANT_MULTIPLE : QUANT_SINGLE);
582 }
583 
584 
LoadNextFrame(unsigned char * data,int size)585 bool DiracEncoder::LoadNextFrame (unsigned char *data, int size)
586 {
587     TESTM (m_seqcomp->Finished() != true, "Did not reach end of sequence");
588     m_inp_ptr->SetMembufReference(data, size);
589     if (m_seqcomp->LoadNextFrame())
590     {
591         if (!m_encparams.FieldCoding())
592             m_num_loaded_pictures++;
593         else
594             m_num_loaded_pictures+=2;
595         return true;
596     }
597     return false;
598 }
599 
CompressNextPicture()600 int DiracEncoder::CompressNextPicture ()
601 {
602     TESTM (m_seqcomp->Finished() != true, "Did not reach end of sequence");
603 
604     if (!m_num_loaded_pictures)
605         return 0;
606 
607     const EncPicture *mypicture = m_seqcomp->CompressNextPicture();
608 
609     m_decpnum = -1;
610 
611     if (mypicture){
612         m_enc_picture = m_seqcomp->GetPictureEncoded();
613 	if (m_enc_picture->GetPparams().PicSort().IsIntra()==false)
614             m_enc_medata = &m_enc_picture->GetMEData();
615 	else
616 	    m_enc_medata = NULL;
617 
618         if (m_return_decoded_pictures &&
619                 mypicture->GetPparams().PictureNum() != m_show_pnum){
620             int ret_val;
621             m_show_pnum = mypicture->GetPparams().PictureNum();
622             TEST (! (m_return_decoded_pictures && !m_dec_buf) );
623             if (m_return_decoded_pictures && m_dec_buf)
624             {
625                 // write locally decoded picture to decode buffer
626                 m_out_ptr->SetMembufReference(m_dec_buf, m_dec_bufsize);
627                 ret_val = m_out_ptr->GetStream()->WriteToNextFrame(*mypicture);
628 
629                 if (ret_val)
630                 {
631                     m_decpnum = m_show_pnum;
632                     m_decpsort = mypicture->GetPparams().PicSort();
633                 }
634             }
635         }
636     }
637     else{
638         m_enc_picture = NULL;
639         m_enc_medata = NULL;
640     }
641 
642     if(!m_dirac_byte_stream.IsUnitAvailable())
643         return 0;
644 
645     if (mypicture){
646          m_num_coded_pictures++;
647          TESTM (m_enc_picture != 0, "Encoder picture available");
648     }
649     return 1;
650 }
651 
GetPictureStats(dirac_encoder_t * encoder)652 void DiracEncoder::GetPictureStats(dirac_encoder_t *encoder)
653 {
654 
655     dirac_enc_picstats_t *pstats = &encoder->enc_pstats;
656     DiracByteStats dirac_byte_stats = m_dirac_byte_stream.GetLastUnitStats();
657 
658     pstats->mv_bits = dirac_byte_stats.GetBitCount(STAT_MV_BYTE_COUNT);
659   //  pstats->mv_hdr_bits = poutput.MVBytes() * 8;
660 
661     pstats->ycomp_bits = dirac_byte_stats.GetBitCount(STAT_YCOMP_BYTE_COUNT);
662   //  pstats->ycomp_hdr_bits = poutput.ComponentHeadBytes( Y_COMP ) * 8;
663 
664     pstats->ucomp_bits = dirac_byte_stats.GetBitCount(STAT_UCOMP_BYTE_COUNT);
665   //  pstats->ucomp_hdr_bits = poutput.ComponentHeadBytes( U_COMP ) * 8;
666 
667     pstats->vcomp_bits = dirac_byte_stats.GetBitCount(STAT_VCOMP_BYTE_COUNT);
668    // pstats->vcomp_hdr_bits = poutput.ComponentHeadBytes( V_COMP ) * 8;
669 
670     pstats->pic_bits = dirac_byte_stats.GetBitCount(STAT_TOTAL_BYTE_COUNT);
671    // pstats->pic_hdr_bits = poutput.PictureHeadBytes() * 8;
672 
673     DiracEncoder *compressor = (DiracEncoder *)encoder->compressor;
674     if (compressor->GetEncParams().Verbose())
675     {
676         std::cout<<std::endl<<"Number of MV bits="<<pstats->mv_bits;
677         std::cout<<std::endl<<"Number of bits for Y="<<pstats->ycomp_bits;
678         std::cout<<std::endl<<"Number of bits for U="<<pstats->ucomp_bits;
679         std::cout<<std::endl<<"Number of bits for V="<<pstats->vcomp_bits;
680         if (m_encparams.FieldCoding())
681             std::cout<<std::endl<<"Total field bits="<<pstats->pic_bits;
682         else
683             std::cout<<std::endl<<"Total frame bits="<<pstats->pic_bits;
684     }
685 }
686 
GetEncodedData(dirac_encoder_t * encoder)687 int DiracEncoder::GetEncodedData (dirac_encoder_t *encoder)
688 {
689     int size = 0;
690     dirac_enc_data_t *encdata = &encoder->enc_buf;
691 
692     string output = m_dirac_byte_stream.GetBytes();
693     size = output.size();
694     //std::cout << std::endl << "ParseUnit size=" << size << std::endl;
695     if (size > 0)
696     {
697         if (encdata->size < size )
698         {
699             return -1;
700         }
701         memmove (encdata->buffer, output.c_str(),  output.size());
702         if (m_enc_picture)
703         {
704             // picture data
705             encoder->enc_pparams.pnum = m_enc_picture->GetPparams().PictureNum();
706             encoder->enc_pparams.ptype = m_enc_picture->GetPparams().PicSort().IsIntra() ? INTRA_PICTURE : INTER_PICTURE;
707             encoder->enc_pparams.rtype = m_enc_picture->GetPparams().PicSort().IsRef() ? REFERENCE_PICTURE : NON_REFERENCE_PICTURE;
708 
709             // Get frame statistics
710             GetPictureStats (encoder);
711             if(m_encparams.Verbose() && encoder->enc_ctx.enc_params.picture_coding_mode==1)
712             {
713                 if (encoder->enc_pparams.pnum%2 == 0)
714                     m_field1_stats = encoder->enc_pstats;
715                 else
716                 {
717                     std::cout<<std::endl<<std::endl
718                              <<"Frame "<<encoder->enc_pparams.pnum/2;
719                     std::cout<< " stats";
720                     std::cout<<std::endl<< "Number of MV bits=";
721                     std::cout<< m_field1_stats.mv_bits + encoder->enc_pstats.mv_bits;
722                     std::cout<< std::endl << "Number of bits for Y=";
723                     std::cout<< m_field1_stats.ycomp_bits + encoder->enc_pstats.ycomp_bits;
724                     std::cout<< std::endl << "Number of bits for U=";
725                     std::cout<< m_field1_stats.ucomp_bits + encoder->enc_pstats.ucomp_bits;
726                     std::cout<< std::endl << "Number of bits for V=";
727                     std::cout<< m_field1_stats.vcomp_bits + encoder->enc_pstats.vcomp_bits;
728                     std::cout << std::endl << "Total frame bits=";
729                     std::cout<< m_field1_stats.pic_bits + encoder->enc_pstats.pic_bits;
730                 }
731             }
732            }
733         else
734         {
735             // Not picture data
736             encoder->enc_pparams.pnum = -1;
737         }
738         encdata->size = size;
739 
740         GetInstrumentationData(encoder);
741         encoder->encoded_picture_avail = 1;
742     }
743     else
744     {
745         encdata->size = 0;
746     }
747 
748     if (m_enc_picture)
749     {
750        //Rate Control - work out bit rate to date and for current GOP
751        // and keep track of frame numbers
752     int interlace_factor = m_encparams.FieldCoding() ? 2 : 1;
753     int num_L1 = encoder->enc_ctx.enc_params.num_L1;
754     int L1_sep = encoder->enc_ctx.enc_params.L1_sep;
755 
756     // Length of the GOP in pictures - twice as many if fields
757     int GOP_pic_length = (num_L1+1)*L1_sep*interlace_factor;
758 
759     int offset;
760     if (num_L1 == 0)
761     {
762         GOP_pic_length = 10;
763         offset = 0;
764     }
765     else
766         offset = std::max(L1_sep-1,0)*interlace_factor;
767 
768     m_gop_bits += encoder->enc_pstats.pic_bits;
769     m_picture_count++;
770 
771     if ( (m_gop_count==0 && m_picture_count == GOP_pic_length-offset) ||
772          (m_gop_count>0 && m_picture_count == GOP_pic_length))
773     {
774         int denominator = encoder->enc_ctx.src_params.frame_rate.denominator;
775         int numerator = encoder->enc_ctx.src_params.frame_rate.numerator;
776         double frame_rate =  (double)numerator/(double)denominator;
777 
778         double gop_duration = double(m_picture_count)/interlace_factor/frame_rate;
779         double bit_rate = double(m_gop_bits)/gop_duration;
780 
781         DiracEncoder *compressor = (DiracEncoder *)encoder->compressor;
782         if (compressor->GetEncParams().Verbose())
783         {
784             std::cout<<std::endl<<std::endl<<"Bit Rate for GOP number ";
785             std::cout<<m_gop_count<<" is "<<bit_rate/1000.0<<" kbps"<<std::endl;
786         }
787 
788         m_gop_count++;
789         m_gop_bits = 0;
790         m_picture_count = 0;
791     }
792     //End of Rate Control
793     }
794 
795     m_dirac_byte_stream.Clear();
796 
797     return size;
798 }
799 
GetDecodedData(dirac_encoder_t * encoder)800 int DiracEncoder::GetDecodedData (dirac_encoder_t *encoder)
801 {
802     dirac_picparams_t *pp = &encoder->dec_pparams;
803 
804     int ret_stat = (m_decpnum != -1);
805     if (m_return_decoded_pictures && m_decpnum != -1)
806     {
807         pp->ptype = m_decpsort.IsIntra() ? INTRA_PICTURE : INTER_PICTURE;
808         pp->rtype = m_decpsort.IsRef() ? REFERENCE_PICTURE : NON_REFERENCE_PICTURE;
809         pp->pnum = m_decpnum;
810         encoder->decoded_frame_avail = 1;
811         m_decpnum = -1;
812     }
813     return ret_stat;
814 }
815 
GetSequenceStats(dirac_encoder_t * encoder,const DiracByteStats & dirac_seq_stats)816 void DiracEncoder::GetSequenceStats(dirac_encoder_t *encoder,
817                                     const DiracByteStats& dirac_seq_stats)
818 {
819     dirac_enc_seqstats_t *sstats = &encoder->enc_seqstats;
820 
821     sstats->seq_bits = dirac_seq_stats.GetBitCount(STAT_TOTAL_BYTE_COUNT);
822     sstats->mv_bits = dirac_seq_stats.GetBitCount(STAT_MV_BYTE_COUNT);
823     sstats->ycomp_bits = dirac_seq_stats.GetBitCount(STAT_YCOMP_BYTE_COUNT);
824     sstats->ucomp_bits = dirac_seq_stats.GetBitCount(STAT_UCOMP_BYTE_COUNT);
825     sstats->vcomp_bits = dirac_seq_stats.GetBitCount(STAT_VCOMP_BYTE_COUNT);
826 
827     sstats->bit_rate = int64_t((sstats->seq_bits *
828                         (double)m_srcparams.FrameRate().m_num)/
829                         (m_srcparams.FrameRate().m_denom * m_num_coded_pictures));
830     if (encoder->enc_ctx.enc_params.picture_coding_mode==1)
831         sstats->bit_rate *= 2;
832 
833     DiracEncoder *compressor = (DiracEncoder *)encoder->compressor;
834     if (compressor->GetEncParams().Verbose())
835     {
836         std::cout<<std::endl<<std::endl<<"Total bits for sequence="<<sstats->seq_bits;
837         std::cout<<std::endl<<"Of these: "<<std::endl;
838         std::cout<<std::endl<<sstats->ycomp_bits <<" were Y, ";
839         std::cout<<std::endl<<sstats->ucomp_bits <<" were U, ";
840         std::cout<<std::endl<<sstats->vcomp_bits<<" were V, and ";
841         std::cout<<std::endl<<sstats->mv_bits<<" were motion vector data.";
842     }
843 }
844 
GetSequenceEnd(dirac_encoder_t * encoder)845 int DiracEncoder::GetSequenceEnd (dirac_encoder_t *encoder)
846 {
847     dirac_enc_data_t *encdata = &encoder->enc_buf;
848     DiracByteStats dirac_seq_stats=m_seqcomp->EndSequence();
849     string output = m_dirac_byte_stream.GetBytes();
850     int size = output.size();
851     if (size > 0)
852     {
853         if (encdata->size < size )
854         {
855             return -1;
856         }
857         memmove (encdata->buffer, output.c_str(),  size);
858         GetSequenceStats(encoder,
859                          dirac_seq_stats);
860         encdata->size = size;
861     }
862     else
863     {
864         encdata->size = 0;
865     }
866     m_dirac_byte_stream.Clear();
867     return size;
868 }
869 
InitialiseEncoder(const dirac_encoder_context_t * enc_ctx,bool verbose,dirac_encoder_t * encoder)870 static bool InitialiseEncoder (const dirac_encoder_context_t *enc_ctx, bool verbose, dirac_encoder_t *encoder)
871 {
872     TEST (enc_ctx != NULL);
873     TEST (encoder != NULL);
874 
875     if (enc_ctx->src_params.width == 0 || enc_ctx->src_params.height == 0)
876         return false;
877 
878     if (enc_ctx->src_params.chroma < format444 ||
879             enc_ctx->src_params.chroma >= formatNK)
880         return false;
881 
882     if (!enc_ctx->src_params.frame_rate.numerator ||
883             !enc_ctx->src_params.frame_rate.denominator)
884         return false;
885 
886     memmove (&encoder->enc_ctx, enc_ctx, sizeof(dirac_encoder_context_t));
887 
888     encoder->dec_buf.id = 0;
889 
890     switch ( enc_ctx->src_params.chroma )
891     {
892     case format420:
893          encoder->enc_ctx.src_params.chroma_width = enc_ctx->src_params.width/2;
894          encoder->enc_ctx.src_params.chroma_height = enc_ctx->src_params.height/2;
895          break;
896     case format422:
897          encoder->enc_ctx.src_params.chroma_width = enc_ctx->src_params.width/2;
898          encoder->enc_ctx.src_params.chroma_height = enc_ctx->src_params.height;
899          break;
900     case format444:
901     default:
902          encoder->enc_ctx.src_params.chroma_width = enc_ctx->src_params.width;
903          encoder->enc_ctx.src_params.chroma_height = enc_ctx->src_params.height;
904          break;
905     }
906 
907     try
908     {
909         DiracEncoder *comp = new DiracEncoder (&encoder->enc_ctx, verbose);
910 
911         encoder->compressor = comp;
912         if (encoder->enc_ctx.decode_flag)
913         {
914             int bufsize = (encoder->enc_ctx.src_params.width * encoder->enc_ctx.src_params.height)+ 2*(encoder->enc_ctx.src_params.chroma_width*encoder->enc_ctx.src_params.chroma_height);
915             encoder->dec_buf.buf[0] = new unsigned char [bufsize];
916             encoder->dec_buf.buf[1] = encoder->dec_buf.buf[0] +
917                 (encoder->enc_ctx.src_params.width * encoder->enc_ctx.src_params.height);
918             encoder->dec_buf.buf[2] = encoder->dec_buf.buf[1] +
919                 (encoder->enc_ctx.src_params.chroma_width*encoder->enc_ctx.src_params.chroma_height);
920 
921             comp->SetDecodeBuffer (encoder->dec_buf.buf[0], bufsize);
922         }
923     }
924     catch (...)
925     {
926         return false;
927     }
928     return true;
929 }
930 
SetSourceParameters(dirac_encoder_context_t * enc_ctx,const VideoFormat & video_format)931 static void SetSourceParameters(dirac_encoder_context_t *enc_ctx,
932                                   const VideoFormat& video_format)
933 {
934     TEST (enc_ctx != NULL);
935     dirac_sourceparams_t &src_params = enc_ctx->src_params;
936 
937     // create object containing sequence params
938     SourceParams default_src_params(video_format);
939 
940     src_params.height = default_src_params.Yl();
941     src_params.width = default_src_params.Xl();
942     src_params.chroma_height = default_src_params.ChromaHeight();
943     src_params.chroma_width = default_src_params.ChromaWidth();
944     src_params.chroma = default_src_params.CFormat();
945     src_params.frame_rate.numerator = default_src_params.FrameRate().m_num;
946     src_params.frame_rate.denominator = default_src_params.FrameRate().m_denom;
947     src_params.pix_asr.numerator = default_src_params.PixelAspectRatio().m_num;
948     src_params.pix_asr.denominator = default_src_params.PixelAspectRatio().m_denom;
949     src_params.source_sampling = default_src_params.SourceSampling();
950     src_params.topfieldfirst = default_src_params.TopFieldFirst();
951 
952     //TODO - Need to accept these params from command line
953     //Set clean area
954     //Set signal range
955     //Set colour specification
956 }
957 
SetEncoderParameters(dirac_encoder_context_t * enc_ctx,const VideoFormat & video_format)958 static void SetEncoderParameters(dirac_encoder_context_t *enc_ctx,
959                                  const VideoFormat& video_format)
960 {
961     TEST (enc_ctx != NULL);
962     dirac_encparams_t &encparams = enc_ctx->enc_params;
963 
964     encparams.video_format = static_cast<int>(video_format);
965     // set encoder defaults
966     EncoderParams default_enc_params(video_format);
967 
968     encparams.qf = default_enc_params.Qf();
969     encparams.cpd = default_enc_params.CPD();
970     encparams.prefilter = default_enc_params.Prefilter();
971     encparams.prefilter_strength = default_enc_params.PrefilterStrength();
972     encparams.L1_sep = default_enc_params.L1Sep();
973     encparams.lossless = default_enc_params.Lossless();
974     encparams.using_ac = default_enc_params.UsingAC();
975     encparams.num_L1 = default_enc_params.NumL1();
976 
977     // Set rate to zero by default, meaning no rate control
978     encparams.trate = 0;
979 
980     // set default block params
981     OLBParams default_block_params;
982     SetDefaultBlockParameters(default_block_params, video_format);
983     encparams.xblen = default_block_params.Xblen();
984     encparams.yblen = default_block_params.Yblen();
985     encparams.xbsep = default_block_params.Xbsep();
986     encparams.ybsep = default_block_params.Ybsep();
987 
988     // set default MV parameters
989     encparams.mv_precision = default_enc_params.GetPicPredParams().MVPrecision();
990 
991     // by default, use hierarchical, not full search
992     encparams.full_search = 0;
993     encparams.x_range_me = 32;
994     encparams.y_range_me = 32;
995 
996     // by default, don't use combined component motion estimation
997     encparams.combined_me = 0;
998 
999     // set default transform parameters
1000     WltFilter wf;
1001     SetDefaultTransformFilter(INTRA_PICTURE, video_format, wf);
1002     encparams.intra_wlt_filter = wf;
1003     SetDefaultTransformFilter(INTER_PICTURE, video_format, wf);
1004     encparams.inter_wlt_filter = wf;
1005     encparams.wlt_depth = default_enc_params.TransformDepth();
1006     encparams.spatial_partition = default_enc_params.SpatialPartition();
1007     encparams.multi_quants = default_enc_params.GetCodeBlockMode() == QUANT_MULTIPLE;
1008 
1009     encparams.picture_coding_mode = default_enc_params.FieldCoding() ? 1 : 0;
1010 }
1011 
1012 #ifdef __cplusplus
1013 extern "C" {
1014 #endif
1015 
dirac_encoder_context_init(dirac_encoder_context_t * enc_ctx,dirac_encoder_presets_t preset)1016 extern DllExport void dirac_encoder_context_init ( dirac_encoder_context_t *enc_ctx, dirac_encoder_presets_t preset)
1017 {
1018     TEST (enc_ctx != NULL);
1019     memset (enc_ctx, 0, sizeof(dirac_encoder_context_t));
1020 
1021     // preset is the video format
1022     int ps = static_cast<int>(preset);
1023     VideoFormat video_format(static_cast<VideoFormat>(ps));
1024     SetSourceParameters (enc_ctx, video_format);
1025     SetEncoderParameters (enc_ctx, video_format);
1026 }
1027 
dirac_encoder_init(const dirac_encoder_context_t * enc_ctx,int verbose)1028 extern DllExport dirac_encoder_t *dirac_encoder_init (const dirac_encoder_context_t *enc_ctx, int verbose)
1029 {
1030     /* Allocate for encoder */
1031     dirac_encoder_t *encoder = new dirac_encoder_t;
1032 
1033     memset (encoder, 0, sizeof(dirac_encoder_t));
1034     /* initialse the encoder context */
1035     if (!InitialiseEncoder(enc_ctx, verbose>0, encoder))
1036     {
1037         delete encoder;
1038         return NULL;
1039     }
1040 
1041     encoder->encoded_picture_avail = encoder->decoded_frame_avail = 0;
1042     encoder->instr_data_avail = 0;
1043 
1044     return encoder;
1045 }
1046 
1047 #if DIRAC_RESEARCH_VERSION_ATLEAST(1,0,2)
dirac_encoder_pts_offset(const dirac_encoder_t * encoder)1048 extern DllExport int dirac_encoder_pts_offset (const dirac_encoder_t *encoder)
1049 {
1050     TEST (encoder != NULL);
1051     TEST (encoder->compressor != NULL);
1052     DiracEncoder *compressor = (DiracEncoder *)encoder->compressor;
1053     int ret;
1054     try
1055     {
1056         ret = compressor->GetPTSOffset();
1057     }
1058     catch (...)
1059     {
1060         ret = -1;
1061     }
1062 
1063     return ret;
1064 }
1065 #endif
1066 
dirac_encoder_load(dirac_encoder_t * encoder,unsigned char * uncdata,int uncdata_size)1067 extern DllExport int dirac_encoder_load (dirac_encoder_t *encoder, unsigned char *uncdata, int uncdata_size)
1068 {
1069     TEST (encoder != NULL);
1070     TEST (encoder->compressor != NULL);
1071     DiracEncoder *compressor = (DiracEncoder *)encoder->compressor;
1072     int ret_stat = 0;
1073     try
1074     {
1075         if ( compressor->LoadNextFrame (uncdata, uncdata_size))
1076         {
1077             ret_stat = uncdata_size;
1078         }
1079     }
1080     catch (...)
1081     {
1082         if (compressor->GetEncParams().Verbose())
1083             std::cerr << "dirac_encoder_load failed" << std::endl;
1084         ret_stat = -1;
1085     }
1086     return ret_stat;
1087 }
1088 
1089 extern DllExport dirac_encoder_state_t
dirac_encoder_output(dirac_encoder_t * encoder)1090       dirac_encoder_output (dirac_encoder_t *encoder)
1091 {
1092     TEST (encoder != NULL);
1093     TEST (encoder->compressor != NULL);
1094     TEST (encoder->enc_buf.size != 0);
1095     TEST (encoder->enc_buf.buffer != NULL);
1096     DiracEncoder *compressor = (DiracEncoder *)encoder->compressor;
1097     dirac_encoder_state_t ret_stat = ENC_STATE_BUFFER;
1098 
1099     encoder->encoded_picture_avail = 0;
1100     encoder->decoded_frame_avail = 0;
1101     encoder->instr_data_avail = 0;
1102 
1103     try
1104     {
1105         // Get the next compressed picture
1106         if (compressor->CompressNextPicture() != 0)
1107         {
1108             if (compressor->GetEncodedData (encoder) < 0)
1109                 ret_stat = ENC_STATE_INVALID;
1110             else
1111             {
1112                 if (encoder->enc_buf.size > 0)
1113                 {
1114                     ret_stat = ENC_STATE_AVAIL;
1115                 }
1116 
1117             }
1118         }
1119         else
1120         {
1121             // check if EOS has been signalled by the user app
1122             if (compressor->EOS())
1123             {
1124                 compressor->GetSequenceEnd (encoder);
1125                 encoder->end_of_sequence = 1;
1126                 encoder->enc_pparams.pnum = -1;
1127                 ret_stat = ENC_STATE_EOS;
1128             }
1129         }
1130         if (encoder->enc_ctx.decode_flag)
1131             compressor->GetDecodedData(encoder);
1132     }
1133     catch (...)
1134     {
1135         if (compressor->GetEncParams().Verbose())
1136             std::cerr << "GetEncodedData failed..." << std::endl;
1137 
1138         ret_stat = ENC_STATE_INVALID;
1139     }
1140     return ret_stat;
1141 }
1142 
dirac_encoder_end_sequence(dirac_encoder_t * encoder)1143 extern DllExport void dirac_encoder_end_sequence (dirac_encoder_t *encoder)
1144 {
1145     TEST (encoder != NULL);
1146     TEST (encoder->compressor != NULL);
1147     DiracEncoder *compressor = (DiracEncoder *)encoder->compressor;
1148 
1149     encoder->encoded_picture_avail = 0;
1150     encoder->decoded_frame_avail = 0;
1151     encoder->instr_data_avail = 0;
1152 
1153     compressor->SignalEOS();
1154 
1155 }
1156 
dirac_encoder_close(dirac_encoder_t * encoder)1157 extern DllExport void dirac_encoder_close (dirac_encoder_t *encoder)
1158 {
1159     TEST (encoder != NULL);
1160     TEST (encoder->compressor != NULL);
1161 
1162     delete (DiracEncoder *)(encoder->compressor);
1163 
1164     if (encoder->enc_ctx.instr_flag)
1165     {
1166         dealloc_instr_data(&encoder->instr);
1167     }
1168 
1169     if (encoder->enc_ctx.decode_flag)
1170     {
1171         delete [] encoder->dec_buf.buf[0];
1172     }
1173     delete encoder;
1174 }
1175 
1176 
1177 #ifdef __cplusplus
1178 }
1179 #endif
1180