]> git.sesse.net Git - vlc/blob - modules/packetizer/vc1.c
f8edd3a64548e695236069b17125e08199f86dd0
[vlc] / modules / packetizer / vc1.c
1 /*****************************************************************************
2  * vc1.c
3  *****************************************************************************
4  * Copyright (C) 2001, 2002, 2006 the VideoLAN team
5  * $Id$
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *          Gildas Bazin <gbazin@videolan.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
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 General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24
25 /*****************************************************************************
26  * Preamble
27  *****************************************************************************/
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #endif
32
33 #include <vlc_common.h>
34 #include <vlc_plugin.h>
35 #include <vlc_codec.h>
36 #include <vlc_block.h>
37
38 #include "vlc_bits.h"
39 #include "vlc_block_helper.h"
40 #include "packetizer_helper.h"
41
42 /*****************************************************************************
43  * Module descriptor
44  *****************************************************************************/
45 static int  Open ( vlc_object_t * );
46 static void Close( vlc_object_t * );
47
48 vlc_module_begin ()
49     set_category( CAT_SOUT )
50     set_subcategory( SUBCAT_SOUT_PACKETIZER )
51     set_description( N_("VC-1 packetizer") )
52     set_capability( "packetizer", 50 )
53     set_callbacks( Open, Close )
54 vlc_module_end ()
55
56 /*****************************************************************************
57  * Local prototypes
58  *****************************************************************************/
59 struct decoder_sys_t
60 {
61     /*
62      * Input properties
63      */
64     packetizer_t packetizer;
65
66     /* Current sequence header */
67     bool b_sequence_header;
68     struct
69     {
70         block_t *p_sh;
71         bool b_advanced_profile;
72         bool b_interlaced;
73         bool b_frame_interpolation;
74         bool b_range_reduction;
75         bool b_has_bframe;
76     } sh;
77     bool b_entry_point;
78     struct
79     {
80         block_t *p_ep;
81     } ep;
82
83     /* */
84     bool  b_frame;
85
86     /* Current frame being built */
87     block_t    *p_frame;
88     block_t    **pp_last;
89
90
91     mtime_t i_interpolated_dts;
92 };
93
94 typedef enum
95 {
96     IDU_TYPE_SEQUENCE_HEADER = 0x0f,
97     IDU_TYPE_ENTRY_POINT = 0x0e,
98     IDU_TYPE_FRAME = 0x0D,
99     IDU_TYPE_FIELD = 0x0C,
100     IDU_TYPE_SLICE = 0x0B,
101     IDU_TYPE_END_OF_SEQUENCE = 0x0A,
102
103     IDU_TYPE_SEQUENCE_LEVEL_USER_DATA = 0x1F,
104     IDU_TYPE_ENTRY_POINT_USER_DATA = 0x1E,
105     IDU_TYPE_FRAME_USER_DATA = 0x1D,
106     IDU_TYPE_FIELD_USER_DATA = 0x1C,
107     IDU_TYPE_SLICE_USER_DATA = 0x1B,
108 } idu_type_t;
109
110 static block_t *Packetize( decoder_t *p_dec, block_t **pp_block );
111
112 static void PacketizeReset( void *p_private, bool b_broken );
113 static block_t *PacketizeParse( void *p_private, bool *pb_ts_used, block_t * );
114 static int PacketizeValidate( void *p_private, block_t * );
115
116 static block_t *ParseIDU( decoder_t *p_dec, bool *pb_used_ts, block_t *p_frag );
117
118 static const uint8_t p_vc1_startcode[3] = { 0x00, 0x00, 0x01 };
119 /*****************************************************************************
120  * Open: probe the packetizer and return score
121  *****************************************************************************
122  * Tries to launch a decoder and return score so that the interface is able
123  * to choose.
124  *****************************************************************************/
125 static int Open( vlc_object_t *p_this )
126 {
127     decoder_t     *p_dec = (decoder_t*)p_this;
128     decoder_sys_t *p_sys;
129
130     if( p_dec->fmt_in.i_codec !=  VLC_FOURCC( 'W', 'V', 'C', '1' ) )
131         return VLC_EGENERIC;
132
133     p_dec->pf_packetize = Packetize;
134
135     /* Create the output format */
136     es_format_Copy( &p_dec->fmt_out, &p_dec->fmt_in );
137     p_dec->p_sys = p_sys = malloc( sizeof( decoder_sys_t ) );
138
139     packetizer_Init( &p_sys->packetizer,
140                      p_vc1_startcode, sizeof(p_vc1_startcode),
141                      NULL, 0,
142                      PacketizeReset, PacketizeParse, PacketizeValidate, p_dec );
143
144     p_sys->b_sequence_header = false;
145     p_sys->sh.p_sh = NULL;
146     p_sys->b_entry_point = false;
147     p_sys->ep.p_ep = NULL;
148
149     p_sys->b_frame = false;
150     p_sys->p_frame = NULL;
151     p_sys->pp_last = &p_sys->p_frame;
152
153     p_sys->i_interpolated_dts = -1;
154
155     if( p_dec->fmt_out.i_extra > 0 )
156     {
157         uint8_t *p_extra = p_dec->fmt_out.p_extra;
158
159         /* With (some) ASF the first byte has to be stripped */
160         if( p_extra[0] != 0x00 )
161         {
162             memcpy( &p_extra[0], &p_extra[1], p_dec->fmt_out.i_extra - 1 );
163             p_dec->fmt_out.i_extra--;
164         }
165
166         /* */
167         if( p_dec->fmt_out.i_extra > 0 )
168             packetizer_Header( &p_sys->packetizer,
169                                p_dec->fmt_out.p_extra, p_dec->fmt_out.i_extra );
170     }
171
172     return VLC_SUCCESS;
173 }
174
175 /*****************************************************************************
176  * Close:
177  *****************************************************************************/
178 static void Close( vlc_object_t *p_this )
179 {
180     decoder_t     *p_dec = (decoder_t*)p_this;
181     decoder_sys_t *p_sys = p_dec->p_sys;
182
183     packetizer_Clean( &p_sys->packetizer );
184     if( p_sys->p_frame )
185         block_Release( p_sys->p_frame );
186     free( p_sys );
187 }
188
189 /*****************************************************************************
190  * Packetize: packetize an access unit
191  *****************************************************************************/
192 static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
193 {
194     decoder_sys_t *p_sys = p_dec->p_sys;
195
196     return packetizer_Packetize( &p_sys->packetizer, pp_block );
197 }
198
199 static void PacketizeReset( void *p_private, bool b_broken )
200 {
201     decoder_t *p_dec = p_private;
202     decoder_sys_t *p_sys = p_dec->p_sys;
203
204     if( b_broken )
205     {
206         if( p_sys->p_frame )
207             block_ChainRelease( p_sys->p_frame );
208         p_sys->p_frame = NULL;
209         p_sys->pp_last = &p_sys->p_frame;
210         p_sys->b_frame = false;
211     }
212     p_sys->i_interpolated_dts = 0;
213 }
214 static block_t *PacketizeParse( void *p_private, bool *pb_ts_used, block_t *p_block )
215 {
216     decoder_t *p_dec = p_private;
217
218     return ParseIDU( p_dec, pb_ts_used, p_block );
219 }
220
221 static int PacketizeValidate( void *p_private, block_t *p_au )
222 {
223     decoder_t *p_dec = p_private;
224     decoder_sys_t *p_sys = p_dec->p_sys;
225
226     if( p_sys->i_interpolated_dts < 0 )
227     {
228         msg_Dbg( p_dec, "need a starting pts/dts" );
229         return VLC_EGENERIC;
230     }
231     VLC_UNUSED(p_au);
232     return VLC_SUCCESS;
233 }
234
235
236 /* DecodeRIDU: decode the startcode emulation prevention (same than h264) */
237 static void DecodeRIDU( uint8_t *p_ret, int *pi_ret, uint8_t *src, int i_src )
238 {
239     uint8_t *end = &src[i_src];
240     uint8_t *dst_end = &p_ret[*pi_ret];
241     uint8_t *dst = p_ret;
242
243     while( src < end && dst < dst_end )
244     {
245         if( src < end - 3 && src[0] == 0x00 && src[1] == 0x00 &&
246             src[2] == 0x03 )
247         {
248             *dst++ = 0x00;
249             *dst++ = 0x00;
250
251             src += 3;
252             continue;
253         }
254         *dst++ = *src++;
255     }
256
257     *pi_ret = dst - p_ret;
258 }
259 /* BuildExtraData: gather sequence header and entry point */
260 static void BuildExtraData( decoder_t *p_dec )
261 {
262     decoder_sys_t *p_sys = p_dec->p_sys;
263     es_format_t *p_es = &p_dec->fmt_out;
264     int i_extra;
265     if( !p_sys->b_sequence_header || !p_sys->b_entry_point )
266         return;
267
268     i_extra = p_sys->sh.p_sh->i_buffer + p_sys->ep.p_ep->i_buffer;
269     if( p_es->i_extra != i_extra )
270     {
271         p_es->i_extra = i_extra;
272         p_es->p_extra = realloc( p_dec->fmt_out.p_extra, p_es->i_extra );
273     }
274     memcpy( p_es->p_extra,
275             p_sys->sh.p_sh->p_buffer, p_sys->sh.p_sh->i_buffer );
276     memcpy( (uint8_t*)p_es->p_extra + p_sys->sh.p_sh->i_buffer,
277             p_sys->ep.p_ep->p_buffer, p_sys->ep.p_ep->i_buffer );
278 }
279 /* ParseIDU: parse an Independent Decoding Unit */
280 static block_t *ParseIDU( decoder_t *p_dec, bool *pb_used_ts, block_t *p_frag )
281 {
282     decoder_sys_t *p_sys = p_dec->p_sys;
283     block_t *p_pic;
284     const idu_type_t idu = p_frag->p_buffer[3];
285
286     *pb_used_ts = false;
287     if( !p_sys->b_sequence_header && idu != IDU_TYPE_SEQUENCE_HEADER )
288     {
289         msg_Warn( p_dec, "waiting for sequence header" );
290         block_Release( p_frag );
291         return NULL;
292     }
293     if( p_sys->b_sequence_header && !p_sys->b_entry_point && idu != IDU_TYPE_ENTRY_POINT )
294     {
295         msg_Warn( p_dec, "waiting for entry point" );
296         block_Release( p_frag );
297         return NULL;
298     }
299     /* TODO we do not gather ENTRY_POINT and SEQUENCE_DATA user data
300      * But It should not be a problem for decoder */
301
302     /* Do we have completed a frame */
303     p_pic = NULL;
304     if( p_sys->b_frame &&
305         idu != IDU_TYPE_FRAME_USER_DATA &&
306         idu != IDU_TYPE_FIELD && idu != IDU_TYPE_FIELD_USER_DATA &&
307         idu != IDU_TYPE_SLICE && idu != IDU_TYPE_SLICE_USER_DATA &&
308         idu != IDU_TYPE_END_OF_SEQUENCE )
309     {
310         /* */
311         p_pic = block_ChainGather( p_sys->p_frame );
312
313         /* */
314         if( p_pic->i_dts > 0 )
315             p_sys->i_interpolated_dts = p_pic->i_dts;
316
317         /* We can interpolate dts/pts only if we have a frame rate */
318         if( p_dec->fmt_out.video.i_frame_rate != 0 && p_dec->fmt_out.video.i_frame_rate_base != 0 )
319         {
320             if( p_sys->i_interpolated_dts > 0 )
321                 p_sys->i_interpolated_dts += INT64_C(1000000) *
322                                              p_dec->fmt_out.video.i_frame_rate_base /
323                                              p_dec->fmt_out.video.i_frame_rate;
324
325             //msg_Dbg( p_dec, "-------------- XXX0 dts=%"PRId64" pts=%"PRId64" interpolated=%"PRId64,
326             //         p_pic->i_dts, p_pic->i_pts, p_sys->i_interpolated_dts );
327             if( p_pic->i_dts <= 0 )
328                 p_pic->i_dts = p_sys->i_interpolated_dts;
329
330             if( p_pic->i_pts <= 0 )
331             {
332                 if( !p_sys->sh.b_has_bframe || (p_pic->i_flags & BLOCK_FLAG_TYPE_B ) )
333                     p_pic->i_pts = p_pic->i_dts;
334                 /* TODO compute pts for other case */
335             }
336         }
337
338         //msg_Dbg( p_dec, "-------------- dts=%"PRId64" pts=%"PRId64, p_pic->i_dts, p_pic->i_pts );
339
340         /* Reset context */
341         p_sys->b_frame = false;
342         p_sys->p_frame = NULL;
343         p_sys->pp_last = &p_sys->p_frame;
344     }
345
346     /*  */
347     if( p_sys->p_frame )
348     {
349         block_t *p_frame = p_sys->p_frame;
350         if( p_frame->i_dts <= 0 && p_frame->i_pts <= 0 )
351         {
352             p_frame->i_dts = p_frag->i_dts;
353             p_frame->i_pts = p_frag->i_pts;
354             *pb_used_ts = true;
355         }
356     }
357     block_ChainLastAppend( &p_sys->pp_last, p_frag );
358
359     /* Parse IDU */
360     if( idu == IDU_TYPE_SEQUENCE_HEADER )
361     {
362         es_format_t *p_es = &p_dec->fmt_out;
363         bs_t s;
364         int i_profile;
365         uint8_t ridu[32];
366         int     i_ridu = sizeof(ridu);
367
368         /* */
369         if( p_sys->sh.p_sh )
370             block_Release( p_sys->sh.p_sh );
371         p_sys->sh.p_sh = block_Duplicate( p_frag );
372
373         /* Extract the raw IDU */
374         DecodeRIDU( ridu, &i_ridu, &p_frag->p_buffer[4], p_frag->i_buffer - 4 );
375
376         /* Auto detect VC-1_SPMP_PESpacket_PayloadFormatHeader (SMPTE RP 227) for simple/main profile
377          * TODO find a test case and valid it */
378         if( i_ridu > 4 && (ridu[0]&0x80) == 0 ) /* for advanced profile, the first bit is 1 */
379         {
380             video_format_t *p_v = &p_dec->fmt_in.video;
381             const size_t i_potential_width  = GetWBE( &ridu[0] );
382             const size_t i_potential_height = GetWBE( &ridu[2] );
383
384             if( i_potential_width >= 2  && i_potential_width <= 8192 &&
385                 i_potential_height >= 2 && i_potential_height <= 8192 )
386             {
387                 if( ( p_v->i_width <= 0 && p_v->i_height <= 0  ) ||
388                     ( p_v->i_width  == i_potential_width &&  p_v->i_height == i_potential_height ) )
389                 {
390                     static const uint8_t startcode[4] = { 0x00, 0x00, 0x01, IDU_TYPE_SEQUENCE_HEADER };
391                     p_es->video.i_width  = i_potential_width;
392                     p_es->video.i_height = i_potential_height;
393
394                     /* Remove it */
395                     p_frag->p_buffer += 4;
396                     p_frag->i_buffer -= 4;
397                     memcpy( p_frag->p_buffer, startcode, sizeof(startcode) );
398                 }
399             }
400         }
401
402         /* Parse it */
403         bs_init( &s, ridu, i_ridu );
404         i_profile = bs_read( &s, 2 );
405         if( i_profile == 3 )
406         {
407             const int i_level = bs_read( &s, 3 );
408
409             /* Advanced profile */
410             p_sys->sh.b_advanced_profile = true;
411             p_sys->sh.b_range_reduction = false;
412             p_sys->sh.b_has_bframe = true;
413
414             bs_skip( &s, 2+3+5+1 ); // chroma format + frame rate Q + bit rate Q + postprocflag
415
416             p_es->video.i_width  = 2*bs_read( &s, 12 )+2;
417             p_es->video.i_height = 2*bs_read( &s, 12 )+2;
418
419             if( !p_sys->b_sequence_header )
420                 msg_Dbg( p_dec, "found sequence header for advanced profile level L%d resolution %dx%d",
421                          i_level, p_es->video.i_width, p_es->video.i_height);
422
423             bs_skip( &s, 1 );// pulldown
424             p_sys->sh.b_interlaced = bs_read( &s, 1 );
425             bs_skip( &s, 1 );// frame counter
426             p_sys->sh.b_frame_interpolation = bs_read( &s, 1 );
427             bs_skip( &s, 1 );       // Reserved
428             bs_skip( &s, 1 );       // Psf
429
430             if( bs_read( &s, 1 ) )  /* Display extension */
431             {
432                 const int i_display_width  = bs_read( &s, 14 )+1;
433                 const int i_display_height = bs_read( &s, 14 )+1;
434
435                 p_es->video.i_aspect = VOUT_ASPECT_FACTOR * i_display_width / i_display_height;
436
437                 if( !p_sys->b_sequence_header )
438                     msg_Dbg( p_dec, "display size %dx%d", i_display_width, i_display_height );
439
440                 if( bs_read( &s, 1 ) )  /* Pixel aspect ratio (PAR/SAR) */
441                 {
442                     static const int p_ar[16][2] = {
443                         { 0, 0}, { 1, 1}, {12,11}, {10,11}, {16,11}, {40,33},
444                         {24,11}, {20,11}, {32,11}, {80,33}, {18,11}, {15,11},
445                         {64,33}, {160,99},{ 0, 0}, { 0, 0}
446                     };
447                     int i_ar = bs_read( &s, 4 );
448                     unsigned i_ar_w, i_ar_h;
449
450                     if( i_ar == 15 )
451                     {
452                         i_ar_w = bs_read( &s, 8 );
453                         i_ar_h = bs_read( &s, 8 );
454                     }
455                     else
456                     {
457                         i_ar_w = p_ar[i_ar][0];
458                         i_ar_h = p_ar[i_ar][1];
459                     }
460                     vlc_ureduce( &i_ar_w, &i_ar_h, i_ar_w, i_ar_h, 0 );
461                     if( !p_sys->b_sequence_header )
462                         msg_Dbg( p_dec, "aspect ratio %d:%d", i_ar_w, i_ar_h );
463                 }
464             }
465             if( bs_read( &s, 1 ) )  /* Frame rate */
466             {
467                 int i_fps_num = 0;
468                 int i_fps_den = 0;
469                 if( bs_read( &s, 1 ) )
470                 {
471                     i_fps_num = bs_read( &s, 16 )+1;
472                     i_fps_den = 32;
473                 }
474                 else
475                 {
476                     const int i_nr = bs_read( &s, 8 );
477                     const int i_dn = bs_read( &s, 4 );
478
479                     switch( i_nr )
480                     {
481                     case 1: i_fps_num = 24000; break;
482                     case 2: i_fps_num = 25000; break;
483                     case 3: i_fps_num = 30000; break;
484                     case 4: i_fps_num = 50000; break;
485                     case 5: i_fps_num = 60000; break;
486                     case 6: i_fps_num = 48000; break;
487                     case 7: i_fps_num = 72000; break;
488                     }
489                     switch( i_dn )
490                     {
491                     case 1: i_fps_den = 1000; break;
492                     case 2: i_fps_den = 1001; break;
493                     }
494                 }
495                 if( i_fps_num != 0 && i_fps_den != 0 )
496                     vlc_ureduce( &p_es->video.i_frame_rate, &p_es->video.i_frame_rate_base, i_fps_num, i_fps_den, 0 );
497
498                 if( !p_sys->b_sequence_header )
499                     msg_Dbg( p_dec, "frame rate %d/%d", p_es->video.i_frame_rate, p_es->video.i_frame_rate_base );
500             }
501         }
502         else
503         {
504             /* Simple and main profile */
505             p_sys->sh.b_advanced_profile = false;
506             p_sys->sh.b_interlaced = false;
507
508             if( !p_sys->b_sequence_header )
509                 msg_Dbg( p_dec, "found sequence header for %s profile", i_profile == 0 ? "simple" : "main" );
510
511             bs_skip( &s, 2+3+5+1+1+     // reserved + frame rate Q + bit rate Q + loop filter + reserved
512                          1+1+1+1+2+     // multiresolution + reserved + fast uv mc + extended mv + dquant
513                          1+1+1+1 );     // variable size transform + reserved + overlap + sync marker
514             p_sys->sh.b_range_reduction = bs_read( &s, 1 );
515             if( bs_read( &s, 3 ) > 0 )
516                 p_sys->sh.b_has_bframe = true;
517             else
518                 p_sys->sh.b_has_bframe = false;
519             bs_skip( &s, 2 );           // quantizer
520
521             p_sys->sh.b_frame_interpolation = bs_read( &s, 1 );
522         }
523         p_sys->b_sequence_header = true;
524         BuildExtraData( p_dec );
525     }
526     else if( idu == IDU_TYPE_ENTRY_POINT )
527     {
528         if( p_sys->ep.p_ep )
529             block_Release( p_sys->ep.p_ep );
530         p_sys->ep.p_ep = block_Duplicate( p_frag );
531
532         p_sys->b_entry_point = true;
533         BuildExtraData( p_dec );
534     }
535     else if( idu == IDU_TYPE_FRAME )
536     {
537         bs_t s;
538         uint8_t ridu[8];
539         int     i_ridu = sizeof(ridu);
540
541         /* Extract the raw IDU */
542         DecodeRIDU( ridu, &i_ridu, &p_frag->p_buffer[4], p_frag->i_buffer - 4 );
543
544         /* Parse it + interpolate pts/dts if possible */
545         bs_init( &s, ridu, i_ridu );
546
547         if( p_sys->sh.b_advanced_profile )
548         {
549             int i_fcm = 0;
550
551             if( p_sys->sh.b_interlaced )
552             {
553                 if( bs_read( &s, 1 ) )
554                 {
555                     if( bs_read( &s, 1 ) )
556                         i_fcm = 1;  /* interlaced field */
557                     else
558                         i_fcm = 2;  /* interlaced frame */
559                 }
560             }
561
562             if( i_fcm == 1 ) /*interlaced field */
563             {
564                 /* XXX for mixed I/P we should check reference usage before marking them I (too much work) */
565                 switch( bs_read( &s, 3 ) )
566                 {
567                 case 0: /* II */
568                 case 1: /* IP */
569                 case 2: /* PI */
570                     p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_I;
571                     p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_I;
572                     p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_I;
573                     break;
574                 case 3: /* PP */
575                     p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_P;
576                     break;
577                 case 4: /* BB */
578                 case 5: /* BBi */
579                 case 6: /* BiB */
580                 case 7: /* BiBi */
581                     p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_B;
582                     break;
583                 }
584             }
585             else
586             {
587                 if( !bs_read( &s, 1 ) )
588                     p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_P;
589                 else if( !bs_read( &s, 1 ) )
590                     p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_B;
591                 else if( !bs_read( &s, 1 ) )
592                     p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_I;
593                 else if( !bs_read( &s, 1 ) )
594                     p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_B;   /* Bi */
595                 else
596                     p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_P;   /* P Skip */
597             }
598         }
599         else
600         {
601             if( p_sys->sh.b_frame_interpolation )
602                 bs_skip( &s, 1 );   // interpolate
603             bs_skip( &s, 2 );       // frame count
604             if( p_sys->sh.b_range_reduction )
605                 bs_skip( &s, 1 );   // range reduction
606
607             if( bs_read( &s, 1 ) )
608                 p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_P;
609             else if( !p_sys->sh.b_has_bframe || bs_read( &s, 1 ) )
610                 p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_I;
611             else
612                 p_sys->p_frame->i_flags |= BLOCK_FLAG_TYPE_B;
613         }
614         p_sys->b_frame = true;
615     }
616     return p_pic;
617 }
618