1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2001, 2002, 2006 VLC authors and VideoLAN
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8 * Gildas Bazin <gbazin@videolan.org>
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with this program; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23 *****************************************************************************/
25 /*****************************************************************************
27 *****************************************************************************/
33 #include <vlc_common.h>
34 #include <vlc_plugin.h>
35 #include <vlc_codec.h>
36 #include <vlc_block.h>
39 #include <vlc_block_helper.h>
40 #include "../codec/cc.h"
41 #include "packetizer_helper.h"
43 #include "startcode_helper.h"
45 /*****************************************************************************
47 *****************************************************************************/
48 static int Open ( vlc_object_t
* );
49 static void Close( vlc_object_t
* );
52 set_category( CAT_SOUT
)
53 set_subcategory( SUBCAT_SOUT_PACKETIZER
)
54 set_description( N_("VC-1 packetizer") )
55 set_capability( "packetizer", 50 )
56 set_callbacks( Open
, Close
)
59 /*****************************************************************************
61 *****************************************************************************/
67 packetizer_t packetizer
;
69 /* Current sequence header */
70 bool b_sequence_header
;
74 bool b_advanced_profile
;
76 bool b_frame_interpolation
;
77 bool b_range_reduction
;
89 /* Current frame being built */
96 mtime_t i_interpolated_dts
;
97 bool b_check_startcode
;
110 IDU_TYPE_SEQUENCE_HEADER
= 0x0f,
111 IDU_TYPE_ENTRY_POINT
= 0x0e,
112 IDU_TYPE_FRAME
= 0x0D,
113 IDU_TYPE_FIELD
= 0x0C,
114 IDU_TYPE_SLICE
= 0x0B,
115 IDU_TYPE_END_OF_SEQUENCE
= 0x0A,
117 IDU_TYPE_SEQUENCE_LEVEL_USER_DATA
= 0x1F,
118 IDU_TYPE_ENTRY_POINT_USER_DATA
= 0x1E,
119 IDU_TYPE_FRAME_USER_DATA
= 0x1D,
120 IDU_TYPE_FIELD_USER_DATA
= 0x1C,
121 IDU_TYPE_SLICE_USER_DATA
= 0x1B,
124 static block_t
*Packetize( decoder_t
*p_dec
, block_t
**pp_block
);
125 static void Flush( decoder_t
* );
127 static void PacketizeReset( void *p_private
, bool b_broken
);
128 static block_t
*PacketizeParse( void *p_private
, bool *pb_ts_used
, block_t
* );
129 static int PacketizeValidate( void *p_private
, block_t
* );
131 static block_t
*ParseIDU( decoder_t
*p_dec
, bool *pb_ts_used
, block_t
*p_frag
);
132 static block_t
*GetCc( decoder_t
*p_dec
, bool pb_present
[4], int * );
134 static const uint8_t p_vc1_startcode
[3] = { 0x00, 0x00, 0x01 };
135 /*****************************************************************************
136 * Open: probe the packetizer and return score
137 *****************************************************************************
138 * Tries to launch a decoder and return score so that the interface is able
140 *****************************************************************************/
141 static int Open( vlc_object_t
*p_this
)
143 decoder_t
*p_dec
= (decoder_t
*)p_this
;
144 decoder_sys_t
*p_sys
;
146 if( p_dec
->fmt_in
.i_codec
!= VLC_CODEC_VC1
)
149 p_dec
->pf_packetize
= Packetize
;
150 p_dec
->pf_flush
= Flush
;
151 p_dec
->pf_get_cc
= GetCc
;
153 /* Create the output format */
154 es_format_Copy( &p_dec
->fmt_out
, &p_dec
->fmt_in
);
155 p_dec
->p_sys
= p_sys
= malloc( sizeof( decoder_sys_t
) );
156 if( unlikely( !p_sys
) )
159 packetizer_Init( &p_sys
->packetizer
,
160 p_vc1_startcode
, sizeof(p_vc1_startcode
), startcode_FindAnnexB
,
162 PacketizeReset
, PacketizeParse
, PacketizeValidate
, p_dec
);
164 p_sys
->b_sequence_header
= false;
165 p_sys
->sh
.p_sh
= NULL
;
166 p_sys
->b_entry_point
= false;
167 p_sys
->ep
.p_ep
= NULL
;
169 p_sys
->i_frame_dts
= VLC_TS_INVALID
;
170 p_sys
->i_frame_pts
= VLC_TS_INVALID
;
172 p_sys
->b_frame
= false;
173 p_sys
->p_frame
= NULL
;
174 p_sys
->pp_last
= &p_sys
->p_frame
;
176 p_sys
->i_interpolated_dts
= VLC_TS_INVALID
;
177 p_sys
->b_check_startcode
= p_dec
->fmt_in
.b_packetized
;
179 if( p_dec
->fmt_out
.i_extra
> 0 )
181 uint8_t *p_extra
= p_dec
->fmt_out
.p_extra
;
183 /* With (some) ASF the first byte has to be stripped */
184 if( p_extra
[0] != 0x00 )
186 memmove( &p_extra
[0], &p_extra
[1], p_dec
->fmt_out
.i_extra
- 1 );
187 p_dec
->fmt_out
.i_extra
--;
191 if( p_dec
->fmt_out
.i_extra
> 0 )
192 packetizer_Header( &p_sys
->packetizer
,
193 p_dec
->fmt_out
.p_extra
, p_dec
->fmt_out
.i_extra
);
197 p_sys
->i_cc_pts
= VLC_TS_INVALID
;
198 p_sys
->i_cc_dts
= VLC_TS_INVALID
;
199 p_sys
->i_cc_flags
= 0;
200 cc_Init( &p_sys
->cc
);
201 cc_Init( &p_sys
->cc_next
);
206 /*****************************************************************************
208 *****************************************************************************/
209 static void Close( vlc_object_t
*p_this
)
211 decoder_t
*p_dec
= (decoder_t
*)p_this
;
212 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
214 packetizer_Clean( &p_sys
->packetizer
);
216 block_Release( p_sys
->p_frame
);
218 cc_Exit( &p_sys
->cc_next
);
219 cc_Exit( &p_sys
->cc
);
224 /*****************************************************************************
225 * Packetize: packetize an access unit
226 *****************************************************************************/
227 static block_t
*Packetize( decoder_t
*p_dec
, block_t
**pp_block
)
229 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
231 if( p_sys
->b_check_startcode
&& pp_block
&& *pp_block
)
233 /* Fix syntax for (some?) VC1 from asf */
234 const unsigned i_startcode
= sizeof(p_vc1_startcode
);
236 block_t
*p_block
= *pp_block
;
237 if( p_block
->i_buffer
> 0 &&
238 ( p_block
->i_buffer
< i_startcode
||
239 memcmp( p_block
->p_buffer
, p_vc1_startcode
, i_startcode
) ) )
241 *pp_block
= p_block
= block_Realloc( p_block
, i_startcode
+1, p_block
->i_buffer
);
244 memcpy( p_block
->p_buffer
, p_vc1_startcode
, i_startcode
);
246 if( p_sys
->b_sequence_header
&& p_sys
->sh
.b_interlaced
&&
247 p_block
->i_buffer
> i_startcode
+1 &&
248 (p_block
->p_buffer
[i_startcode
+1] & 0xc0) == 0xc0 )
249 p_block
->p_buffer
[i_startcode
] = IDU_TYPE_FIELD
;
251 p_block
->p_buffer
[i_startcode
] = IDU_TYPE_FRAME
;
254 p_sys
->b_check_startcode
= false;
257 block_t
*p_au
= packetizer_Packetize( &p_sys
->packetizer
, pp_block
);
259 p_sys
->b_check_startcode
= p_dec
->fmt_in
.b_packetized
;
264 static void Flush( decoder_t
*p_dec
)
266 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
268 packetizer_Flush( &p_sys
->packetizer
);
271 static void PacketizeReset( void *p_private
, bool b_broken
)
273 decoder_t
*p_dec
= p_private
;
274 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
279 block_ChainRelease( p_sys
->p_frame
);
280 p_sys
->p_frame
= NULL
;
281 p_sys
->pp_last
= &p_sys
->p_frame
;
282 p_sys
->b_frame
= false;
285 p_sys
->i_frame_dts
= VLC_TS_INVALID
;
286 p_sys
->i_frame_pts
= VLC_TS_INVALID
;
287 p_sys
->i_interpolated_dts
= VLC_TS_INVALID
;
289 static block_t
*PacketizeParse( void *p_private
, bool *pb_ts_used
, block_t
*p_block
)
291 decoder_t
*p_dec
= p_private
;
293 return ParseIDU( p_dec
, pb_ts_used
, p_block
);
296 static int PacketizeValidate( void *p_private
, block_t
*p_au
)
298 decoder_t
*p_dec
= p_private
;
299 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
301 if( p_sys
->i_interpolated_dts
<= VLC_TS_INVALID
)
303 msg_Dbg( p_dec
, "need a starting pts/dts" );
310 /* BuildExtraData: gather sequence header and entry point */
311 static void BuildExtraData( decoder_t
*p_dec
)
313 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
314 es_format_t
*p_es
= &p_dec
->fmt_out
;
316 if( !p_sys
->b_sequence_header
|| !p_sys
->b_entry_point
)
319 i_extra
= p_sys
->sh
.p_sh
->i_buffer
+ p_sys
->ep
.p_ep
->i_buffer
;
320 if( p_es
->i_extra
!= i_extra
)
322 p_es
->i_extra
= i_extra
;
323 p_es
->p_extra
= xrealloc( p_es
->p_extra
, p_es
->i_extra
);
325 memcpy( p_es
->p_extra
,
326 p_sys
->sh
.p_sh
->p_buffer
, p_sys
->sh
.p_sh
->i_buffer
);
327 memcpy( (uint8_t*)p_es
->p_extra
+ p_sys
->sh
.p_sh
->i_buffer
,
328 p_sys
->ep
.p_ep
->p_buffer
, p_sys
->ep
.p_ep
->i_buffer
);
330 /* ParseIDU: parse an Independent Decoding Unit */
331 static block_t
*ParseIDU( decoder_t
*p_dec
, bool *pb_ts_used
, block_t
*p_frag
)
333 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
335 const idu_type_t idu
= p_frag
->p_buffer
[3];
338 if( !p_sys
->b_sequence_header
&& idu
!= IDU_TYPE_SEQUENCE_HEADER
)
340 msg_Warn( p_dec
, "waiting for sequence header" );
341 block_Release( p_frag
);
344 if( p_sys
->b_sequence_header
&& !p_sys
->b_entry_point
&& idu
!= IDU_TYPE_ENTRY_POINT
)
346 msg_Warn( p_dec
, "waiting for entry point" );
347 block_Release( p_frag
);
350 /* TODO we do not gather ENTRY_POINT and SEQUENCE_DATA user data
351 * But It should not be a problem for decoder */
353 /* Do we have completed a frame */
355 if( p_sys
->b_frame
&&
356 idu
!= IDU_TYPE_FRAME_USER_DATA
&&
357 idu
!= IDU_TYPE_FIELD
&& idu
!= IDU_TYPE_FIELD_USER_DATA
&&
358 idu
!= IDU_TYPE_SLICE
&& idu
!= IDU_TYPE_SLICE_USER_DATA
&&
359 idu
!= IDU_TYPE_END_OF_SEQUENCE
)
361 /* Prepend SH and EP on I */
362 if( p_sys
->p_frame
->i_flags
& BLOCK_FLAG_TYPE_I
)
364 block_t
*p_list
= block_Duplicate( p_sys
->sh
.p_sh
);
365 block_ChainAppend( &p_list
, block_Duplicate( p_sys
->ep
.p_ep
) );
366 block_ChainAppend( &p_list
, p_sys
->p_frame
);
368 p_list
->i_flags
= p_sys
->p_frame
->i_flags
;
370 p_sys
->p_frame
= p_list
;
374 p_pic
= block_ChainGather( p_sys
->p_frame
);
375 p_pic
->i_dts
= p_sys
->i_frame_dts
;
376 p_pic
->i_pts
= p_sys
->i_frame_pts
;
379 if( p_pic
->i_dts
> VLC_TS_INVALID
)
380 p_sys
->i_interpolated_dts
= p_pic
->i_dts
;
382 /* We can interpolate dts/pts only if we have a frame rate */
383 if( p_dec
->fmt_out
.video
.i_frame_rate
!= 0 && p_dec
->fmt_out
.video
.i_frame_rate_base
!= 0 )
385 if( p_sys
->i_interpolated_dts
> VLC_TS_INVALID
)
386 p_sys
->i_interpolated_dts
+= INT64_C(1000000) *
387 p_dec
->fmt_out
.video
.i_frame_rate_base
/
388 p_dec
->fmt_out
.video
.i_frame_rate
;
390 //msg_Dbg( p_dec, "-------------- XXX0 dts=%"PRId64" pts=%"PRId64" interpolated=%"PRId64,
391 // p_pic->i_dts, p_pic->i_pts, p_sys->i_interpolated_dts );
392 if( p_pic
->i_dts
<= VLC_TS_INVALID
)
393 p_pic
->i_dts
= p_sys
->i_interpolated_dts
;
395 if( p_pic
->i_pts
<= VLC_TS_INVALID
)
397 if( !p_sys
->sh
.b_has_bframe
|| (p_pic
->i_flags
& BLOCK_FLAG_TYPE_B
) )
398 p_pic
->i_pts
= p_pic
->i_dts
;
399 /* TODO compute pts for other case */
403 //msg_Dbg( p_dec, "-------------- dts=%"PRId64" pts=%"PRId64, p_pic->i_dts, p_pic->i_pts );
406 p_sys
->i_cc_pts
= p_pic
->i_pts
;
407 p_sys
->i_cc_dts
= p_pic
->i_dts
;
408 p_sys
->i_cc_flags
= p_pic
->i_flags
;
410 p_sys
->cc
= p_sys
->cc_next
;
411 cc_Flush( &p_sys
->cc_next
);
414 p_sys
->b_frame
= false;
415 p_sys
->i_frame_dts
= VLC_TS_INVALID
;
416 p_sys
->i_frame_pts
= VLC_TS_INVALID
;
417 p_sys
->p_frame
= NULL
;
418 p_sys
->pp_last
= &p_sys
->p_frame
;
422 if( p_sys
->i_frame_dts
<= VLC_TS_INVALID
&& p_sys
->i_frame_pts
<= VLC_TS_INVALID
)
424 p_sys
->i_frame_dts
= p_frag
->i_dts
;
425 p_sys
->i_frame_pts
= p_frag
->i_pts
;
429 /* We will add back SH and EP on I frames */
430 block_t
*p_release
= NULL
;
431 if( idu
!= IDU_TYPE_SEQUENCE_HEADER
&& idu
!= IDU_TYPE_ENTRY_POINT
)
432 block_ChainLastAppend( &p_sys
->pp_last
, p_frag
);
437 if( idu
== IDU_TYPE_SEQUENCE_HEADER
)
439 es_format_t
*p_es
= &p_dec
->fmt_out
;
441 unsigned i_bitflow
= 0;
446 block_Release( p_sys
->sh
.p_sh
);
447 p_sys
->sh
.p_sh
= block_Duplicate( p_frag
);
449 /* Auto detect VC-1_SPMP_PESpacket_PayloadFormatHeader (SMPTE RP 227) for simple/main profile
450 * TODO find a test case and valid it */
451 if( p_frag
->i_buffer
> 8 && (p_frag
->p_buffer
[4]&0x80) == 0 ) /* for advanced profile, the first bit is 1 */
453 video_format_t
*p_v
= &p_dec
->fmt_in
.video
;
454 const size_t i_potential_width
= GetWBE( &p_frag
->p_buffer
[4] );
455 const size_t i_potential_height
= GetWBE( &p_frag
->p_buffer
[6] );
457 if( i_potential_width
>= 2 && i_potential_width
<= 8192 &&
458 i_potential_height
>= 2 && i_potential_height
<= 8192 )
460 if( ( p_v
->i_width
<= 0 && p_v
->i_height
<= 0 ) ||
461 ( p_v
->i_width
== i_potential_width
&& p_v
->i_height
== i_potential_height
) )
463 static const uint8_t startcode
[4] = { 0x00, 0x00, 0x01, IDU_TYPE_SEQUENCE_HEADER
};
464 p_es
->video
.i_width
= i_potential_width
;
465 p_es
->video
.i_height
= i_potential_height
;
468 p_frag
->p_buffer
+= 4;
469 p_frag
->i_buffer
-= 4;
470 memcpy( p_frag
->p_buffer
, startcode
, sizeof(startcode
) );
476 bs_init( &s
, &p_frag
->p_buffer
[4], p_frag
->i_buffer
- 4 );
477 s
.p_fwpriv
= &i_bitflow
;
478 s
.pf_forward
= hxxx_bsfw_ep3b_to_rbsp
; /* Does the emulated 3bytes conversion to rbsp */
480 i_profile
= bs_read( &s
, 2 );
483 const int i_level
= bs_read( &s
, 3 );
485 /* Advanced profile */
486 p_sys
->sh
.b_advanced_profile
= true;
487 p_sys
->sh
.b_range_reduction
= false;
488 p_sys
->sh
.b_has_bframe
= true;
490 bs_skip( &s
, 2+3+5+1 ); // chroma format + frame rate Q + bit rate Q + postprocflag
492 p_es
->video
.i_width
= 2*bs_read( &s
, 12 )+2;
493 p_es
->video
.i_height
= 2*bs_read( &s
, 12 )+2;
495 if( !p_sys
->b_sequence_header
)
496 msg_Dbg( p_dec
, "found sequence header for advanced profile level L%d resolution %dx%d",
497 i_level
, p_es
->video
.i_width
, p_es
->video
.i_height
);
499 bs_skip( &s
, 1 );// pulldown
500 p_sys
->sh
.b_interlaced
= bs_read( &s
, 1 );
501 bs_skip( &s
, 1 );// frame counter
502 p_sys
->sh
.b_frame_interpolation
= bs_read( &s
, 1 );
503 bs_skip( &s
, 1 ); // Reserved
504 bs_skip( &s
, 1 ); // Psf
506 if( bs_read( &s
, 1 ) ) /* Display extension */
508 const int i_display_width
= bs_read( &s
, 14 )+1;
509 const int i_display_height
= bs_read( &s
, 14 )+1;
511 p_es
->video
.i_sar_num
= i_display_width
* p_es
->video
.i_height
;
512 p_es
->video
.i_sar_den
= i_display_height
* p_es
->video
.i_width
;
514 if( !p_sys
->b_sequence_header
)
515 msg_Dbg( p_dec
, "display size %dx%d", i_display_width
, i_display_height
);
517 if( bs_read( &s
, 1 ) ) /* Pixel aspect ratio (PAR/SAR) */
519 static const unsigned p_ar
[16][2] = {
520 { 0, 0}, { 1, 1}, {12,11}, {10,11}, {16,11}, {40,33},
521 {24,11}, {20,11}, {32,11}, {80,33}, {18,11}, {15,11},
522 {64,33}, {160,99},{ 0, 0}, { 0, 0}
524 int i_ar
= bs_read( &s
, 4 );
525 unsigned i_ar_w
, i_ar_h
;
529 i_ar_w
= bs_read( &s
, 8 );
530 i_ar_h
= bs_read( &s
, 8 );
534 i_ar_w
= p_ar
[i_ar
][0];
535 i_ar_h
= p_ar
[i_ar
][1];
537 vlc_ureduce( &i_ar_w
, &i_ar_h
, i_ar_w
, i_ar_h
, 0 );
538 if( !p_sys
->b_sequence_header
)
539 msg_Dbg( p_dec
, "aspect ratio %d:%d", i_ar_w
, i_ar_h
);
542 if( bs_read( &s
, 1 ) ) /* Frame rate */
544 unsigned i_fps_num
= 0;
545 unsigned i_fps_den
= 0;
546 if( bs_read( &s
, 1 ) )
548 i_fps_num
= bs_read( &s
, 16 )+1;
553 const int i_nr
= bs_read( &s
, 8 );
554 const int i_dn
= bs_read( &s
, 4 );
558 case 1: i_fps_num
= 24000; break;
559 case 2: i_fps_num
= 25000; break;
560 case 3: i_fps_num
= 30000; break;
561 case 4: i_fps_num
= 50000; break;
562 case 5: i_fps_num
= 60000; break;
563 case 6: i_fps_num
= 48000; break;
564 case 7: i_fps_num
= 72000; break;
568 case 1: i_fps_den
= 1000; break;
569 case 2: i_fps_den
= 1001; break;
572 if( i_fps_num
!= 0 && i_fps_den
!= 0 )
573 vlc_ureduce( &p_es
->video
.i_frame_rate
, &p_es
->video
.i_frame_rate_base
, i_fps_num
, i_fps_den
, 0 );
575 if( !p_sys
->b_sequence_header
)
576 msg_Dbg( p_dec
, "frame rate %d/%d", p_es
->video
.i_frame_rate
, p_es
->video
.i_frame_rate_base
);
578 if( bs_read1( &s
) ) /* Color Format */
580 switch( bs_read( &s
, 8 ) ) /* Color Primaries */
582 case 1: p_es
->video
.primaries
= COLOR_PRIMARIES_BT709
; break;
583 case 4: p_es
->video
.primaries
= COLOR_PRIMARIES_BT470_M
; break;
584 case 5: p_es
->video
.primaries
= COLOR_PRIMARIES_BT470_BG
; break;
585 case 6: p_es
->video
.primaries
= COLOR_PRIMARIES_SMTPE_RP145
; break;
586 default: p_es
->video
.primaries
= COLOR_PRIMARIES_UNDEF
; break;
589 switch( bs_read( &s
, 8 ) ) /* Transfert Chars */
591 case 1: p_es
->video
.transfer
= TRANSFER_FUNC_BT709
; break;
592 case 4: p_es
->video
.transfer
= TRANSFER_FUNC_BT470_M
; break;
593 case 5: p_es
->video
.transfer
= TRANSFER_FUNC_BT470_BG
; break;
594 case 6: p_es
->video
.transfer
= TRANSFER_FUNC_SMPTE_170
; break;
595 case 7: p_es
->video
.transfer
= TRANSFER_FUNC_SMPTE_240
; break;
596 case 8: p_es
->video
.transfer
= TRANSFER_FUNC_LINEAR
; break;
597 default: p_es
->video
.transfer
= TRANSFER_FUNC_UNDEF
; break;
600 switch( bs_read( &s
, 8 ) ) /* Matrix Coef */
602 case 1: p_es
->video
.space
= COLOR_SPACE_BT709
; break;
603 case 6: p_es
->video
.space
= COLOR_SPACE_BT601
; break;
604 case 7: p_es
->video
.space
= COLOR_SPACE_SMPTE_240
; break;
605 default: p_es
->video
.space
= COLOR_SPACE_UNDEF
; break;
611 /* Simple and main profile */
612 p_sys
->sh
.b_advanced_profile
= false;
613 p_sys
->sh
.b_interlaced
= false;
615 if( !p_sys
->b_sequence_header
)
616 msg_Dbg( p_dec
, "found sequence header for %s profile", i_profile
== 0 ? "simple" : "main" );
618 bs_skip( &s
, 2+3+5+1+1+ // reserved + frame rate Q + bit rate Q + loop filter + reserved
619 1+1+1+1+2+ // multiresolution + reserved + fast uv mc + extended mv + dquant
620 1+1+1+1 ); // variable size transform + reserved + overlap + sync marker
621 p_sys
->sh
.b_range_reduction
= bs_read( &s
, 1 );
622 if( bs_read( &s
, 3 ) > 0 )
623 p_sys
->sh
.b_has_bframe
= true;
625 p_sys
->sh
.b_has_bframe
= false;
626 bs_skip( &s
, 2 ); // quantizer
628 p_sys
->sh
.b_frame_interpolation
= bs_read( &s
, 1 );
630 p_sys
->b_sequence_header
= true;
631 BuildExtraData( p_dec
);
633 else if( idu
== IDU_TYPE_ENTRY_POINT
)
636 block_Release( p_sys
->ep
.p_ep
);
637 p_sys
->ep
.p_ep
= block_Duplicate( p_frag
);
639 if( !p_sys
->b_entry_point
)
640 msg_Dbg( p_dec
, "found entry point" );
642 p_sys
->b_entry_point
= true;
643 BuildExtraData( p_dec
);
645 else if( idu
== IDU_TYPE_FRAME
)
648 unsigned i_bitflow
= 0;
650 /* Parse it + interpolate pts/dts if possible */
651 bs_init( &s
, &p_frag
->p_buffer
[4], p_frag
->i_buffer
- 4 );
652 s
.p_fwpriv
= &i_bitflow
;
653 s
.pf_forward
= hxxx_bsfw_ep3b_to_rbsp
; /* Does the emulated 3bytes conversion to rbsp */
655 if( p_sys
->sh
.b_advanced_profile
)
659 if( p_sys
->sh
.b_interlaced
)
661 if( bs_read( &s
, 1 ) )
663 if( bs_read( &s
, 1 ) )
664 i_fcm
= 1; /* interlaced field */
666 i_fcm
= 2; /* interlaced frame */
670 if( i_fcm
== 1 ) /*interlaced field */
672 /* XXX for mixed I/P we should check reference usage before marking them I (too much work) */
673 switch( bs_read( &s
, 3 ) )
678 p_sys
->p_frame
->i_flags
|= BLOCK_FLAG_TYPE_I
;
679 p_sys
->p_frame
->i_flags
|= BLOCK_FLAG_TYPE_I
;
680 p_sys
->p_frame
->i_flags
|= BLOCK_FLAG_TYPE_I
;
683 p_sys
->p_frame
->i_flags
|= BLOCK_FLAG_TYPE_P
;
689 p_sys
->p_frame
->i_flags
|= BLOCK_FLAG_TYPE_B
;
695 if( !bs_read( &s
, 1 ) )
696 p_sys
->p_frame
->i_flags
|= BLOCK_FLAG_TYPE_P
;
697 else if( !bs_read( &s
, 1 ) )
698 p_sys
->p_frame
->i_flags
|= BLOCK_FLAG_TYPE_B
;
699 else if( !bs_read( &s
, 1 ) )
700 p_sys
->p_frame
->i_flags
|= BLOCK_FLAG_TYPE_I
;
701 else if( !bs_read( &s
, 1 ) )
702 p_sys
->p_frame
->i_flags
|= BLOCK_FLAG_TYPE_B
; /* Bi */
704 p_sys
->p_frame
->i_flags
|= BLOCK_FLAG_TYPE_P
; /* P Skip */
709 if( p_sys
->sh
.b_frame_interpolation
)
710 bs_skip( &s
, 1 ); // interpolate
711 bs_skip( &s
, 2 ); // frame count
712 if( p_sys
->sh
.b_range_reduction
)
713 bs_skip( &s
, 1 ); // range reduction
715 if( bs_read( &s
, 1 ) )
716 p_sys
->p_frame
->i_flags
|= BLOCK_FLAG_TYPE_P
;
717 else if( !p_sys
->sh
.b_has_bframe
|| bs_read( &s
, 1 ) )
718 p_sys
->p_frame
->i_flags
|= BLOCK_FLAG_TYPE_I
;
720 p_sys
->p_frame
->i_flags
|= BLOCK_FLAG_TYPE_B
;
722 p_sys
->b_frame
= true;
724 else if( idu
== IDU_TYPE_FRAME_USER_DATA
)
727 unsigned i_bitflow
= 0;
728 const size_t i_size
= p_frag
->i_buffer
- 4;
729 bs_init( &s
, &p_frag
->p_buffer
[4], i_size
);
730 s
.p_fwpriv
= &i_bitflow
;
731 s
.pf_forward
= hxxx_bsfw_ep3b_to_rbsp
; /* Does the emulated 3bytes conversion to rbsp */
734 uint8_t *p_data
= malloc( i_size
);
737 /* store converted data */
738 for( i_data
= 0; i_data
<i_size
&& bs_remain( &s
) >= 16 /* trailing 0x80 flush byte */; i_data
++ )
739 p_data
[i_data
] = bs_read( &s
, 8 );
741 /* TS 101 154 Auxiliary Data and VC-1 video */
742 static const uint8_t p_DVB1_user_identifier
[] = {
743 0x47, 0x41, 0x39, 0x34 /* user identifier */
746 /* Check if we have DVB1_data() */
747 if( i_data
>= sizeof(p_DVB1_user_identifier
) &&
748 !memcmp( p_data
, p_DVB1_user_identifier
, sizeof(p_DVB1_user_identifier
) ) )
750 cc_ProbeAndExtract( &p_sys
->cc_next
, true, p_data
, i_data
);
758 block_Release( p_release
);
762 /*****************************************************************************
764 *****************************************************************************/
765 static block_t
*GetCc( decoder_t
*p_dec
, bool pb_present
[4], int *pi_reorder_depth
)
767 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
769 *pi_reorder_depth
= p_sys
->cc
.b_reorder
? 4 : -1;
771 for( int i
= 0; i
< 4; i
++ )
772 pb_present
[i
] = p_sys
->cc
.pb_present
[i
];
774 p_cc
= block_Alloc( p_sys
->cc
.i_data
);
777 memcpy( p_cc
->p_buffer
, p_sys
->cc
.p_data
, p_sys
->cc
.i_data
);
779 p_cc
->i_pts
= p_sys
->cc
.b_reorder
? p_sys
->i_cc_pts
: p_sys
->i_cc_dts
;
780 p_cc
->i_flags
= p_sys
->i_cc_flags
& BLOCK_FLAG_TYPE_MASK
;
782 cc_Flush( &p_sys
->cc
);