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