1 /*****************************************************************************
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 /*****************************************************************************
26 *****************************************************************************/
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_codec.h>
35 #include <vlc_block.h>
38 #include <vlc_block_helper.h>
39 #include "../codec/cc.h"
40 #include "packetizer_helper.h"
42 #include "hxxx_ep3b.h"
43 #include "startcode_helper.h"
44 #include "iso_color_tables.h"
46 /*****************************************************************************
48 *****************************************************************************/
49 static int Open ( vlc_object_t
* );
50 static void Close( vlc_object_t
* );
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
)
60 /*****************************************************************************
62 *****************************************************************************/
68 packetizer_t packetizer
;
70 /* Current sequence header */
71 bool b_sequence_header
;
75 bool b_advanced_profile
;
77 bool b_frame_interpolation
;
78 bool b_range_reduction
;
90 /* Current frame being built */
91 vlc_tick_t i_frame_dts
;
92 vlc_tick_t i_frame_pts
;
98 bool b_check_startcode
;
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,
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
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
)
152 p_dec
->p_sys
= p_sys
= malloc( sizeof( decoder_sys_t
) );
153 if( unlikely( !p_sys
) )
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
,
165 PacketizeReset
, PacketizeParse
, PacketizeValidate
, PacketizeDrain
,
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
);
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
--;
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
);
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
);
214 /*****************************************************************************
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
);
224 block_Release( p_sys
->p_frame
);
226 block_Release( p_sys
->sh
.p_sh
);
228 block_Release( p_sys
->ep
.p_ep
);
230 cc_Exit( &p_sys
->cc_next
);
231 cc_Exit( &p_sys
->cc
);
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
);
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
;
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
);
271 p_sys
->b_check_startcode
= p_dec
->fmt_in
.b_packetized
;
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
;
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" );
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
;
335 if( !p_sys
->b_sequence_header
|| !p_sys
->b_entry_point
)
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
);
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
;
371 block_t
*p_pic
= block_ChainGather( p_sys
->p_frame
);
374 p_pic
->i_dts
= p_sys
->i_frame_dts
;
375 p_pic
->i_pts
= p_sys
->i_frame_pts
;
379 if( i_dts
== VLC_TICK_INVALID
)
380 i_dts
= date_Get( &p_sys
->dts
);
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
) )
388 /* TODO compute pts for other case */
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 ) );
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
);
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
;
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];
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
);
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
);
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
);
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
;
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
);
474 if( idu
== IDU_TYPE_SEQUENCE_HEADER
)
476 es_format_t
*p_es
= &p_dec
->fmt_out
;
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
;
504 p_frag
->p_buffer
+= 4;
505 p_frag
->i_buffer
-= 4;
506 memcpy( p_frag
->p_buffer
, startcode
, sizeof(startcode
) );
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 );
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
;
566 i_ar_w
= bs_read( &s
, 8 );
567 i_ar_h
= bs_read( &s
, 8 );
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;
590 const int i_nr
= bs_read( &s
, 8 );
591 const int i_dn
= bs_read( &s
, 4 );
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;
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 ) );
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;
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
)
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
)
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
)
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 */
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 ) )
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
;
703 p_sys
->p_frame
->i_flags
|= BLOCK_FLAG_TYPE_P
;
709 p_sys
->p_frame
->i_flags
|= BLOCK_FLAG_TYPE_B
;
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 */
724 p_sys
->p_frame
->i_flags
|= BLOCK_FLAG_TYPE_P
; /* P Skip */
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
;
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
)
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
);
753 uint8_t *p_data
= malloc( i_size
);
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 );
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
);
781 block_Release( p_release
);
785 /*****************************************************************************
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
;
793 p_cc
= block_Alloc( p_sys
->cc
.i_data
);
796 memcpy( p_cc
->p_buffer
, p_sys
->cc
.p_data
, p_sys
->cc
.i_data
);
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
);