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 code.
18 * The Initial Developer of the Original Code is the British Broadcasting
20 * Portions created by the Initial Developer are Copyright (C) 2007.
21 * All Rights Reserved.
23 * Contributor(s): Andrea Gabriellini (Original Author)
25 * Alternatively, the contents of this file may be used under the terms of
26 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
27 * Public License Version 2.1 (the "LGPL"), in which case the provisions of
28 * the GPL or the LGPL are applicable instead of those above. If you wish to
29 * allow use of your version of this file only under the terms of the either
30 * the GPL or LGPL and not to allow others to use your version of this file
31 * under the MPL, indicate your decision by deleting the provisions above
32 * and replace them with the notice and other provisions required by the GPL
33 * or LGPL. If you do not delete the provisions above, a recipient may use
34 * your version of this file under the terms of any one of the MPL, the GPL
36 * ***** END LICENSE BLOCK ***** */
44 #include <decoder/Diracdec.hpp>
45 #include <decoder/DiracState.hpp>
48 using namespace ::dirac::decoder
;
49 using ::dirac::parser_project::AccessUnit
;
51 Diracdec::Diracdec ( IDecoder::ParserAutoPtr parser
52 , IDecoder::FrameManagerAutoPtr manager
)
53 : IDecoder ( parser
, manager
), numberOfDecodedFrames_ ( 0 )
54 , canPushBits_ ( true ), eos_ ( false )
56 yuv_
[0] = yuv_
[1] = yuv_
[2] = static_cast<pointer
> ( 0 );
58 fetchSequenceHeader();
70 const int VERBOSE_MODE
= 0; // set to 1 if you wish to log messages to stdout
71 DecoderSharedPtr
tmp ( dirac_decoder_init ( VERBOSE_MODE
)
72 , dirac_decoder_close
);
74 throw DecoderException ( "failed to create dirac decoder" );
76 decoder_
.swap ( tmp
);
80 Diracdec::fetchSequenceHeader()
83 if ( !parser_
->getNextSequenceHeader ( au
) || au
.empty() ) {
84 throw DecoderException ( "Dirac decoder: failed to parser sequence header" );
86 dirac_buffer ( decoder_
.get(), const_cast<AU::pointer
> ( au
.begin() )
87 , const_cast<AU::pointer
> ( au
.end() ) );
88 if ( !parser_
->moveCursorFwd() ) {
89 throw DecoderException ( "Dirac decoder: failed to parse access unit" );
91 if ( !parser_
->getNextAccessUnit ( au
) || au
.empty() ) {
92 throw DecoderException ( "Dirac decoder: failed to parse access unit" );
94 dirac_buffer ( decoder_
.get(), const_cast<AU::pointer
> ( au
.begin() )
95 , const_cast<AU::pointer
> ( au
.end() ) );
96 // dirac_buffer ( decoder_.get(), aux, aux + 16 ); // FIXME
97 if ( STATE_SEQUENCE
!= dirac_parse ( decoder_
.get() ) ) {
98 throw DecoderException ( "Dirac decoder: failed to decode sequence header" );
103 Diracdec::resetDecoder()
108 numberOfDecodedFrames_
= 0;
111 fetchSequenceHeader();
115 //! push an access unit into dirac's input buffer
116 //! \r true if successful, false if end of stream
120 DIRAC_MESSAGE_ASSERT ( "parser and decoder cannot be null", 0 != parser_
.get()
121 && 0 != decoder_
.get() );
123 if ( parser_
->getNextAccessUnit ( au
) ) {
124 if ( canPushBits_
) {
125 dirac_buffer ( decoder_
.get(), const_cast<AU::pointer
> ( au
.begin() )
126 , const_cast<AU::pointer
> ( au
.end() ) );
128 if ( au
.isLastEndOfSequence() || !parser_
->moveCursorFwd() ) {
129 if ( !canPushBits_
) eos_
= true;
130 canPushBits_
= false;
134 if ( !canPushBits_
) eos_
= true;
135 else canPushBits_
= false;
142 DIRAC_MESSAGE_ASSERT ( "parser and decoder cannot be null"
143 , 0 != parser_
.get() && 0 != decoder_
.get() );
144 size_type bufferSize
= getFrameBufferSize ( frameWidth(), frameHeight()
147 throw DecoderException ( "failed to create frame buffer" );
148 yuv_
[0] = new value_type
[ bufferSize
];
149 yuv_
[1] = yuv_
[0] + frameWidth() * frameHeight();
150 size_type chromaWidth
= decoder_
->src_params
.chroma_width
,
151 chromaHeight
= decoder_
->src_params
.chroma_height
;
152 yuv_
[2] = yuv_
[1] + chromaWidth
* chromaHeight
;
153 dirac_set_buf ( decoder_
.get(), yuv_
, NULL
);
157 Diracdec::pullFrameAndWrite()
159 DIRAC_MESSAGE_ASSERT ( "decoder and frame manager cannot be null"
160 , 0 != decoder_
.get() && 0 != manager_
.get() );
161 if ( !decoder_
->fbuf
|| !decoder_
->fbuf
->buf
[0] ) {
163 DecoderException ( "Dirac decoder: invalid frame buffer in dirac decoder" );
165 ++numberOfDecodedFrames_
;
170 Diracdec::writeFrame()
172 size_type count
= getFrameBufferSize ( frameWidth(), frameHeight()
174 // this is a safe cast
175 pointer buffer
= const_cast<pointer
> ( manager_
->allocate ( count
) );
176 memcpy(static_cast<void*> ( buffer
), yuv_
[0], count
);
177 manager_
->write ( buffer
, count
);
178 manager_
->release ( buffer
);
182 Diracdec::getFrameWidth() const
184 DIRAC_MESSAGE_ASSERT ( "decoder cannot be null", 0 != decoder_
.get() );
185 return decoder_
->src_params
.width
;
189 Diracdec::getFrameHeight() const
191 DIRAC_MESSAGE_ASSERT ( "decoder cannot be null", 0 != decoder_
.get() );
192 return decoder_
->src_params
.height
;
195 ::dirac::decoder::ChromaFormat
196 Diracdec::getChromaFormat() const
198 DIRAC_MESSAGE_ASSERT ( "decoder cannot be null", 0 != decoder_
.get() );
199 switch ( decoder_
->src_params
.chroma
) {
216 Diracdec::runDecoder()
218 DIRAC_MESSAGE_ASSERT ( "decoder cannot be null", 0 != decoder_
.get() );
220 std::auto_ptr
<IDecoderState
> decoderState
;
222 std::auto_ptr
<IDecoderState
> tmp ( getState() );
224 decoderState
->doNextAction();
225 } while ( !decoderState
->isEndOfSequence() );
229 Diracdec::numberOfFrames() const
231 return numberOfDecodedFrames_
;
235 Diracdec::getDecoderState()
237 DIRAC_MESSAGE_ASSERT ( "decoder cannot be null", 0 != decoder_
.get() );
239 return makeDiracState ( *this, dirac_parse ( decoder_
.get() ) );