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 * Alternatively, the contents of this file may be used under the terms of
27 * the GNU General Public License Version 2 (the "GPL"), or the GNU Lesser
28 * Public License Version 2.1 (the "LGPL"), in which case the provisions of
29 * the GPL or the LGPL are applicable instead of those above. If you wish to
30 * allow use of your version of this file only under the terms of the either
31 * the GPL or LGPL and not to allow others to use your version of this file
32 * under the MPL, indicate your decision by deleting the provisions above
33 * and replace them with the notice and other provisions required by the GPL
34 * or LGPL. If you do not delete the provisions above, a recipient may use
35 * your version of this file under the terms of any one of the MPL, the GPL
37 * ***** END LICENSE BLOCK ***** */
40 #include <libdirac_common/dirac_assertions.h>
41 #include <libdirac_decoder/dirac_cppparser.h>
42 #include <libdirac_decoder/dirac_parser.h>
43 #include <libdirac_common/dirac_exception.h>
44 #include <libdirac_common/picture.h>
45 #if defined (HAVE_MMX)
49 using namespace dirac
;
55 extern DllExport dirac_decoder_t
*dirac_decoder_init(int verbose
)
57 dirac_decoder_t
* decoder
= new dirac_decoder_t
;
58 memset (decoder
, 0, sizeof(dirac_decoder_t
));
60 bool verbosity
= verbose
> 0 ? true : false;
61 DiracParser
*parser
= new DiracParser(verbosity
);
62 decoder
->parser
= static_cast<void *>(parser
);
64 decoder
->fbuf
= new dirac_framebuf_t
;
65 decoder
->fbuf
->id
= NULL
;
66 decoder
->fbuf
->buf
[0] = decoder
->fbuf
->buf
[1] = decoder
->fbuf
->buf
[2] = NULL
;
70 extern DllExport
void dirac_decoder_close(dirac_decoder_t
*decoder
)
72 TEST (decoder
!= NULL
);
73 TEST (decoder
->parser
!= NULL
);
74 DiracParser
*parser
= static_cast<DiracParser
*>(decoder
->parser
);
85 extern DllExport
void dirac_buffer (dirac_decoder_t
*decoder
, unsigned char *start
, unsigned char *end
)
87 TEST (decoder
!= NULL
);
88 TEST (decoder
->parser
!= NULL
);
89 DiracParser
*parser
= static_cast<DiracParser
*>(decoder
->parser
);
91 parser
->SetBuffer((char *)start
, (char *)end
);
94 static void set_sequence_params (const DiracParser
* const parser
, dirac_decoder_t
*decoder
)
96 TEST (parser
!= NULL
);
97 TEST (decoder
!= NULL
);
99 dirac_sourceparams_t
*src_params
= &decoder
->src_params
;
100 dirac_parseparams_t
*parse_params
= &decoder
->parse_params
;
101 const SourceParams
& srcparams
= parser
->GetSourceParams();
102 const ParseParams
& pparams
= parser
->GetParseParams();
104 parse_params
->major_ver
= pparams
.MajorVersion();
105 parse_params
->minor_ver
= pparams
.MinorVersion();
106 parse_params
->profile
= pparams
.Profile();
107 parse_params
->level
= pparams
.Level();
109 src_params
->width
= srcparams
.Xl();
110 src_params
->height
= srcparams
.Yl();
112 src_params
->chroma
= (dirac_chroma_t
)srcparams
.CFormat();
113 src_params
->chroma_width
= srcparams
.ChromaWidth();
114 src_params
->chroma_height
= srcparams
.ChromaHeight();
116 // set the source parmeters
117 src_params
->source_sampling
= srcparams
.SourceSampling();
118 src_params
->topfieldfirst
= srcparams
.TopFieldFirst() ? 1 : 0;
120 src_params
->frame_rate
.numerator
= srcparams
.FrameRate().m_num
;
121 src_params
->frame_rate
.denominator
= srcparams
.FrameRate().m_denom
;
123 src_params
->pix_asr
.numerator
= srcparams
.PixelAspectRatio().m_num
;
124 src_params
->pix_asr
.denominator
= srcparams
.PixelAspectRatio().m_denom
;
127 src_params
->clean_area
.width
= srcparams
.CleanWidth();
128 src_params
->clean_area
.height
= srcparams
.CleanHeight();
129 src_params
->clean_area
.left_offset
= srcparams
.LeftOffset();
130 src_params
->clean_area
.top_offset
= srcparams
.TopOffset();
133 src_params
->signal_range
.luma_offset
= srcparams
.LumaOffset();
134 src_params
->signal_range
.luma_excursion
= srcparams
.LumaExcursion();
135 src_params
->signal_range
.chroma_offset
= srcparams
.ChromaOffset();
136 src_params
->signal_range
.chroma_excursion
= srcparams
.ChromaExcursion();
138 // Colour specfication
139 src_params
->colour_spec
.col_primary
= srcparams
.ColourPrimariesIndex();
140 src_params
->colour_spec
.trans_func
= srcparams
.TransferFunctionIndex();
141 switch(srcparams
.ColourMatrixIndex())
144 src_params
->colour_spec
.col_matrix
.kr
= 0.299f
;
145 src_params
->colour_spec
.col_matrix
.kb
= 0.114f
;
148 src_params
->colour_spec
.col_matrix
.kr
= 0.25f
;
149 src_params
->colour_spec
.col_matrix
.kb
= 0.25f
;
151 case CM_HDTV_COMP_INTERNET
:
153 src_params
->colour_spec
.col_matrix
.kr
= 0.2126f
;
154 src_params
->colour_spec
.col_matrix
.kb
= 0.0722f
;
159 static void set_frame_component (const PicArray
& pic_data
, const CompSort cs
, dirac_decoder_t
*decoder
)
161 TEST (decoder
->fbuf
!= NULL
);
169 xl
= decoder
->src_params
.chroma_width
;
170 yl
= decoder
->src_params
.chroma_height
;
171 buf
= decoder
->fbuf
->buf
[1];
174 xl
= decoder
->src_params
.chroma_width
;
175 yl
= decoder
->src_params
.chroma_height
;
176 buf
= decoder
->fbuf
->buf
[2];
181 xl
= decoder
->src_params
.width
;
182 yl
= decoder
->src_params
.height
;
183 buf
= decoder
->fbuf
->buf
[0];
190 int last_idx
= (xl
>>3)<<3;
191 __m64 tmp
= _mm_set_pi16(128, 128, 128, 128);
192 for (int j
=0 ; j
<yl
;++j
)
194 for (int i
=0 ; i
<last_idx
; i
+=8 )
196 __m64 pic1
= *(__m64
*)&pic_data
[j
][i
];
197 pic1
= _mm_add_pi16 (pic1
, tmp
);
198 __m64 pic2
= *(__m64
*)(&pic_data
[j
][i
+4]);
199 pic2
= _mm_add_pi16 (pic2
, tmp
);
200 __m64
*tmp
= (__m64
*)&buf
[j
*xl
+i
];
201 *tmp
= _mm_packs_pu16 (pic1
, pic2
);
206 // mop up remaining pixels
207 for (int j
=0 ; j
<yl
;++j
)
209 for (int i
=last_idx
; i
<xl
; i
++ )
211 buf
[j
*xl
+i
]=(unsigned char) (pic_data
[j
][i
]+128);
217 for (int j
=0 ; j
<yl
;++j
)
219 for (int i
=0 ; i
<xl
; ++i
)
221 buf
[j
*xl
+i
]=(unsigned char) (pic_data
[j
][i
]+128);
228 static void set_field_component (const PicArray
& pic_data
, const CompSort cs
, dirac_decoder_t
*decoder
, unsigned int pic_num
)
230 TEST (decoder
->fbuf
!= NULL
);
238 xl
= decoder
->src_params
.chroma_width
;
239 yl
= decoder
->src_params
.chroma_height
;
240 buf
= decoder
->fbuf
->buf
[1];
243 xl
= decoder
->src_params
.chroma_width
;
244 yl
= decoder
->src_params
.chroma_height
;
245 buf
= decoder
->fbuf
->buf
[2];
250 xl
= decoder
->src_params
.width
;
251 yl
= decoder
->src_params
.height
;
252 buf
= decoder
->fbuf
->buf
[0];
258 // Seek offset before writing field to store
260 // Seek offset between writing fields to store
264 bool top_field
= decoder
->src_params
.topfieldfirst
? (!(pic_num
%2)) :
267 if (top_field
) // i.e. top field
270 skip
= 2 * xl
* sizeof(char);
272 else // else bottom field
275 skip
= 2 * xl
* sizeof(char);
278 unsigned char *tempc
= buf
+ start
;
280 int field_yl
= yl
>>1;
283 for (int j
=0 ; j
<field_yl
;++j
)
285 for (int i
=0 ; i
<field_xl
; ++i
)
287 tempc
[i
] = (unsigned char) (pic_data
[j
][i
]+128);
293 static void set_frame_data (const DiracParser
* const parser
, dirac_decoder_t
*decoder
)
295 TEST (parser
!= NULL
);
296 TEST (decoder
!= NULL
);
297 TEST (decoder
->fbuf
!= NULL
);
298 TEST (decoder
->state
== STATE_PICTURE_AVAIL
);
300 const Picture
* my_picture
= parser
->GetNextPicture();
304 int pic_num
= my_picture
->GetPparams().PictureNum();
306 if (!parser
->GetDecoderParams().FieldCoding())
308 set_frame_component (my_picture
->Data(Y_COMP
), Y_COMP
, decoder
);
309 set_frame_component (my_picture
->Data(U_COMP
), U_COMP
, decoder
);
310 set_frame_component (my_picture
->Data(V_COMP
), V_COMP
, decoder
);
314 set_field_component (my_picture
->Data(Y_COMP
), Y_COMP
, decoder
, pic_num
);
315 set_field_component (my_picture
->Data(U_COMP
), U_COMP
, decoder
, pic_num
);
316 set_field_component (my_picture
->Data(V_COMP
), V_COMP
, decoder
, pic_num
);
322 extern DllExport dirac_decoder_state_t
dirac_parse (dirac_decoder_t
*decoder
)
324 TEST (decoder
!= NULL
);
325 TEST (decoder
->parser
!= NULL
);
326 DiracParser
*parser
= static_cast<DiracParser
*>(decoder
->parser
);
328 unsigned int pic_num
;
334 decoder
->state
= parser
->Parse();
336 switch (decoder
->state
)
339 return decoder
->state
;
343 set_sequence_params(parser
, decoder
);
344 decoder
->frame_avail
= 0;
345 return decoder
->state
;
348 case STATE_PICTURE_AVAIL
:
350 const Picture
*my_picture
= parser
->GetNextPicture();
353 pic_num
= parser
->GetNextPicture()->GetPparams().PictureNum();
354 decoder
->frame_num
= pic_num
;
355 set_frame_data (parser
, decoder
);
357 /* A full frame is only available if we're doing
358 * progressive coding or have decoded the second field.
359 * Will only return when a full frame is available
361 if (!parser
->GetDecoderParams().FieldCoding() ||
364 /* Frame number currently available for display */
365 decoder
->frame_num
= pic_num
;
366 if (parser
->GetDecoderParams().FieldCoding())
367 decoder
->frame_num
= pic_num
>>1;
368 decoder
->frame_avail
= 1;
369 return decoder
->state
;
376 return decoder
->state
;
379 case STATE_SEQUENCE_END
:
380 return decoder
->state
;
387 catch (const DiracException
& e
)
389 return STATE_INVALID
;
393 return decoder
->state
;
396 extern DllExport
void dirac_set_buf (dirac_decoder_t
*decoder
, unsigned char *buf
[3], void *id
)
398 TEST (decoder
!= NULL
);
399 TEST (decoder
->fbuf
!= NULL
);
401 decoder
->fbuf
->buf
[0] = buf
[0];
402 decoder
->fbuf
->buf
[1] = buf
[1];
403 decoder
->fbuf
->buf
[2] = buf
[2];
404 decoder
->fbuf
->id
= id
;