qml: Create MediaGroupDisplay
[vlc.git] / modules / packetizer / vc1.c
blobd8f43f306062da4ac1c6ae9c58faf671716e98ca
1 /*****************************************************************************
2 * vc1.c
3 *****************************************************************************
4 * Copyright (C) 2001, 2002, 2006 VLC authors and VideoLAN
6 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
7 * Gildas Bazin <gbazin@videolan.org>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
25 * Preamble
26 *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_codec.h>
35 #include <vlc_block.h>
37 #include <vlc_bits.h>
38 #include <vlc_block_helper.h>
39 #include "../codec/cc.h"
40 #include "packetizer_helper.h"
41 #include "hxxx_nal.h"
42 #include "hxxx_ep3b.h"
43 #include "startcode_helper.h"
44 #include "iso_color_tables.h"
46 /*****************************************************************************
47 * Module descriptor
48 *****************************************************************************/
49 static int Open ( vlc_object_t * );
50 static void Close( vlc_object_t * );
52 vlc_module_begin ()
53 set_category( CAT_SOUT )
54 set_subcategory( SUBCAT_SOUT_PACKETIZER )
55 set_description( N_("VC-1 packetizer") )
56 set_capability( "packetizer", 50 )
57 set_callbacks( Open, Close )
58 vlc_module_end ()
60 /*****************************************************************************
61 * Local prototypes
62 *****************************************************************************/
63 typedef struct
66 * Input properties
68 packetizer_t packetizer;
70 /* Current sequence header */
71 bool b_sequence_header;
72 struct
74 block_t *p_sh;
75 bool b_advanced_profile;
76 bool b_interlaced;
77 bool b_frame_interpolation;
78 bool b_range_reduction;
79 bool b_has_bframe;
80 } sh;
81 bool b_entry_point;
82 struct
84 block_t *p_ep;
85 } ep;
87 /* */
88 bool b_frame;
90 /* Current frame being built */
91 vlc_tick_t i_frame_dts;
92 vlc_tick_t i_frame_pts;
93 block_t *p_frame;
94 block_t **pp_last;
95 date_t dts;
98 bool b_check_startcode;
100 /* */
101 uint32_t i_cc_flags;
102 vlc_tick_t i_cc_pts;
103 vlc_tick_t i_cc_dts;
104 cc_data_t cc;
106 cc_data_t cc_next;
107 } decoder_sys_t;
109 typedef enum
111 IDU_TYPE_SEQUENCE_HEADER = 0x0f,
112 IDU_TYPE_ENTRY_POINT = 0x0e,
113 IDU_TYPE_FRAME = 0x0D,
114 IDU_TYPE_FIELD = 0x0C,
115 IDU_TYPE_SLICE = 0x0B,
116 IDU_TYPE_END_OF_SEQUENCE = 0x0A,
118 IDU_TYPE_SEQUENCE_LEVEL_USER_DATA = 0x1F,
119 IDU_TYPE_ENTRY_POINT_USER_DATA = 0x1E,
120 IDU_TYPE_FRAME_USER_DATA = 0x1D,
121 IDU_TYPE_FIELD_USER_DATA = 0x1C,
122 IDU_TYPE_SLICE_USER_DATA = 0x1B,
123 } idu_type_t;
125 static block_t *Packetize( decoder_t *p_dec, block_t **pp_block );
126 static void Flush( decoder_t * );
128 static void PacketizeReset( void *p_private, bool b_broken );
129 static block_t *PacketizeParse( void *p_private, bool *pb_ts_used, block_t * );
130 static int PacketizeValidate( void *p_private, block_t * );
131 static block_t *PacketizeDrain( void *p_private );
133 static block_t *OutputFrame( decoder_t *p_dec );
134 static block_t *ParseIDU( decoder_t *p_dec, bool *pb_ts_used, block_t *p_frag );
135 static block_t *GetCc( decoder_t *p_dec, decoder_cc_desc_t * );
137 static const uint8_t p_vc1_startcode[3] = { 0x00, 0x00, 0x01 };
138 /*****************************************************************************
139 * Open: probe the packetizer and return score
140 *****************************************************************************
141 * Tries to launch a decoder and return score so that the interface is able
142 * to choose.
143 *****************************************************************************/
144 static int Open( vlc_object_t *p_this )
146 decoder_t *p_dec = (decoder_t*)p_this;
147 decoder_sys_t *p_sys;
149 if( p_dec->fmt_in.i_codec != VLC_CODEC_VC1 )
150 return VLC_EGENERIC;
152 p_dec->p_sys = p_sys = malloc( sizeof( decoder_sys_t ) );
153 if( unlikely( !p_sys ) )
154 return VLC_ENOMEM;
156 /* Create the output format */
157 es_format_Copy( &p_dec->fmt_out, &p_dec->fmt_in );
158 p_dec->pf_packetize = Packetize;
159 p_dec->pf_flush = Flush;
160 p_dec->pf_get_cc = GetCc;
162 packetizer_Init( &p_sys->packetizer,
163 p_vc1_startcode, sizeof(p_vc1_startcode), startcode_FindAnnexB,
164 NULL, 0, 4,
165 PacketizeReset, PacketizeParse, PacketizeValidate, PacketizeDrain,
166 p_dec );
168 p_sys->b_sequence_header = false;
169 p_sys->sh.p_sh = NULL;
170 p_sys->b_entry_point = false;
171 p_sys->ep.p_ep = NULL;
173 p_sys->i_frame_dts = VLC_TICK_INVALID;
174 p_sys->i_frame_pts = VLC_TICK_INVALID;
176 p_sys->b_frame = false;
177 p_sys->p_frame = NULL;
178 p_sys->pp_last = &p_sys->p_frame;
180 if( p_dec->fmt_in.video.i_frame_rate && p_dec->fmt_in.video.i_frame_rate_base )
181 date_Init( &p_sys->dts, p_dec->fmt_in.video.i_frame_rate * 2,
182 p_dec->fmt_in.video.i_frame_rate_base );
183 else
184 date_Init( &p_sys->dts, 30000*2, 1000 );
185 p_sys->b_check_startcode = p_dec->fmt_in.b_packetized;
187 if( p_dec->fmt_out.i_extra > 0 )
189 uint8_t *p_extra = p_dec->fmt_out.p_extra;
191 /* With (some) ASF the first byte has to be stripped */
192 if( p_extra[0] != 0x00 )
194 memmove( &p_extra[0], &p_extra[1], p_dec->fmt_out.i_extra - 1 );
195 p_dec->fmt_out.i_extra--;
198 /* */
199 if( p_dec->fmt_out.i_extra > 0 )
200 packetizer_Header( &p_sys->packetizer,
201 p_dec->fmt_out.p_extra, p_dec->fmt_out.i_extra );
204 /* */
205 p_sys->i_cc_pts = VLC_TICK_INVALID;
206 p_sys->i_cc_dts = VLC_TICK_INVALID;
207 p_sys->i_cc_flags = 0;
208 cc_Init( &p_sys->cc );
209 cc_Init( &p_sys->cc_next );
211 return VLC_SUCCESS;
214 /*****************************************************************************
215 * Close:
216 *****************************************************************************/
217 static void Close( vlc_object_t *p_this )
219 decoder_t *p_dec = (decoder_t*)p_this;
220 decoder_sys_t *p_sys = p_dec->p_sys;
222 packetizer_Clean( &p_sys->packetizer );
223 if( p_sys->p_frame )
224 block_Release( p_sys->p_frame );
225 if( p_sys->sh.p_sh )
226 block_Release( p_sys->sh.p_sh );
227 if( p_sys->ep.p_ep )
228 block_Release( p_sys->ep.p_ep );
230 cc_Exit( &p_sys->cc_next );
231 cc_Exit( &p_sys->cc );
233 free( p_sys );
236 /*****************************************************************************
237 * Packetize: packetize an access unit
238 *****************************************************************************/
239 static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
241 decoder_sys_t *p_sys = p_dec->p_sys;
243 if( p_sys->b_check_startcode && pp_block && *pp_block )
245 /* Fix syntax for (some?) VC1 from asf */
246 const unsigned i_startcode = sizeof(p_vc1_startcode);
248 block_t *p_block = *pp_block;
249 if( p_block->i_buffer > 0 &&
250 ( p_block->i_buffer < i_startcode ||
251 memcmp( p_block->p_buffer, p_vc1_startcode, i_startcode ) ) )
253 *pp_block = p_block = block_Realloc( p_block, i_startcode+1, p_block->i_buffer );
254 if( p_block )
256 memcpy( p_block->p_buffer, p_vc1_startcode, i_startcode );
258 if( p_sys->b_sequence_header && p_sys->sh.b_interlaced &&
259 p_block->i_buffer > i_startcode+1 &&
260 (p_block->p_buffer[i_startcode+1] & 0xc0) == 0xc0 )
261 p_block->p_buffer[i_startcode] = IDU_TYPE_FIELD;
262 else
263 p_block->p_buffer[i_startcode] = IDU_TYPE_FRAME;
266 p_sys->b_check_startcode = false;
269 block_t *p_au = packetizer_Packetize( &p_sys->packetizer, pp_block );
270 if( !p_au )
271 p_sys->b_check_startcode = p_dec->fmt_in.b_packetized;
273 return p_au;
276 static void Flush( decoder_t *p_dec )
278 decoder_sys_t *p_sys = p_dec->p_sys;
280 packetizer_Flush( &p_sys->packetizer );
283 static void PacketizeReset( void *p_private, bool b_flush )
285 decoder_t *p_dec = p_private;
286 decoder_sys_t *p_sys = p_dec->p_sys;
288 if( b_flush )
290 if( p_sys->p_frame )
291 block_ChainRelease( p_sys->p_frame );
292 p_sys->p_frame = NULL;
293 p_sys->pp_last = &p_sys->p_frame;
294 p_sys->b_frame = false;
297 p_sys->i_frame_dts = VLC_TICK_INVALID;
298 p_sys->i_frame_pts = VLC_TICK_INVALID;
299 date_Set( &p_sys->dts, VLC_TICK_INVALID );
301 static block_t *PacketizeParse( void *p_private, bool *pb_ts_used, block_t *p_block )
303 decoder_t *p_dec = p_private;
305 return ParseIDU( p_dec, pb_ts_used, p_block );
308 static int PacketizeValidate( void *p_private, block_t *p_au )
310 decoder_t *p_dec = p_private;
311 decoder_sys_t *p_sys = p_dec->p_sys;
313 if( date_Get( &p_sys->dts ) == VLC_TICK_INVALID )
315 msg_Dbg( p_dec, "need a starting pts/dts" );
316 return VLC_EGENERIC;
318 VLC_UNUSED(p_au);
319 return VLC_SUCCESS;
322 static block_t * PacketizeDrain( void *p_private )
324 decoder_t *p_dec = p_private;
325 decoder_sys_t *p_sys = p_dec->p_sys;
326 return p_sys->b_frame ? OutputFrame( p_dec ) : NULL;
329 /* BuildExtraData: gather sequence header and entry point */
330 static void BuildExtraData( decoder_t *p_dec )
332 decoder_sys_t *p_sys = p_dec->p_sys;
333 es_format_t *p_es = &p_dec->fmt_out;
334 int i_extra;
335 if( !p_sys->b_sequence_header || !p_sys->b_entry_point )
336 return;
338 i_extra = p_sys->sh.p_sh->i_buffer + p_sys->ep.p_ep->i_buffer;
339 if( p_es->i_extra != i_extra )
341 p_es->i_extra = i_extra;
342 p_es->p_extra = xrealloc( p_es->p_extra, p_es->i_extra );
344 memcpy( p_es->p_extra,
345 p_sys->sh.p_sh->p_buffer, p_sys->sh.p_sh->i_buffer );
346 memcpy( (uint8_t*)p_es->p_extra + p_sys->sh.p_sh->i_buffer,
347 p_sys->ep.p_ep->p_buffer, p_sys->ep.p_ep->i_buffer );
350 static block_t *OutputFrame( decoder_t *p_dec )
352 decoder_sys_t *p_sys = p_dec->p_sys;
353 const int i_pic_flags = p_sys->p_frame->i_flags;
355 /* Prepend SH and EP on I */
356 if( i_pic_flags & BLOCK_FLAG_TYPE_I )
358 block_t *p_list = block_Duplicate( p_sys->sh.p_sh );
359 block_t *p_ep = block_Duplicate( p_sys->ep.p_ep );
360 if( p_ep )
361 block_ChainAppend( &p_list, p_ep );
362 block_ChainAppend( &p_list, p_sys->p_frame );
363 p_list->i_flags = i_pic_flags;
364 p_sys->p_frame = p_list;
367 vlc_tick_t i_dts = p_sys->i_frame_dts;
368 vlc_tick_t i_pts = p_sys->i_frame_pts;
370 /* */
371 block_t *p_pic = block_ChainGather( p_sys->p_frame );
372 if( p_pic )
374 p_pic->i_dts = p_sys->i_frame_dts;
375 p_pic->i_pts = p_sys->i_frame_pts;
378 /* */
379 if( i_dts == VLC_TICK_INVALID )
380 i_dts = date_Get( &p_sys->dts );
381 else
382 date_Set( &p_sys->dts, i_dts );
384 if( i_pts == VLC_TICK_INVALID )
386 if( !p_sys->sh.b_has_bframe || (i_pic_flags & BLOCK_FLAG_TYPE_B ) )
387 i_pts = i_dts;
388 /* TODO compute pts for other case */
391 if( p_pic )
393 p_pic->i_dts = i_dts;
394 p_pic->i_pts = i_pts;
397 //msg_Dbg( p_dec, "-------------- dts=%"PRId64" pts=%"PRId64, i_dts, i_pts );
399 /* We can interpolate dts/pts only if we have a frame rate */
400 if( p_dec->fmt_out.video.i_frame_rate && p_dec->fmt_out.video.i_frame_rate_base )
402 date_Increment( &p_sys->dts, 2 );
403 // msg_Dbg( p_dec, "-------------- XXX0 dts=%"PRId64" pts=%"PRId64" interpolated=%"PRId64,
404 // i_dts, i_pts, date_Get( &p_sys->dts ) );
407 /* CC */
408 p_sys->i_cc_pts = i_pts;
409 p_sys->i_cc_dts = i_dts;
410 p_sys->i_cc_flags = i_pic_flags;
412 p_sys->cc = p_sys->cc_next;
413 cc_Flush( &p_sys->cc_next );
415 /* Reset context */
416 p_sys->b_frame = false;
417 p_sys->i_frame_dts = VLC_TICK_INVALID;
418 p_sys->i_frame_pts = VLC_TICK_INVALID;
419 p_sys->p_frame = NULL;
420 p_sys->pp_last = &p_sys->p_frame;
422 return p_pic;
425 /* ParseIDU: parse an Independent Decoding Unit */
426 static block_t *ParseIDU( decoder_t *p_dec, bool *pb_ts_used, block_t *p_frag )
428 decoder_sys_t *p_sys = p_dec->p_sys;
429 block_t *p_pic = NULL;
430 const idu_type_t idu = p_frag->p_buffer[3];
432 *pb_ts_used = false;
433 if( !p_sys->b_sequence_header && idu != IDU_TYPE_SEQUENCE_HEADER )
435 msg_Warn( p_dec, "waiting for sequence header" );
436 block_Release( p_frag );
437 return NULL;
439 if( p_sys->b_sequence_header && !p_sys->b_entry_point && idu != IDU_TYPE_ENTRY_POINT )
441 msg_Warn( p_dec, "waiting for entry point" );
442 block_Release( p_frag );
443 return NULL;
445 /* TODO we do not gather ENTRY_POINT and SEQUENCE_DATA user data
446 * But It should not be a problem for decoder */
448 /* Do we have completed a frame */
449 if( p_sys->b_frame &&
450 idu != IDU_TYPE_FRAME_USER_DATA &&
451 idu != IDU_TYPE_FIELD && idu != IDU_TYPE_FIELD_USER_DATA &&
452 idu != IDU_TYPE_SLICE && idu != IDU_TYPE_SLICE_USER_DATA &&
453 idu != IDU_TYPE_END_OF_SEQUENCE )
455 p_pic = OutputFrame( p_dec );
458 /* */
459 if( p_sys->i_frame_dts == VLC_TICK_INVALID && p_sys->i_frame_pts == VLC_TICK_INVALID )
461 p_sys->i_frame_dts = p_frag->i_dts;
462 p_sys->i_frame_pts = p_frag->i_pts;
463 *pb_ts_used = true;
466 /* We will add back SH and EP on I frames */
467 block_t *p_release = NULL;
468 if( idu != IDU_TYPE_SEQUENCE_HEADER && idu != IDU_TYPE_ENTRY_POINT )
469 block_ChainLastAppend( &p_sys->pp_last, p_frag );
470 else
471 p_release = p_frag;
473 /* Parse IDU */
474 if( idu == IDU_TYPE_SEQUENCE_HEADER )
476 es_format_t *p_es = &p_dec->fmt_out;
477 bs_t s;
478 int i_profile;
480 /* */
481 if( p_sys->sh.p_sh )
482 block_Release( p_sys->sh.p_sh );
483 p_sys->sh.p_sh = block_Duplicate( p_frag );
485 /* Auto detect VC-1_SPMP_PESpacket_PayloadFormatHeader (SMPTE RP 227) for simple/main profile
486 * TODO find a test case and valid it */
487 if( p_frag->i_buffer > 8 && (p_frag->p_buffer[4]&0x80) == 0 ) /* for advanced profile, the first bit is 1 */
489 video_format_t *p_v = &p_dec->fmt_in.video;
490 const size_t i_potential_width = GetWBE( &p_frag->p_buffer[4] );
491 const size_t i_potential_height = GetWBE( &p_frag->p_buffer[6] );
493 if( i_potential_width >= 2 && i_potential_width <= 8192 &&
494 i_potential_height >= 2 && i_potential_height <= 8192 )
496 if( ( p_v->i_width <= 0 && p_v->i_height <= 0 ) ||
497 ( p_v->i_width == i_potential_width && p_v->i_height == i_potential_height ) )
499 static const uint8_t startcode[4] = { 0x00, 0x00, 0x01, IDU_TYPE_SEQUENCE_HEADER };
500 p_es->video.i_width = i_potential_width;
501 p_es->video.i_height = i_potential_height;
503 /* Remove it */
504 p_frag->p_buffer += 4;
505 p_frag->i_buffer -= 4;
506 memcpy( p_frag->p_buffer, startcode, sizeof(startcode) );
511 /* Parse it */
512 struct hxxx_bsfw_ep3b_ctx_s bsctx;
513 hxxx_bsfw_ep3b_ctx_init( &bsctx );
514 bs_init_custom( &s, &p_frag->p_buffer[4], p_frag->i_buffer - 4,
515 &hxxx_bsfw_ep3b_callbacks, &bsctx );
517 i_profile = bs_read( &s, 2 );
518 if( i_profile == 3 )
520 const int i_level = bs_read( &s, 3 );
522 /* Advanced profile */
523 p_sys->sh.b_advanced_profile = true;
524 p_sys->sh.b_range_reduction = false;
525 p_sys->sh.b_has_bframe = true;
527 bs_skip( &s, 2+3+5+1 ); // chroma format + frame rate Q + bit rate Q + postprocflag
529 p_es->video.i_width = 2*bs_read( &s, 12 )+2;
530 p_es->video.i_height = 2*bs_read( &s, 12 )+2;
532 if( !p_sys->b_sequence_header )
533 msg_Dbg( p_dec, "found sequence header for advanced profile level L%d resolution %dx%d",
534 i_level, p_es->video.i_width, p_es->video.i_height);
536 bs_skip( &s, 1 );// pulldown
537 p_sys->sh.b_interlaced = bs_read( &s, 1 );
538 bs_skip( &s, 1 );// frame counter
539 p_sys->sh.b_frame_interpolation = bs_read( &s, 1 );
540 bs_skip( &s, 1 ); // Reserved
541 bs_skip( &s, 1 ); // Psf
543 if( bs_read( &s, 1 ) ) /* Display extension */
545 const int i_display_width = bs_read( &s, 14 )+1;
546 const int i_display_height = bs_read( &s, 14 )+1;
548 p_es->video.i_sar_num = i_display_width * p_es->video.i_height;
549 p_es->video.i_sar_den = i_display_height * p_es->video.i_width;
551 if( !p_sys->b_sequence_header )
552 msg_Dbg( p_dec, "display size %dx%d", i_display_width, i_display_height );
554 if( bs_read( &s, 1 ) ) /* Pixel aspect ratio (PAR/SAR) */
556 static const unsigned p_ar[16][2] = {
557 { 0, 0}, { 1, 1}, {12,11}, {10,11}, {16,11}, {40,33},
558 {24,11}, {20,11}, {32,11}, {80,33}, {18,11}, {15,11},
559 {64,33}, {160,99},{ 0, 0}, { 0, 0}
561 int i_ar = bs_read( &s, 4 );
562 unsigned i_ar_w, i_ar_h;
564 if( i_ar == 15 )
566 i_ar_w = bs_read( &s, 8 );
567 i_ar_h = bs_read( &s, 8 );
569 else
571 i_ar_w = p_ar[i_ar][0];
572 i_ar_h = p_ar[i_ar][1];
574 vlc_ureduce( &i_ar_w, &i_ar_h, i_ar_w, i_ar_h, 0 );
575 if( !p_sys->b_sequence_header )
576 msg_Dbg( p_dec, "aspect ratio %d:%d", i_ar_w, i_ar_h );
579 if( bs_read( &s, 1 ) ) /* Frame rate */
581 unsigned i_fps_num = 0;
582 unsigned i_fps_den = 0;
583 if( bs_read( &s, 1 ) )
585 i_fps_num = bs_read( &s, 16 )+1;
586 i_fps_den = 32;
588 else
590 const int i_nr = bs_read( &s, 8 );
591 const int i_dn = bs_read( &s, 4 );
593 switch( i_nr )
595 case 1: i_fps_num = 24000; break;
596 case 2: i_fps_num = 25000; break;
597 case 3: i_fps_num = 30000; break;
598 case 4: i_fps_num = 50000; break;
599 case 5: i_fps_num = 60000; break;
600 case 6: i_fps_num = 48000; break;
601 case 7: i_fps_num = 72000; break;
603 switch( i_dn )
605 case 1: i_fps_den = 1000; break;
606 case 2: i_fps_den = 1001; break;
610 if( i_fps_num != 0 && i_fps_den != 0 &&
611 (p_dec->fmt_in.video.i_frame_rate == 0 ||
612 p_dec->fmt_in.video.i_frame_rate_base == 0) )
613 vlc_ureduce( &p_es->video.i_frame_rate, &p_es->video.i_frame_rate_base, i_fps_num, i_fps_den, 0 );
615 if( !p_sys->b_sequence_header )
617 msg_Dbg( p_dec, "frame rate %d/%d", p_es->video.i_frame_rate, p_es->video.i_frame_rate_base );
618 date_Change( &p_sys->dts, p_es->video.i_frame_rate * 2, p_es->video.i_frame_rate_base );
621 if( bs_read1( &s ) && /* Color Format */
622 p_dec->fmt_in.video.primaries == COLOR_PRIMARIES_UNDEF )
624 p_es->video.primaries = iso_23001_8_cp_to_vlc_primaries( bs_read( &s, 8 ) );
625 p_es->video.transfer = iso_23001_8_tc_to_vlc_xfer( bs_read( &s, 8 ) );
626 p_es->video.space = iso_23001_8_mc_to_vlc_coeffs( bs_read( &s, 8 ) );
629 else
631 /* Simple and main profile */
632 p_sys->sh.b_advanced_profile = false;
633 p_sys->sh.b_interlaced = false;
635 if( !p_sys->b_sequence_header )
636 msg_Dbg( p_dec, "found sequence header for %s profile", i_profile == 0 ? "simple" : "main" );
638 bs_skip( &s, 2+3+5+1+1+ // reserved + frame rate Q + bit rate Q + loop filter + reserved
639 1+1+1+1+2+ // multiresolution + reserved + fast uv mc + extended mv + dquant
640 1+1+1+1 ); // variable size transform + reserved + overlap + sync marker
641 p_sys->sh.b_range_reduction = bs_read( &s, 1 );
642 if( bs_read( &s, 3 ) > 0 )
643 p_sys->sh.b_has_bframe = true;
644 else
645 p_sys->sh.b_has_bframe = false;
646 bs_skip( &s, 2 ); // quantizer
648 p_sys->sh.b_frame_interpolation = bs_read( &s, 1 );
650 p_sys->b_sequence_header = true;
651 BuildExtraData( p_dec );
653 else if( idu == IDU_TYPE_ENTRY_POINT )
655 if( p_sys->ep.p_ep )
656 block_Release( p_sys->ep.p_ep );
657 p_sys->ep.p_ep = block_Duplicate( p_frag );
659 if( !p_sys->b_entry_point )
660 msg_Dbg( p_dec, "found entry point" );
662 p_sys->b_entry_point = true;
663 BuildExtraData( p_dec );
665 else if( idu == IDU_TYPE_FRAME )
667 bs_t s;
669 /* Parse it + interpolate pts/dts if possible */
670 struct hxxx_bsfw_ep3b_ctx_s bsctx;
671 hxxx_bsfw_ep3b_ctx_init( &bsctx );
672 bs_init_custom( &s, &p_frag->p_buffer[4], p_frag->i_buffer - 4,
673 &hxxx_bsfw_ep3b_callbacks, &bsctx );
675 if( p_sys->sh.b_advanced_profile )
677 int i_fcm = 0;
679 if( p_sys->sh.b_interlaced )
681 if( bs_read( &s, 1 ) )
683 if( bs_read( &s, 1 ) )
684 i_fcm = 1; /* interlaced field */
685 else
686 i_fcm = 2; /* interlaced frame */
690 if( i_fcm == 1 ) /*interlaced field */
692 /* XXX for mixed I/P we should check reference usage before marking them I (too much work) */
693 switch( bs_read( &s, 3 ) )
695 case 0: /* II */
696 case 1: /* IP */
697 case 2: /* PI */
698 p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_I;
699 p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_I;
700 p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_I;
701 break;
702 case 3: /* PP */
703 p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_P;
704 break;
705 case 4: /* BB */
706 case 5: /* BBi */
707 case 6: /* BiB */
708 case 7: /* BiBi */
709 p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_B;
710 break;
713 else
715 if( !bs_read( &s, 1 ) )
716 p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_P;
717 else if( !bs_read( &s, 1 ) )
718 p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_B;
719 else if( !bs_read( &s, 1 ) )
720 p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_I;
721 else if( !bs_read( &s, 1 ) )
722 p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_B; /* Bi */
723 else
724 p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_P; /* P Skip */
727 else
729 if( p_sys->sh.b_frame_interpolation )
730 bs_skip( &s, 1 ); // interpolate
731 bs_skip( &s, 2 ); // frame count
732 if( p_sys->sh.b_range_reduction )
733 bs_skip( &s, 1 ); // range reduction
735 if( bs_read( &s, 1 ) )
736 p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_P;
737 else if( !p_sys->sh.b_has_bframe || bs_read( &s, 1 ) )
738 p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_I;
739 else
740 p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_B;
742 p_sys->b_frame = true;
744 else if( idu == IDU_TYPE_FRAME_USER_DATA )
746 bs_t s;
747 const size_t i_size = p_frag->i_buffer - 4;
748 struct hxxx_bsfw_ep3b_ctx_s bsctx;
749 hxxx_bsfw_ep3b_ctx_init( &bsctx );
750 bs_init_custom( &s, &p_frag->p_buffer[4], i_size, &hxxx_bsfw_ep3b_callbacks, &bsctx );
752 unsigned i_data;
753 uint8_t *p_data = malloc( i_size );
754 if( p_data )
756 /* store converted data */
757 for( i_data = 0; i_data + 1 /* trailing 0x80 flush byte */<i_size; i_data++ )
759 p_data[i_data] = bs_read( &s, 8 );
760 if( bs_error(&s) )
761 break;
764 /* TS 101 154 Auxiliary Data and VC-1 video */
765 static const uint8_t p_DVB1_user_identifier[] = {
766 0x47, 0x41, 0x39, 0x34 /* user identifier */
769 /* Check if we have DVB1_data() */
770 if( i_data >= sizeof(p_DVB1_user_identifier) &&
771 !memcmp( p_data, p_DVB1_user_identifier, sizeof(p_DVB1_user_identifier) ) )
773 cc_ProbeAndExtract( &p_sys->cc_next, true, p_data, i_data );
776 free( p_data );
780 if( p_release )
781 block_Release( p_release );
782 return p_pic;
785 /*****************************************************************************
786 * GetCc:
787 *****************************************************************************/
788 static block_t *GetCc( decoder_t *p_dec, decoder_cc_desc_t *p_desc )
790 decoder_sys_t *p_sys = p_dec->p_sys;
791 block_t *p_cc;
793 p_cc = block_Alloc( p_sys->cc.i_data);
794 if( p_cc )
796 memcpy( p_cc->p_buffer, p_sys->cc.p_data, p_sys->cc.i_data );
797 p_cc->i_dts =
798 p_cc->i_pts = p_sys->cc.b_reorder ? p_sys->i_cc_pts : p_sys->i_cc_dts;
799 p_cc->i_flags = p_sys->i_cc_flags & BLOCK_FLAG_TYPE_MASK;
801 p_desc->i_608_channels = p_sys->cc.i_608channels;
802 p_desc->i_708_channels = p_sys->cc.i_708channels;
803 p_desc->i_reorder_depth = p_sys->cc.b_reorder ? 4 : -1;
805 cc_Flush( &p_sys->cc );
806 return p_cc;