1 /* ***** BEGIN LICENSE BLOCK *****
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
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/
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.
16 * The Original Code is BBC Research and Development code.
18 * The Initial Developer of the Original Code is the British Broadcasting
20 * Portions created by the Initial Developer are Copyright (C) 2004.
21 * All Rights Reserved.
23 * Contributor(s): Anuradha Suraparaju (Original Author),
26 * Myo Tun (Brunel University)
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
39 * ***** END LICENSE BLOCK ***** */
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>
56 using namespace dirac
;
59 template <class T
, class S
>
60 void copy_2dArray (const TwoDArray
<T
> & in
, S
*out
)
62 for (int j
=0 ; j
<in
.LengthY() ; ++j
)
64 for (int i
=0 ; i
<in
.LengthX() ; ++i
)
66 // out[j*in.LengthX() + i] = in[j][i];
67 *out
++ = S( in
[j
][i
] );
72 void copy_2dArray (const TwoDArray
<PredMode
> & in
, int *out
)
74 for (int j
=0 ; j
<in
.LengthY() ; ++j
)
76 for (int i
=0 ; i
<in
.LengthX() ; ++i
)
78 // out[j*in.LengthX() + i] = in[j][i];
84 void copy_2dArray (const TwoDArray
<bool> & in
, int *out
)
86 for (int j
=0 ; j
<in
.LengthY() ; ++j
)
88 for (int i
=0 ; i
<in
.LengthX() ; ++i
)
90 // out[j*in.LengthX() + i] = in[j][i];
96 void copy_mv ( const MvArray
& mv
, dirac_mv_t
*dmv
)
98 for (int j
=0 ; j
<mv
.LengthY() ; ++j
)
100 for (int i
=0 ; i
<mv
.LengthX() ; ++i
)
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
;
111 void copy_mv_cost (const TwoDArray
<MvCostData
> &pc
, dirac_mv_cost_t
*dpc
)
113 for (int j
=0 ; j
<pc
.LengthY() ; ++j
)
115 for (int i
=0 ; i
<pc
.LengthX() ; ++i
)
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
;
127 Function that allocates the locally managed instrumentation data
129 void alloc_instr_data(dirac_instr_t
*instr
)
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
155 for (int i
= 0; i
< 2; i
++)
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
);
162 for (int i
= 0; i
< 2; i
++)
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
);
171 Function that frees the locally managed instrumentation data
173 void dealloc_instr_data(dirac_instr_t
*instr
)
175 if (instr
->sb_split_mode
)
176 delete [] instr
->sb_split_mode
;
179 delete [] instr
->sb_costs
;
181 if (instr
->pred_mode
)
182 delete [] instr
->pred_mode
;
184 if (instr
->intra_costs
)
185 delete [] instr
->intra_costs
;
187 if (instr
->bipred_costs
)
188 delete [] instr
->bipred_costs
;
191 delete [] instr
->dc_ycomp
;
194 delete [] instr
->dc_ucomp
;
197 delete [] instr
->dc_vcomp
;
199 for (int i
= 0; i
< 2; i
++)
202 delete [] instr
->mv
[i
];
204 for (int i
= 0; i
< 2; i
++)
206 if (instr
->pred_costs
[i
])
207 delete [] instr
->pred_costs
[i
];
212 Wrapper class around the SequenceCompressor Class. This class is used
213 by the "C" encoder interface
219 DiracEncoder(const dirac_encoder_context_t
*enc_ctx
, bool verbose
);
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();
228 // Set the encode frame in encoder to the encoded frame data
229 int GetEncodedData(dirac_encoder_t
*encoder
);
231 // Set the locally decoded frame data in encoder
232 int GetDecodedData (dirac_encoder_t
*encoder
);
234 // Set the instrumentation data in encoder
235 void GetInstrumentationData (dirac_encoder_t
*encoder
);
237 // Set the end of sequence infomration in encoder
238 int GetSequenceEnd(dirac_encoder_t
*encoder
);
240 // Set the buffer to hold the locally decoded frame
241 void SetDecodeBuffer (unsigned char *buffer
, int buffer_size
);
243 // Return the encoder parameters
244 const EncoderParams
& GetEncParams() const { return m_encparams
; }
246 // Return the source parameters
247 const SourceParams
& GetSrcParams() const { return m_srcparams
; }
249 // Return the pts offset
250 int GetPTSOffset() const { return m_seqcomp
->PTSOffset(); }
252 // Signal End of Sequence
253 void SignalEOS() { m_eos_signalled
= true; m_seqcomp
->SignalEOS(); }
256 bool EOS() { return m_eos_signalled
== true; }
260 // Set the encoder parameters
261 void SetEncoderParams (const dirac_encoder_context_t
*enc_ctx
);
263 // Set the source parameters
264 void SetSourceParams (const dirac_encoder_context_t
*enc_ctx
);
266 // Get the picture statistics
267 void GetPictureStats(dirac_encoder_t
*encoder
);
269 // Get the seuqence statistics
270 void GetSequenceStats(dirac_encoder_t
*encoder
,
271 const DiracByteStats
& dirac_seq_stats
);
274 // sequence compressor
275 SequenceCompressor
*m_seqcomp
;
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
286 //locally decoded picture type
287 PictureSort m_decpsort
;
288 // locally decoded picture number in display order
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
;
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
304 // Flag that determines if locally decoded pictures are to be returned. Set
306 bool m_return_decoded_pictures
;
307 // Flag that determines if instrumentation data is to be returned. Set
309 bool m_return_instr_data
;
311 // Output destination for compressed data in bitstream format
312 DiracByteStream m_dirac_byte_stream
;
314 //Rate Control parameters
315 // Total Number of bits for a GOP
318 // Total Number GOPs in the input sequence
321 // To count the number of pictures for calculating the GOP bit rate
324 // field 1 stats if interlaced
325 dirac_enc_picstats_t m_field1_stats
;
327 // End of sequence flag. Set to true when user app signals end of
329 bool m_eos_signalled
;
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
338 void DiracEncoder::GetInstrumentationData (dirac_encoder_t
*encoder
)
340 ASSERT (encoder
!= NULL
);
341 dirac_instr_t
*instr
= &encoder
->instr
;
342 dirac_instr_t old_instr
= *instr
;
344 if (!m_return_instr_data
|| m_enc_picture
== NULL
)
347 const PictureParams
& pparams
= m_enc_picture
->GetPparams();
348 const PictureSort psort
= pparams
.PicSort();
350 instr
->pnum
= pparams
.PictureNum();
351 instr
->ptype
= psort
.IsIntra() ? INTRA_PICTURE
: INTER_PICTURE
;
352 instr
->rtype
= psort
.IsRef() ? REFERENCE_PICTURE
: NON_REFERENCE_PICTURE
;
354 encoder
->instr_data_avail
= 1;
358 // no MV data for Intra coded data
362 TESTM (m_enc_medata
!= NULL
, "ME data available");
365 instr
->num_refs
= pparams
.Refs().size();
366 ASSERTM (instr
->num_refs
<= 2, "Max # reference frames is 2");
368 for (int i
=0; i
<instr
->num_refs
; ++i
)
369 instr
->refs
[i
] = pparams
.Refs()[i
];
371 // Block separation params
372 instr
->ybsep
= m_encparams
.GetPicPredParams().LumaBParams(2).Ybsep();
373 instr
->xbsep
= m_encparams
.GetPicPredParams().LumaBParams(2).Xbsep();
376 instr
->sb_ylen
= m_enc_medata
->SBSplit().LengthY();
377 instr
->sb_xlen
= m_enc_medata
->SBSplit().LengthX();
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();
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
)
388 dealloc_instr_data(instr
);
389 alloc_instr_data(instr
);
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
);
397 if (instr
->num_refs
> 1)
399 copy_mv_cost (m_enc_medata
->BiPredCosts(), instr
->bipred_costs
);
402 copy_2dArray (m_enc_medata
->DC( Y_COMP
), instr
->dc_ycomp
);
403 if (m_enc_medata
->DC().Length() == 3)
405 copy_2dArray (m_enc_medata
->DC( U_COMP
), instr
->dc_ucomp
);
406 copy_2dArray (m_enc_medata
->DC( V_COMP
), instr
->dc_vcomp
);
409 for (int i
=1; i
<=instr
->num_refs
; ++i
)
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]);
416 DiracEncoder::DiracEncoder(const dirac_encoder_context_t
*enc_ctx
,
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),
421 m_num_loaded_pictures(0),
422 m_num_coded_pictures(0),
426 m_return_decoded_pictures(enc_ctx
->decode_flag
> 0),
427 m_return_instr_data(enc_ctx
->instr_flag
> 0),
431 m_eos_signalled(false)
433 // Setup source parameters
434 SetSourceParams (enc_ctx
);
435 // Setup encoder parameters
436 m_encparams
.SetVerbose( verbose
);
437 SetEncoderParams (enc_ctx
);
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());
444 // initialise the sequence compressor
445 if (!m_encparams
.FieldCoding())
447 m_seqcomp
= new FrameSequenceCompressor (m_inp_ptr
->GetStream(), m_encparams
, m_dirac_byte_stream
);
451 m_seqcomp
= new FieldSequenceCompressor (m_inp_ptr
->GetStream(), m_encparams
, m_dirac_byte_stream
);
455 void DiracEncoder::SetDecodeBuffer (unsigned char *buffer
, int buffer_size
)
458 m_dec_bufsize
= buffer_size
;
459 m_return_decoded_pictures
= true;
462 DiracEncoder::~DiracEncoder()
469 void DiracEncoder::SetSourceParams (const dirac_encoder_context_t
*enc_ctx
)
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
);
475 m_srcparams
.SetCleanWidth( m_srcparams
.Xl() );
476 m_srcparams
.SetCleanHeight( m_srcparams
.Yl() );
477 m_srcparams
.SetLeftOffset( 0 );
478 m_srcparams
.SetTopOffset( 0 );
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
)
484 m_srcparams
.SetFrameRate( enc_ctx
->src_params
.frame_rate
.numerator
,
485 enc_ctx
->src_params
.frame_rate
.denominator
);
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
)
490 m_srcparams
.SetPixelAspectRatio( enc_ctx
->src_params
.pix_asr
.numerator
,
491 enc_ctx
->src_params
.pix_asr
.denominator
);
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
);
500 void DiracEncoder::SetEncoderParams (const dirac_encoder_context_t
*enc_ctx
)
502 TEST (enc_ctx
!= NULL
);
503 OLBParams
bparams(12, 12, 8, 8);
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
);
511 if (enc_ctx
->enc_params
.picture_coding_mode
> 1)
513 std::ostringstream errstr
;
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
,
524 m_encparams
.SetPictureCodingMode(enc_ctx
->enc_params
.picture_coding_mode
);
525 if (m_encparams
.FieldCoding())
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);
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
);
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
);
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
);
561 // Now rationalise the GOP options
562 // this stuff should really be done in a constructor!
563 if (m_encparams
.NumL1()<0)
565 //don't have a proper GOP
566 m_encparams
.SetL1Sep( std::max(1 , m_encparams
.L1Sep()) );
568 else if (m_encparams
.NumL1() == 0)
570 //have I-frame only coding
571 m_encparams
.SetL1Sep(0);
573 m_encparams
.GetPicPredParams().SetBlockSizes( bparams
, enc_ctx
->src_params
.chroma
);
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
);
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
);
585 bool DiracEncoder::LoadNextFrame (unsigned char *data
, int size
)
587 TESTM (m_seqcomp
->Finished() != true, "Did not reach end of sequence");
588 m_inp_ptr
->SetMembufReference(data
, size
);
589 if (m_seqcomp
->LoadNextFrame())
591 if (!m_encparams
.FieldCoding())
592 m_num_loaded_pictures
++;
594 m_num_loaded_pictures
+=2;
600 int DiracEncoder::CompressNextPicture ()
602 TESTM (m_seqcomp
->Finished() != true, "Did not reach end of sequence");
604 if (!m_num_loaded_pictures
)
607 const EncPicture
*mypicture
= m_seqcomp
->CompressNextPicture();
612 m_enc_picture
= m_seqcomp
->GetPictureEncoded();
613 if (m_enc_picture
->GetPparams().PicSort().IsIntra()==false)
614 m_enc_medata
= &m_enc_picture
->GetMEData();
618 if (m_return_decoded_pictures
&&
619 mypicture
->GetPparams().PictureNum() != m_show_pnum
){
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
)
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
);
631 m_decpnum
= m_show_pnum
;
632 m_decpsort
= mypicture
->GetPparams().PicSort();
638 m_enc_picture
= NULL
;
642 if(!m_dirac_byte_stream
.IsUnitAvailable())
646 m_num_coded_pictures
++;
647 TESTM (m_enc_picture
!= 0, "Encoder picture available");
652 void DiracEncoder::GetPictureStats(dirac_encoder_t
*encoder
)
655 dirac_enc_picstats_t
*pstats
= &encoder
->enc_pstats
;
656 DiracByteStats dirac_byte_stats
= m_dirac_byte_stream
.GetLastUnitStats();
658 pstats
->mv_bits
= dirac_byte_stats
.GetBitCount(STAT_MV_BYTE_COUNT
);
659 // pstats->mv_hdr_bits = poutput.MVBytes() * 8;
661 pstats
->ycomp_bits
= dirac_byte_stats
.GetBitCount(STAT_YCOMP_BYTE_COUNT
);
662 // pstats->ycomp_hdr_bits = poutput.ComponentHeadBytes( Y_COMP ) * 8;
664 pstats
->ucomp_bits
= dirac_byte_stats
.GetBitCount(STAT_UCOMP_BYTE_COUNT
);
665 // pstats->ucomp_hdr_bits = poutput.ComponentHeadBytes( U_COMP ) * 8;
667 pstats
->vcomp_bits
= dirac_byte_stats
.GetBitCount(STAT_VCOMP_BYTE_COUNT
);
668 // pstats->vcomp_hdr_bits = poutput.ComponentHeadBytes( V_COMP ) * 8;
670 pstats
->pic_bits
= dirac_byte_stats
.GetBitCount(STAT_TOTAL_BYTE_COUNT
);
671 // pstats->pic_hdr_bits = poutput.PictureHeadBytes() * 8;
673 DiracEncoder
*compressor
= (DiracEncoder
*)encoder
->compressor
;
674 if (compressor
->GetEncParams().Verbose())
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
;
683 std::cout
<<std::endl
<<"Total frame bits="<<pstats
->pic_bits
;
687 int DiracEncoder::GetEncodedData (dirac_encoder_t
*encoder
)
690 dirac_enc_data_t
*encdata
= &encoder
->enc_buf
;
692 string output
= m_dirac_byte_stream
.GetBytes();
693 size
= output
.size();
694 //std::cout << std::endl << "ParseUnit size=" << size << std::endl;
697 if (encdata
->size
< size
)
701 memmove (encdata
->buffer
, output
.c_str(), output
.size());
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
;
709 // Get frame statistics
710 GetPictureStats (encoder
);
711 if(m_encparams
.Verbose() && encoder
->enc_ctx
.enc_params
.picture_coding_mode
==1)
713 if (encoder
->enc_pparams
.pnum
%2 == 0)
714 m_field1_stats
= encoder
->enc_pstats
;
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
;
736 encoder
->enc_pparams
.pnum
= -1;
738 encdata
->size
= size
;
740 GetInstrumentationData(encoder
);
741 encoder
->encoded_picture_avail
= 1;
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
;
756 // Length of the GOP in pictures - twice as many if fields
757 int GOP_pic_length
= (num_L1
+1)*L1_sep
*interlace_factor
;
766 offset
= std::max(L1_sep
-1,0)*interlace_factor
;
768 m_gop_bits
+= encoder
->enc_pstats
.pic_bits
;
771 if ( (m_gop_count
==0 && m_picture_count
== GOP_pic_length
-offset
) ||
772 (m_gop_count
>0 && m_picture_count
== GOP_pic_length
))
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
;
778 double gop_duration
= double(m_picture_count
)/interlace_factor
/frame_rate
;
779 double bit_rate
= double(m_gop_bits
)/gop_duration
;
781 DiracEncoder
*compressor
= (DiracEncoder
*)encoder
->compressor
;
782 if (compressor
->GetEncParams().Verbose())
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
;
792 //End of Rate Control
795 m_dirac_byte_stream
.Clear();
800 int DiracEncoder::GetDecodedData (dirac_encoder_t
*encoder
)
802 dirac_picparams_t
*pp
= &encoder
->dec_pparams
;
804 int ret_stat
= (m_decpnum
!= -1);
805 if (m_return_decoded_pictures
&& m_decpnum
!= -1)
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;
816 void DiracEncoder::GetSequenceStats(dirac_encoder_t
*encoder
,
817 const DiracByteStats
& dirac_seq_stats
)
819 dirac_enc_seqstats_t
*sstats
= &encoder
->enc_seqstats
;
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
);
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;
833 DiracEncoder
*compressor
= (DiracEncoder
*)encoder
->compressor
;
834 if (compressor
->GetEncParams().Verbose())
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.";
845 int DiracEncoder::GetSequenceEnd (dirac_encoder_t
*encoder
)
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();
853 if (encdata
->size
< size
)
857 memmove (encdata
->buffer
, output
.c_str(), size
);
858 GetSequenceStats(encoder
,
860 encdata
->size
= size
;
866 m_dirac_byte_stream
.Clear();
870 static bool InitialiseEncoder (const dirac_encoder_context_t
*enc_ctx
, bool verbose
, dirac_encoder_t
*encoder
)
872 TEST (enc_ctx
!= NULL
);
873 TEST (encoder
!= NULL
);
875 if (enc_ctx
->src_params
.width
== 0 || enc_ctx
->src_params
.height
== 0)
878 if (enc_ctx
->src_params
.chroma
< format444
||
879 enc_ctx
->src_params
.chroma
>= formatNK
)
882 if (!enc_ctx
->src_params
.frame_rate
.numerator
||
883 !enc_ctx
->src_params
.frame_rate
.denominator
)
886 memmove (&encoder
->enc_ctx
, enc_ctx
, sizeof(dirac_encoder_context_t
));
888 encoder
->dec_buf
.id
= 0;
890 switch ( enc_ctx
->src_params
.chroma
)
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;
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
;
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
;
909 DiracEncoder
*comp
= new DiracEncoder (&encoder
->enc_ctx
, verbose
);
911 encoder
->compressor
= comp
;
912 if (encoder
->enc_ctx
.decode_flag
)
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
);
921 comp
->SetDecodeBuffer (encoder
->dec_buf
.buf
[0], bufsize
);
931 static void SetSourceParameters(dirac_encoder_context_t
*enc_ctx
,
932 const VideoFormat
& video_format
)
934 TEST (enc_ctx
!= NULL
);
935 dirac_sourceparams_t
&src_params
= enc_ctx
->src_params
;
937 // create object containing sequence params
938 SourceParams
default_src_params(video_format
);
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();
952 //TODO - Need to accept these params from command line
955 //Set colour specification
958 static void SetEncoderParameters(dirac_encoder_context_t
*enc_ctx
,
959 const VideoFormat
& video_format
)
961 TEST (enc_ctx
!= NULL
);
962 dirac_encparams_t
&encparams
= enc_ctx
->enc_params
;
964 encparams
.video_format
= static_cast<int>(video_format
);
965 // set encoder defaults
966 EncoderParams
default_enc_params(video_format
);
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();
977 // Set rate to zero by default, meaning no rate control
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();
988 // set default MV parameters
989 encparams
.mv_precision
= default_enc_params
.GetPicPredParams().MVPrecision();
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;
996 // by default, don't use combined component motion estimation
997 encparams
.combined_me
= 0;
999 // set default transform parameters
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
;
1009 encparams
.picture_coding_mode
= default_enc_params
.FieldCoding() ? 1 : 0;
1016 extern DllExport
void dirac_encoder_context_init ( dirac_encoder_context_t
*enc_ctx
, dirac_encoder_presets_t preset
)
1018 TEST (enc_ctx
!= NULL
);
1019 memset (enc_ctx
, 0, sizeof(dirac_encoder_context_t
));
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
);
1028 extern DllExport dirac_encoder_t
*dirac_encoder_init (const dirac_encoder_context_t
*enc_ctx
, int verbose
)
1030 /* Allocate for encoder */
1031 dirac_encoder_t
*encoder
= new dirac_encoder_t
;
1033 memset (encoder
, 0, sizeof(dirac_encoder_t
));
1034 /* initialse the encoder context */
1035 if (!InitialiseEncoder(enc_ctx
, verbose
>0, encoder
))
1041 encoder
->encoded_picture_avail
= encoder
->decoded_frame_avail
= 0;
1042 encoder
->instr_data_avail
= 0;
1047 #if DIRAC_RESEARCH_VERSION_ATLEAST(1,0,2)
1048 extern DllExport
int dirac_encoder_pts_offset (const dirac_encoder_t
*encoder
)
1050 TEST (encoder
!= NULL
);
1051 TEST (encoder
->compressor
!= NULL
);
1052 DiracEncoder
*compressor
= (DiracEncoder
*)encoder
->compressor
;
1056 ret
= compressor
->GetPTSOffset();
1067 extern DllExport
int dirac_encoder_load (dirac_encoder_t
*encoder
, unsigned char *uncdata
, int uncdata_size
)
1069 TEST (encoder
!= NULL
);
1070 TEST (encoder
->compressor
!= NULL
);
1071 DiracEncoder
*compressor
= (DiracEncoder
*)encoder
->compressor
;
1075 if ( compressor
->LoadNextFrame (uncdata
, uncdata_size
))
1077 ret_stat
= uncdata_size
;
1082 if (compressor
->GetEncParams().Verbose())
1083 std::cerr
<< "dirac_encoder_load failed" << std::endl
;
1089 extern DllExport dirac_encoder_state_t
1090 dirac_encoder_output (dirac_encoder_t
*encoder
)
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
;
1099 encoder
->encoded_picture_avail
= 0;
1100 encoder
->decoded_frame_avail
= 0;
1101 encoder
->instr_data_avail
= 0;
1105 // Get the next compressed picture
1106 if (compressor
->CompressNextPicture() != 0)
1108 if (compressor
->GetEncodedData (encoder
) < 0)
1109 ret_stat
= ENC_STATE_INVALID
;
1112 if (encoder
->enc_buf
.size
> 0)
1114 ret_stat
= ENC_STATE_AVAIL
;
1121 // check if EOS has been signalled by the user app
1122 if (compressor
->EOS())
1124 compressor
->GetSequenceEnd (encoder
);
1125 encoder
->end_of_sequence
= 1;
1126 encoder
->enc_pparams
.pnum
= -1;
1127 ret_stat
= ENC_STATE_EOS
;
1130 if (encoder
->enc_ctx
.decode_flag
)
1131 compressor
->GetDecodedData(encoder
);
1135 if (compressor
->GetEncParams().Verbose())
1136 std::cerr
<< "GetEncodedData failed..." << std::endl
;
1138 ret_stat
= ENC_STATE_INVALID
;
1143 extern DllExport
void dirac_encoder_end_sequence (dirac_encoder_t
*encoder
)
1145 TEST (encoder
!= NULL
);
1146 TEST (encoder
->compressor
!= NULL
);
1147 DiracEncoder
*compressor
= (DiracEncoder
*)encoder
->compressor
;
1149 encoder
->encoded_picture_avail
= 0;
1150 encoder
->decoded_frame_avail
= 0;
1151 encoder
->instr_data_avail
= 0;
1153 compressor
->SignalEOS();
1157 extern DllExport
void dirac_encoder_close (dirac_encoder_t
*encoder
)
1159 TEST (encoder
!= NULL
);
1160 TEST (encoder
->compressor
!= NULL
);
1162 delete (DiracEncoder
*)(encoder
->compressor
);
1164 if (encoder
->enc_ctx
.instr_flag
)
1166 dealloc_instr_data(&encoder
->instr
);
1169 if (encoder
->enc_ctx
.decode_flag
)
1171 delete [] encoder
->dec_buf
.buf
[0];