static int _parse_app_info(BITSTREAM *bs, INDX_APP_INFO *app_info)
{
    uint32_t len;

    if (bs_seek_byte(bs, 40) < 0) {
        return 0;
    }

    len = bs_read(bs, 32);

    if (len != 34) {
        BD_DEBUG(DBG_NAV, "index.bdmv app_info length is %d, expected 34 !\n", len);
    }

    bs_skip(bs, 1);
    app_info->initial_output_mode_preference = bs_read(bs, 1);
    app_info->content_exist_flag             = bs_read(bs, 1);
    bs_skip(bs, 5);

    app_info->video_format = bs_read(bs, 4);
    app_info->frame_rate   = bs_read(bs, 4);

    bs_read_bytes(bs, app_info->user_data, 32);

    return 1;
}
Beispiel #2
0
static int32_t getFPS( demux_t *p_demux, block_t * p_block )
{
    demux_sys_t *p_sys = p_demux->p_sys;

    bs_t bs;
    uint8_t * p_decoded_nal;
    int i_decoded_nal;

    if( p_block->i_buffer < 5 )
        return -1;

    p_decoded_nal = CreateDecodedNAL(&i_decoded_nal,
                                     p_block->p_buffer+4, p_block->i_buffer-4);

    if( !p_decoded_nal )
        return -1;

    bs_init( &bs, p_decoded_nal, i_decoded_nal );
    bs_skip( &bs, 12 );
    int32_t max_sub_layer_minus1 = bs_read( &bs, 3 );
    bs_skip( &bs, 17 );

    hevc_skip_profile_tiers_level( &bs, max_sub_layer_minus1 );

    int32_t vps_sub_layer_ordering_info_present_flag = bs_read1( &bs );
    int32_t i = vps_sub_layer_ordering_info_present_flag? 0 : max_sub_layer_minus1;
    for( ; i <= max_sub_layer_minus1; i++ )
    {
        bs_read_ue( &bs );
        bs_read_ue( &bs );
        bs_read_ue( &bs );
    }
    uint32_t vps_max_layer_id = bs_read( &bs, 6);
    uint32_t vps_num_layer_sets_minus1 = bs_read_ue( &bs );
    bs_skip( &bs, vps_max_layer_id * vps_num_layer_sets_minus1 );

    if( bs_read1( &bs ))
    {
        uint32_t num_units_in_tick = bs_read( &bs, 32 );
        uint32_t time_scale = bs_read( &bs, 32 );
        if( num_units_in_tick )
        {
            p_sys->f_fps = ( (float) time_scale )/( (float) num_units_in_tick );
            msg_Dbg(p_demux,"Using framerate %f fps from VPS",
                    (double) p_sys->f_fps);
        }
        else
        {
            msg_Err( p_demux, "vps_num_units_in_tick null defaulting to 25 fps");
            p_sys->f_fps = 25.0f;
        }
    }
    else
    {
        msg_Err( p_demux, "No timing info in VPS defaulting to 25 fps");
        p_sys->f_fps = 25.0f;
    }
    free(p_decoded_nal);
    return 0;
}
Beispiel #3
0
/* Parse WMV3 packet and extract frame type information */
static void ParseWMV3( decoder_t *p_dec, block_t *p_block )
{
    bs_t s;

    /* Parse Sequence header */
    bs_init( &s, p_dec->fmt_in.p_extra, p_dec->fmt_in.i_extra );
    if( bs_read( &s, 2 ) == 3 )
        return;
    bs_skip( &s, 22 );
    const bool b_range_reduction = bs_read( &s, 1 );
    const bool b_has_frames = bs_read( &s, 3 ) > 0;
    bs_skip( &s, 2 );
    const bool b_frame_interpolation = bs_read( &s, 1 );
    if( bs_eof( &s ) )
        return;

    /* Parse frame type */
    bs_init( &s, p_block->p_buffer, p_block->i_buffer );
    bs_skip( &s, b_frame_interpolation +
                 2 +
                 b_range_reduction );

    p_block->i_flags &= ~BLOCK_FLAG_TYPE_MASK;
    if( bs_read( &s, 1 ) )
        p_block->i_flags |= BLOCK_FLAG_TYPE_P;
    else if( !b_has_frames || bs_read( &s, 1 ) )
        p_block->i_flags |= BLOCK_FLAG_TYPE_I;
    else
        p_block->i_flags |= BLOCK_FLAG_TYPE_B;
}
Beispiel #4
0
void bd_mpls_mark_Parse( bd_mpls_mark_t *p_mark, bs_t *s )
{
    bs_skip( s, 8 );
    p_mark->i_type = bs_read( s, 8 );
    p_mark->i_play_item_id = bs_read( s, 16 );
    p_mark->i_time = bs_read( s, 32 );
    p_mark->i_entry_es_pid = bs_read( s, 16 );
    bs_skip( s, 32 );
}
int bd_clpi_ep_map_Parse( bd_clpi_ep_map_t *p_ep_map,
                          bs_t *s, const int i_ep_map_start )
{
    p_ep_map->i_pid = bs_read( s, 16 );
    bs_skip( s, 10 );
    p_ep_map->i_type = bs_read( s, 4 );

    const int i_coarse = bs_read( s, 16 );
    const int i_fine = bs_read( s, 18 );
    const uint32_t i_coarse_start = bs_read( s, 32 );

    p_ep_map->i_ep = i_fine;
    p_ep_map->p_ep = (bd_clpi_ep_t *)calloc( i_fine, sizeof(*p_ep_map->p_ep) );			// sunqueen modify
    if( !p_ep_map->p_ep )
        return VLC_EGENERIC;

    bs_t cs = *s;
    bs_skip( &cs, 8*(i_ep_map_start + i_coarse_start) - bs_pos( s ) );

    const uint32_t i_fine_start = bs_read( &cs, 32 );

    for( int i = 0; i < i_coarse; i++ )
    {
        const int      i_fine_id = bs_read( &cs, 18 );
        const int      i_pts = bs_read( &cs, 14 );
        const uint32_t i_packet = bs_read( &cs, 32 );

        for( int j = i_fine_id; j < p_ep_map->i_ep; j++ )
        {
            p_ep_map->p_ep[j].i_pts = (int64_t)(i_pts & ~1) << 19;
            p_ep_map->p_ep[j].i_packet = i_packet & ~( (1 << 17) - 1 );
        }
    }

    bs_t fs = *s;
    bs_skip( &fs, 8*(i_ep_map_start + i_coarse_start + i_fine_start) - bs_pos( s ) );
    for( int i = 0; i < i_fine; i++ )
    {
        const bool b_angle_point = bs_read( &fs, 1 );
        bs_skip( &fs, 3 );  /* I end position offset */
        const int i_pts = bs_read( &fs, 11 );
        const int i_packet = bs_read( &fs, 17 );

        p_ep_map->p_ep[i].b_angle_point = b_angle_point;
        p_ep_map->p_ep[i].i_pts |= i_pts << 9;
        p_ep_map->p_ep[i].i_packet |= i_packet;
    }
    return VLC_SUCCESS;
}
Beispiel #6
0
static int _parse_hdmv_obj(BITSTREAM *bs, INDX_HDMV_OBJ *hdmv)
{
    hdmv->playback_type = bs_read(bs, 2);
    bs_skip(bs, 14);
    hdmv->id_ref = bs_read(bs, 16);
    bs_skip(bs, 32);

    if (hdmv->playback_type != indx_hdmv_playback_type_movie &&
        hdmv->playback_type != indx_hdmv_playback_type_interactive) {

        BD_DEBUG(DBG_NAV | DBG_CRIT, "index.bdmv: invalid HDMV playback type %d\n", hdmv->playback_type);
    }

    return 1;
}
Beispiel #7
0
static int _parse_bdj_obj(BITSTREAM *bs, INDX_BDJ_OBJ *bdj)
{
    bdj->playback_type = bs_read(bs, 2);
    bs_skip(bs, 14);
    bs_read_string(bs, bdj->name, 5);
    bs_skip(bs, 8);

    if (bdj->playback_type != indx_bdj_playback_type_movie &&
        bdj->playback_type != indx_bdj_playback_type_interactive) {

        BD_DEBUG(DBG_NAV | DBG_CRIT, "index.bdmv: invalid BD-J playback type %d\n", bdj->playback_type);
    }

    return 1;
}
Beispiel #8
0
static void PutPPS( decoder_t *p_dec, block_t *p_frag )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    bs_t s;
    int i_pps_id;
    int i_sps_id;

    bs_init( &s, &p_frag->p_buffer[5], p_frag->i_buffer - 5 );
    i_pps_id = bs_read_ue( &s ); // pps id
    i_sps_id = bs_read_ue( &s ); // sps id
    if( i_pps_id >= PPS_MAX || i_sps_id >= SPS_MAX )
    {
        msg_Warn( p_dec, "invalid PPS (pps_id=%d sps_id=%d)", i_pps_id, i_sps_id );
        block_Release( p_frag );
        return;
    }
    bs_skip( &s, 1 ); // entropy coding mode flag
    p_sys->i_pic_order_present_flag = bs_read( &s, 1 );
    /* TODO */

    /* We have a new PPS */
    if( !p_sys->b_pps )
        msg_Dbg( p_dec, "found NAL_PPS (pps_id=%d sps_id=%d)", i_pps_id, i_sps_id );
    p_sys->b_pps = true;

    if( p_sys->pp_pps[i_pps_id] )
        block_Release( p_sys->pp_pps[i_pps_id] );
    p_sys->pp_pps[i_pps_id] = p_frag;
}
Beispiel #9
0
static int _mobj_parse_object(BITSTREAM *bs, MOBJ_OBJECT *obj)
{
    int i;

    obj->resume_intention_flag = bs_read(bs, 1);
    obj->menu_call_mask = bs_read(bs, 1);
    obj->title_search_mask = bs_read(bs, 1);

    bs_skip(bs, 13); /* padding */

    obj->num_cmds = bs_read(bs, 16);
    obj->cmds     = calloc(obj->num_cmds, sizeof(MOBJ_CMD));
    if (!obj->cmds) {
        BD_DEBUG(DBG_CRIT, "out of memory\n");
        return 0;
    }

    for (i = 0; i < obj->num_cmds; i++) {
        uint8_t buf[12];
        bs_read_bytes(bs, buf, 12);
        mobj_parse_cmd(buf, &obj->cmds[i]);
    }

    return 1;
}
static int _parse_index(BITSTREAM *bs, INDX_ROOT *index)
{
    uint32_t index_len, i;

    index_len = bs_read(bs, 32);

    /* TODO: check if goes to extension data area */

    if ((bs_end(bs) - bs_pos(bs))/8 < (int64_t)index_len) {
        BD_DEBUG(DBG_NAV | DBG_CRIT, "index.bdmv: invalid index_len %d !\n", index_len);
        return 0;
    }

    if (!_parse_playback_obj(bs, &index->first_play) ||
        !_parse_playback_obj(bs, &index->top_menu)) {
        return 0;
    }

    index->num_titles = bs_read(bs, 16);
    if (!index->num_titles) {
        BD_DEBUG(DBG_CRIT, "empty index\n");
        return 0;
    }

    index->titles = calloc(index->num_titles, sizeof(INDX_TITLE));
    if (!index->titles) {
        BD_DEBUG(DBG_CRIT, "out of memory\n");
        return 0;
    }

    if (bs_avail(bs)/(12*8) < index->num_titles) {
        BD_DEBUG(DBG_HDMV|DBG_CRIT, "index.bdmv: unexpected EOF\n");
        return 0;
    }

    for (i = 0; i < index->num_titles; i++) {

        index->titles[i].object_type = bs_read(bs, 2);
        index->titles[i].access_type = bs_read(bs, 2);
        bs_skip(bs, 28);

        switch (index->titles[i].object_type) {
            case indx_object_type_hdmv:
                if (!_parse_hdmv_obj(bs, &index->titles[i].hdmv))
                    return 0;
                break;

            case indx_object_type_bdj:
                if (!_parse_bdj_obj(bs, &index->titles[i].bdj))
                    return 0;
                break;

            default:
                BD_DEBUG(DBG_NAV | DBG_CRIT, "index.bdmv: unknown object type %d (#%d)\n", index->titles[i].object_type, i);
                return 0;
        }
    }

    return 1;
}
Beispiel #11
0
/*****************************************************************************
 * parse_data_group
 *****************************************************************************
 * ARIB STD-B24 VOLUME 1 Part 3 Chapter 9.2 Structure of data group
 *****************************************************************************/
static void parse_data_group( arib_parser_t *p_parser, bs_t *p_bs )
{
    uint8_t i_data_group_id = bs_read( p_bs, 6 );
    bs_skip( p_bs, 2 ); /* i_data_group_version */
    bs_skip( p_bs, 8 ); /* i_data_group_link_number */ 
    bs_skip( p_bs, 8 ); /* i_last_data_group_link_number */
    bs_skip( p_bs, 16 ); /* i_data_group_size */

    if( i_data_group_id == 0x00 || i_data_group_id == 0x20 )
    {
        parse_caption_management_data( p_parser, p_bs );
    }
    else
    {
        parse_caption_statement_data( p_parser, p_bs );
    }
}
Beispiel #12
0
static block_t *PacketizeParse(void *p_private, bool *pb_ts_used, block_t *p_block)
{
    decoder_t *p_dec = p_private;
    decoder_sys_t *p_sys = p_dec->p_sys;

    block_t * p_nal = NULL;

    while (p_block->i_buffer > 5 && p_block->p_buffer[p_block->i_buffer-1] == 0x00 )
        p_block->i_buffer--;

    bs_t bs;
    bs_init(&bs, p_block->p_buffer+3, p_block->i_buffer-3);

    /* Get NALU type */
    uint32_t forbidden_zero_bit = bs_read1(&bs);

    if (forbidden_zero_bit)
    {
        msg_Err(p_dec,"Forbidden zero bit not null, corrupted NAL");
        p_sys->p_frame = NULL;
        p_sys->b_vcl = false;
        return NULL;
    }
    uint32_t nalu_type = bs_read(&bs,6);
    bs_skip(&bs, 9);

    if (nalu_type < VPS)
    {
        /* NAL is a VCL NAL */
        p_sys->b_vcl = true;

        uint32_t first_slice_in_pic = bs_read1(&bs);

        if (first_slice_in_pic && p_sys->p_frame)
        {
            p_nal = block_ChainGather(p_sys->p_frame);
            p_sys->p_frame = NULL;
        }

        block_ChainAppend(&p_sys->p_frame, p_block);
    }
    else
    {
        if (p_sys->b_vcl)
        {
            p_nal = block_ChainGather(p_sys->p_frame);
            p_nal->p_next = p_block;
            p_sys->p_frame = NULL;
            p_sys->b_vcl =false;
        }
        else
            p_nal = p_block;
    }

    *pb_ts_used = false;
    return p_nal;
}
Beispiel #13
0
static MOBJ_OBJECTS *_mobj_parse(BD_FILE_H *fp)
{
    BITSTREAM     bs;
    MOBJ_OBJECTS *objects = NULL;
    uint16_t      num_objects;
    uint32_t      data_len;
    int           extension_data_start, i;

    bs_init(&bs, fp);

    if (!_mobj_parse_header(&bs, &extension_data_start)) {
        BD_DEBUG(DBG_NAV | DBG_CRIT, "MovieObject.bdmv: invalid header\n");
        goto error;
    }

    if (extension_data_start) {
        BD_DEBUG(DBG_NAV | DBG_CRIT, "MovieObject.bdmv: unknown extension data at %d\n", extension_data_start);
    }

    bs_seek_byte(&bs, 40);

    data_len = bs_read(&bs, 32);

    if ((bs_end(&bs) - bs_pos(&bs))/8 < (int64_t)data_len) {
        BD_DEBUG(DBG_NAV | DBG_CRIT, "MovieObject.bdmv: invalid data_len %d !\n", data_len);
        goto error;
    }

    objects = calloc(1, sizeof(MOBJ_OBJECTS));
    if (!objects) {
        BD_DEBUG(DBG_CRIT, "out of memory\n");
        goto error;
    }

    bs_skip(&bs, 32); /* reserved */
    num_objects = bs_read(&bs, 16);

    objects->num_objects = num_objects;
    objects->objects = calloc(num_objects, sizeof(MOBJ_OBJECT));
    if (!objects->objects) {
        BD_DEBUG(DBG_CRIT, "out of memory\n");
        goto error;
    }

    for (i = 0; i < objects->num_objects; i++) {
        if (!_mobj_parse_object(&bs, &objects->objects[i])) {
            BD_DEBUG(DBG_NAV | DBG_CRIT, "MovieObject.bdmv: error parsing object %d\n", i);
            goto error;
        }
    }

    return objects;

 error:
    mobj_free(&objects);
    return NULL;
}
Beispiel #14
0
static void parse_data_unit_others( arib_parser_t *p_parser, bs_t *p_bs,
                                    uint8_t i_data_unit_parameter,
                                    uint32_t i_data_unit_size )
{
    for( uint32_t i = 0; i < i_data_unit_size; i++ )
    {
        bs_skip( p_bs, 8 );
        p_parser->i_data_unit_size += 1;
    }
}
Beispiel #15
0
static MOBJ_OBJECTS *_mobj_parse(const char *file_name)
{
    BITSTREAM     bs;
    BD_FILE_H    *fp;
    MOBJ_OBJECTS *objects = NULL;
    uint16_t      num_objects;
    uint32_t      data_len;
    int           extension_data_start, i;

    fp = file_open(file_name, "rb");
    if (!fp) {
      BD_DEBUG(DBG_NAV | DBG_CRIT, "error opening %s\n", file_name);
      return NULL;
    }

    bs_init(&bs, fp);

    if (!_mobj_parse_header(&bs, &extension_data_start)) {
        BD_DEBUG(DBG_NAV | DBG_CRIT, "%s: invalid header\n", file_name);
        goto error;
    }

    bs_seek_byte(&bs, 40);

    data_len = bs_read(&bs, 32);

    if ((bs_end(&bs) - bs_pos(&bs))/8 < (off_t)data_len) {
        BD_DEBUG(DBG_NAV | DBG_CRIT, "%s: invalid data_len %d !\n", file_name, data_len);
        goto error;
    }

    bs_skip(&bs, 32); /* reserved */
    num_objects = bs_read(&bs, 16);

    objects = calloc(1, sizeof(MOBJ_OBJECTS));
    objects->num_objects = num_objects;
    objects->objects = calloc(num_objects, sizeof(MOBJ_OBJECT));

    for (i = 0; i < objects->num_objects; i++) {
        if (!_mobj_parse_object(&bs, &objects->objects[i])) {
            BD_DEBUG(DBG_NAV | DBG_CRIT, "%s: error parsing object %d\n", file_name, i);
            goto error;
        }
    }

    file_close(fp);

    return objects;

 error:
    mobj_free(&objects);
    file_close(fp);
    return NULL;
}
void bd_clpi_stream_Parse( bd_clpi_stream_t *p_stream, bs_t *s )
{
    p_stream->i_pid = bs_read( s, 16 );

    const int i_length = bs_read( s, 8 );

    p_stream->i_type = bs_read( s, 8 );

    /* Ignore the rest */
    if( i_length > 1 )
        bs_skip( s, 8*i_length - 8 );
}
Beispiel #17
0
/*****************************************************************************
 * arib_parse_pes
 *****************************************************************************
 * ARIB STD-B24 VOLUME3 Chapter 5 Independent PES transmission protocol
 *****************************************************************************/
void arib_parse_pes( arib_parser_t *p_parser, const void *p_data, size_t i_data )
{
    bs_t bs;
    bs_init( &bs, p_data, i_data );
    uint8_t i_data_group_id = bs_read( &bs, 8 );
    if( i_data_group_id != 0x80 && i_data_group_id != 0x81 )
    {
        return;
    }
    uint8_t i_private_stream_id = bs_read( &bs, 8 );
    if( i_private_stream_id != 0xFF )
    {
        return;
    }
    bs_skip( &bs, 4 ); /* reserved */
    uint8_t i_PES_data_packet_header_length= bs_read( &bs, 4 );

     /* skip PES_data_private_data_byte */
    bs_skip( &bs, i_PES_data_packet_header_length );

    parse_data_group( p_parser, &bs );
}
Beispiel #18
0
static bool h264_parse_picture_parameter_set_rbsp( bs_t *p_bs,
                                                   h264_picture_parameter_set_t *p_pps )
{
    p_pps->i_id = bs_read_ue( p_bs ); // pps id
    p_pps->i_sps_id = bs_read_ue( p_bs ); // sps id
    if( p_pps->i_id >= H264_PPS_MAX || p_pps->i_sps_id >= H264_SPS_MAX )
        return false;

    bs_skip( p_bs, 1 ); // entropy coding mode flag
    p_pps->i_pic_order_present_flag = bs_read( p_bs, 1 );
    /* TODO */

    return true;
}
Beispiel #19
0
void bd_mpls_sub_path_Parse( bd_mpls_sub_path_t *p_path, bs_t *s )
{
    const uint32_t i_length = bs_read( s, 32 );
    const int i_start = bs_pos( s ) / 8;

    bs_skip( s, 8 );
    p_path->i_type = bs_read( s, 8 );
    bs_skip( s, 15 );
    p_path->b_repeat = bs_read( s, 1 );
    bs_skip( s, 8 );
    p_path->i_item = bs_read( s, 8 );

    for( int j = 0; j < p_path->i_item; j++ )
    {
        const int i_length = bs_read( s, 16 );
        const int i_start = bs_pos( s ) / 8;

        /* TODO */

        bs_skip( s, 8 * ( i_start + i_length ) - bs_pos( s ) );
    }

    bs_skip( s, 8 * ( i_start + i_length ) - bs_pos( s ) );
}
Beispiel #20
0
/*****************************************************************************
 * parse_caption_data
 *****************************************************************************
 * ARIB STD-B24 VOLUME 1 Part 3 Chapter 9.3.2 Caption statement data
 *****************************************************************************/
static void parse_caption_statement_data( arib_parser_t *p_parser, bs_t *p_bs )
{
    uint8_t i_TMD = bs_read( p_bs, 2 );
    bs_skip( p_bs, 6 ); /* Reserved */
    if( i_TMD == 0x01 /* 01 */ || i_TMD == 0x02 /* 10 */ )
    {
        bs_skip( p_bs, 32 ); /* STM << 4 */
        bs_skip( p_bs, 4 ); /* STM & 15 */
        bs_skip( p_bs, 4 ); /* Reserved */
    }
    uint32_t i_data_unit_loop_length = bs_read( p_bs, 24 );
    free( p_parser->psz_subtitle_data );
    p_parser->i_subtitle_data_size = 0;
    p_parser->psz_subtitle_data = NULL;
    if( i_data_unit_loop_length > 0 )
    {
        p_parser->psz_subtitle_data = (unsigned char*) calloc(
                i_data_unit_loop_length + 1, sizeof(unsigned char) );
    }
    while( p_parser->i_data_unit_size < i_data_unit_loop_length )
    {
        parse_data_unit( p_parser, p_bs );
    }
}
Beispiel #21
0
static int _parse_playback_obj(BITSTREAM *bs, INDX_PLAY_ITEM *obj)
{
    obj->object_type = bs_read(bs, 2);
    bs_skip(bs, 30);

    switch (obj->object_type) {
        case indx_object_type_hdmv:
            return _parse_hdmv_obj(bs, &obj->hdmv);

        case indx_object_type_bdj:
            return _parse_bdj_obj(bs, &obj->bdj);
    }

    BD_DEBUG(DBG_NAV | DBG_CRIT, "index.bdmv: unknown object type %d\n", obj->object_type);
    return 0;
}
Beispiel #22
0
int h264_parse_pps( const uint8_t *p_pps_buf, int i_pps_size,
                    struct nal_pps *p_pps )
{
    bs_t s;

    if (i_pps_size < 5 || (p_pps_buf[4] & 0x1f) != NAL_PPS)
        return -1;

    memset( p_pps, 0, sizeof(struct nal_pps) );
    bs_init( &s, &p_pps_buf[5], i_pps_size - 5 );
    p_pps->i_id = bs_read_ue( &s ); // pps id
    p_pps->i_sps_id = bs_read_ue( &s ); // sps id
    if( p_pps->i_id >= PPS_MAX || p_pps->i_sps_id >= SPS_MAX )
    {
        return -1;
    }
    bs_skip( &s, 1 ); // entropy coding mode flag
    p_pps->i_pic_order_present_flag = bs_read( &s, 1 );
    /* TODO */

    return 0;
}
Beispiel #23
0
static bool h264_parse_sequence_parameter_set_rbsp( bs_t *p_bs,
                                                    h264_sequence_parameter_set_t *p_sps )
{
    int i_tmp;

    int i_profile_idc = bs_read( p_bs, 8 );
    p_sps->i_profile = i_profile_idc;
    p_sps->i_constraint_set_flags = bs_read( p_bs, 8 );
    p_sps->i_level = bs_read( p_bs, 8 );
    /* sps id */
    uint32_t i_sps_id = bs_read_ue( p_bs );
    if( i_sps_id > H264_SPS_ID_MAX )
        return false;
    p_sps->i_id = i_sps_id;

    if( i_profile_idc == PROFILE_H264_HIGH ||
        i_profile_idc == PROFILE_H264_HIGH_10 ||
        i_profile_idc == PROFILE_H264_HIGH_422 ||
        i_profile_idc == PROFILE_H264_HIGH_444 || /* Old one, no longer on spec */
        i_profile_idc == PROFILE_H264_HIGH_444_PREDICTIVE ||
        i_profile_idc == PROFILE_H264_CAVLC_INTRA ||
        i_profile_idc == PROFILE_H264_SVC_BASELINE ||
        i_profile_idc == PROFILE_H264_SVC_HIGH ||
        i_profile_idc == PROFILE_H264_MVC_MULTIVIEW_HIGH ||
        i_profile_idc == PROFILE_H264_MVC_STEREO_HIGH ||
        i_profile_idc == PROFILE_H264_MVC_MULTIVIEW_DEPTH_HIGH ||
        i_profile_idc == PROFILE_H264_MVC_ENHANCED_MULTIVIEW_DEPTH_HIGH ||
        i_profile_idc == PROFILE_H264_MFC_HIGH )
    {
        /* chroma_format_idc */
        p_sps->i_chroma_idc = bs_read_ue( p_bs );
        if( p_sps->i_chroma_idc == 3 )
            bs_skip( p_bs, 1 ); /* separate_colour_plane_flag */
        /* bit_depth_luma_minus8 */
        p_sps->i_bit_depth_luma = bs_read_ue( p_bs ) + 8;
        /* bit_depth_chroma_minus8 */
        p_sps->i_bit_depth_chroma = bs_read_ue( p_bs ) + 8;
        /* qpprime_y_zero_transform_bypass_flag */
        bs_skip( p_bs, 1 );
        /* seq_scaling_matrix_present_flag */
        i_tmp = bs_read( p_bs, 1 );
        if( i_tmp )
        {
            for( int i = 0; i < ((3 != p_sps->i_chroma_idc) ? 8 : 12); i++ )
            {
                /* seq_scaling_list_present_flag[i] */
                i_tmp = bs_read( p_bs, 1 );
                if( !i_tmp )
                    continue;
                const int i_size_of_scaling_list = (i < 6 ) ? 16 : 64;
                /* scaling_list (...) */
                int i_lastscale = 8;
                int i_nextscale = 8;
                for( int j = 0; j < i_size_of_scaling_list; j++ )
                {
                    if( i_nextscale != 0 )
                    {
                        /* delta_scale */
                        i_tmp = bs_read_se( p_bs );
                        i_nextscale = ( i_lastscale + i_tmp + 256 ) % 256;
                        /* useDefaultScalingMatrixFlag = ... */
                    }
                    /* scalinglist[j] */
                    i_lastscale = ( i_nextscale == 0 ) ? i_lastscale : i_nextscale;
                }
            }
        }
    }

    /* Skip i_log2_max_frame_num */
    p_sps->i_log2_max_frame_num = bs_read_ue( p_bs );
    if( p_sps->i_log2_max_frame_num > 12)
        p_sps->i_log2_max_frame_num = 12;
    /* Read poc_type */
    p_sps->i_pic_order_cnt_type = bs_read_ue( p_bs );
    if( p_sps->i_pic_order_cnt_type == 0 )
    {
        /* skip i_log2_max_poc_lsb */
        p_sps->i_log2_max_pic_order_cnt_lsb = bs_read_ue( p_bs );
        if( p_sps->i_log2_max_pic_order_cnt_lsb > 12 )
            p_sps->i_log2_max_pic_order_cnt_lsb = 12;
    }
    else if( p_sps->i_pic_order_cnt_type == 1 )
    {
        int i_cycle;
        /* skip b_delta_pic_order_always_zero */
        p_sps->i_delta_pic_order_always_zero_flag = bs_read( p_bs, 1 );
        /* skip i_offset_for_non_ref_pic */
        bs_read_se( p_bs );
        /* skip i_offset_for_top_to_bottom_field */
        bs_read_se( p_bs );
        /* read i_num_ref_frames_in_poc_cycle */
        i_cycle = bs_read_ue( p_bs );
        if( i_cycle > 256 ) i_cycle = 256;
        while( i_cycle > 0 )
        {
            /* skip i_offset_for_ref_frame */
            bs_read_se(p_bs );
            i_cycle--;
        }
    }
    /* i_num_ref_frames */
    bs_read_ue( p_bs );
    /* b_gaps_in_frame_num_value_allowed */
    bs_skip( p_bs, 1 );

    /* Read size */
    p_sps->pic_width_in_mbs_minus1 = bs_read_ue( p_bs );
    p_sps->pic_height_in_map_units_minus1 = bs_read_ue( p_bs );

    /* b_frame_mbs_only */
    p_sps->frame_mbs_only_flag = bs_read( p_bs, 1 );
    if( !p_sps->frame_mbs_only_flag )
        bs_skip( p_bs, 1 );

    /* b_direct8x8_inference */
    bs_skip( p_bs, 1 );

    /* crop */
    if( bs_read1( p_bs ) ) /* frame_cropping_flag */
    {
        p_sps->frame_crop.left_offset = bs_read_ue( p_bs );
        p_sps->frame_crop.right_offset = bs_read_ue( p_bs );
        p_sps->frame_crop.right_offset = bs_read_ue( p_bs );
        p_sps->frame_crop.bottom_offset = bs_read_ue( p_bs );
    }

    /* vui */
    i_tmp = bs_read( p_bs, 1 );
    if( i_tmp )
    {
        p_sps->vui.b_valid = true;
        /* read the aspect ratio part if any */
        i_tmp = bs_read( p_bs, 1 );
        if( i_tmp )
        {
            static const struct { int w, h; } sar[17] =
            {
                { 0,   0 }, { 1,   1 }, { 12, 11 }, { 10, 11 },
                { 16, 11 }, { 40, 33 }, { 24, 11 }, { 20, 11 },
                { 32, 11 }, { 80, 33 }, { 18, 11 }, { 15, 11 },
                { 64, 33 }, { 160,99 }, {  4,  3 }, {  3,  2 },
                {  2,  1 },
            };
            int i_sar = bs_read( p_bs, 8 );
            int w, h;

            if( i_sar < 17 )
            {
                w = sar[i_sar].w;
                h = sar[i_sar].h;
            }
            else if( i_sar == 255 )
            {
                w = bs_read( p_bs, 16 );
                h = bs_read( p_bs, 16 );
            }
            else
            {
                w = 0;
                h = 0;
            }

            if( w != 0 && h != 0 )
            {
                p_sps->vui.i_sar_num = w;
                p_sps->vui.i_sar_den = h;
            }
            else
            {
                p_sps->vui.i_sar_num = 1;
                p_sps->vui.i_sar_den = 1;
            }
        }

        /* overscan */
        i_tmp = bs_read( p_bs, 1 );
        if ( i_tmp )
            bs_read( p_bs, 1 );

        /* video signal type */
        i_tmp = bs_read( p_bs, 1 );
        if( i_tmp )
        {
            bs_read( p_bs, 3 );
            p_sps->vui.colour.b_full_range = bs_read( p_bs, 1 );
            /* colour desc */
            i_tmp = bs_read( p_bs, 1 );
            if ( i_tmp )
            {
                p_sps->vui.colour.i_colour_primaries = bs_read( p_bs, 8 );
                p_sps->vui.colour.i_transfer_characteristics = bs_read( p_bs, 8 );
                p_sps->vui.colour.i_matrix_coefficients = bs_read( p_bs, 8 );
            }
            else
            {
                p_sps->vui.colour.i_colour_primaries = HXXX_PRIMARIES_UNSPECIFIED;
                p_sps->vui.colour.i_transfer_characteristics = HXXX_TRANSFER_UNSPECIFIED;
                p_sps->vui.colour.i_matrix_coefficients = HXXX_MATRIX_UNSPECIFIED;
            }
        }

        /* chroma loc info */
        i_tmp = bs_read( p_bs, 1 );
        if( i_tmp )
        {
            bs_read_ue( p_bs );
            bs_read_ue( p_bs );
        }

        /* timing info */
        p_sps->vui.b_timing_info_present_flag = bs_read( p_bs, 1 );
        if( p_sps->vui.b_timing_info_present_flag )
        {
            p_sps->vui.i_num_units_in_tick = bs_read( p_bs, 32 );
            p_sps->vui.i_time_scale = bs_read( p_bs, 32 );
            p_sps->vui.b_fixed_frame_rate = bs_read( p_bs, 1 );
        }

        /* Nal hrd & VC1 hrd parameters */
        p_sps->vui.b_hrd_parameters_present_flag = false;
        for ( int i=0; i<2; i++ )
        {
            i_tmp = bs_read( p_bs, 1 );
            if( i_tmp )
            {
                p_sps->vui.b_hrd_parameters_present_flag = true;
                uint32_t count = bs_read_ue( p_bs ) + 1;
                if( count > 31 )
                    return false;
                bs_read( p_bs, 4 );
                bs_read( p_bs, 4 );
                for( uint32_t i=0; i<count; i++ )
                {
                    if( bs_remain( p_bs ) < 23 )
                        return false;
                    bs_read_ue( p_bs );
                    bs_read_ue( p_bs );
                    bs_read( p_bs, 1 );
                }
                bs_read( p_bs, 5 );
                p_sps->vui.i_cpb_removal_delay_length_minus1 = bs_read( p_bs, 5 );
                p_sps->vui.i_dpb_output_delay_length_minus1 = bs_read( p_bs, 5 );
                bs_read( p_bs, 5 );
            }
        }

        if( p_sps->vui.b_hrd_parameters_present_flag )
            bs_read( p_bs, 1 );

        /* pic struct info */
        p_sps->vui.b_pic_struct_present_flag = bs_read( p_bs, 1 );

        /* + unparsed remains */
    }

    return true;
}
Beispiel #24
0
/* read in useful bits from sequence header */
static bool dirac_UnpackSeqHdr( struct seq_hdr_t *p_sh, block_t *p_block )
{
    bs_t bs;
    bs_init( &bs, p_block->p_buffer, p_block->i_buffer );
    bs_skip( &bs, 13*8 ); /* parse_info_header */
    dirac_uint( &bs ); /* major_version */
    dirac_uint( &bs ); /* minor_version */
    dirac_uint( &bs ); /* profile */
    dirac_uint( &bs ); /* level */

    uint32_t u_video_format = dirac_uint( &bs ); /* index */
    if( u_video_format > 20 )
    {
        /* don't know how to parse this header */
        return false;
    }

    static const struct {
        uint32_t u_w, u_h;
    } dirac_size_tbl[] = {
        {640,480}, {176,120}, {176,144}, {352,240}, {352,288}, {704,480},
        {704,576}, {720,480}, {720,576}, {1280,720}, {1280,720}, {1920,1080},
        {1920,1080}, {1920,1080}, {1920,1080}, {2048,1080}, {4096,2160},
        {3840,2160}, {3840,2160}, {7680,4320}, {7680,4320},
    };

    p_sh->u_width = dirac_size_tbl[u_video_format].u_w;
    p_sh->u_height = dirac_size_tbl[u_video_format].u_h;
    if( dirac_bool( &bs ) )
    {
        p_sh->u_width = dirac_uint( &bs ); /* frame_width */
        p_sh->u_height = dirac_uint( &bs ); /* frame_height */
    }

    if( dirac_bool( &bs ) )
    {
        dirac_uint( &bs ); /* chroma_format */
    }

    if( dirac_bool( &bs ) )
    {
        dirac_uint( &bs ); /* scan_format */
    }

    static const struct {
        uint32_t u_n /* numerator */, u_d /* denominator */;
    } dirac_frate_tbl[] = { /* table 10.3 */
        {1, 1}, /* this value is not used */
        {24000,1001}, {24,1}, {25,1}, {30000,1001}, {30,1},
        {50,1}, {60000,1001}, {60,1}, {15000,1001}, {25,2},
    };

    const unsigned dirac_frate_tbl_size =
        sizeof( dirac_frate_tbl ) / sizeof( *dirac_frate_tbl );

    static const uint32_t dirac_vidfmt_frate[] = { /* table C.1 */
        1, 9, 10, 9, 10, 9, 10, 4, 3, 7, 6, 4, 3, 7, 6, 2, 2, 7, 6, 7, 6,
    };

    p_sh->u_fps_num = dirac_frate_tbl[dirac_vidfmt_frate[u_video_format]].u_n;
    p_sh->u_fps_den = dirac_frate_tbl[dirac_vidfmt_frate[u_video_format]].u_d;
    if( dirac_bool( &bs ) )
    {
        uint32_t frame_rate_index = dirac_uint( &bs );
        if( frame_rate_index >= dirac_frate_tbl_size )
        {
            /* invalid header */
            return false;
        }
        p_sh->u_fps_num = dirac_frate_tbl[frame_rate_index].u_n;
        p_sh->u_fps_den = dirac_frate_tbl[frame_rate_index].u_d;
        if( frame_rate_index == 0 )
        {
            p_sh->u_fps_num = dirac_uint( &bs ); /* frame_rate_numerator */
            p_sh->u_fps_den = dirac_uint( &bs ); /* frame_rate_denominator */
        }
    }

    /* must have a valid framerate */
    if( !p_sh->u_fps_num || !p_sh->u_fps_den )
        return false;

    if( dirac_bool( &bs ) )
    {
        uint32_t par_index = dirac_uint( &bs );
        if( !par_index )
        {
            dirac_uint( &bs ); /* par_num */
            dirac_uint( &bs ); /* par_den */
        }
    }

    if( dirac_bool( &bs ) )
    {
        dirac_uint( &bs ); /* clean_width */
        dirac_uint( &bs ); /* clean_height */
        dirac_uint( &bs ); /* clean_left_offset */
        dirac_uint( &bs ); /* clean_top_offset */
    }

    if( dirac_bool( &bs ) )
    {
        uint32_t signal_range_index = dirac_uint( &bs );
        if( !signal_range_index )
        {
            dirac_uint( &bs ); /* luma_offset */
            dirac_uint( &bs ); /* luma_excursion */
            dirac_uint( &bs ); /* chroma_offset */
            dirac_uint( &bs ); /* chroma_excursion */
        }
    }

    if( dirac_bool( &bs ) )
    {
        uint32_t colour_spec_index = dirac_uint( &bs );
        if( !colour_spec_index )
        {
            if( dirac_bool( &bs ) )
            {
                dirac_uint( &bs ); /* colour_primaries_index */
            }
            if( dirac_bool( &bs ) )
            {
                dirac_uint( &bs ); /* colour_matrix_index */
            }
            if( dirac_bool( &bs ) )
            {
                dirac_uint( &bs ); /* transfer_function_index */
            }
        }
    }

    p_sh->u_picture_coding_mode = dirac_uint( &bs );

    return true;
}
Beispiel #25
0
static void PutSPS( decoder_t *p_dec, block_t *p_frag )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    uint8_t *pb_dec = NULL;
    int     i_dec = 0;
    bs_t s;
    int i_tmp;
    int i_sps_id;

    CreateDecodedNAL( &pb_dec, &i_dec, &p_frag->p_buffer[5],
                     p_frag->i_buffer - 5 );

    bs_init( &s, pb_dec, i_dec );
    int i_profile_idc = bs_read( &s, 8 );
    p_dec->fmt_out.i_profile = i_profile_idc;
    /* Skip constraint_set0123, reserved(4) */
    bs_skip( &s, 1+1+1+1 + 4 );
    p_dec->fmt_out.i_level = bs_read( &s, 8 );
    /* sps id */
    i_sps_id = bs_read_ue( &s );
    if( i_sps_id >= SPS_MAX || i_sps_id < 0 )
    {
        msg_Warn( p_dec, "invalid SPS (sps_id=%d)", i_sps_id );
        free( pb_dec );
        block_Release( p_frag );
        return;
    }

    if( i_profile_idc == 100 || i_profile_idc == 110 ||
        i_profile_idc == 122 || i_profile_idc == 244 ||
        i_profile_idc ==  44 || i_profile_idc ==  83 ||
        i_profile_idc ==  86 )
    {
        /* chroma_format_idc */
        const int i_chroma_format_idc = bs_read_ue( &s );
        if( i_chroma_format_idc == 3 )
            bs_skip( &s, 1 ); /* separate_colour_plane_flag */
        /* bit_depth_luma_minus8 */
        bs_read_ue( &s );
        /* bit_depth_chroma_minus8 */
        bs_read_ue( &s );
        /* qpprime_y_zero_transform_bypass_flag */
        bs_skip( &s, 1 );
        /* seq_scaling_matrix_present_flag */
        i_tmp = bs_read( &s, 1 );
        if( i_tmp )
        {
            for( int i = 0; i < ((3 != i_chroma_format_idc) ? 8 : 12); i++ )
            {
                /* seq_scaling_list_present_flag[i] */
                i_tmp = bs_read( &s, 1 );
                if( !i_tmp )
                    continue;
                const int i_size_of_scaling_list = (i < 6 ) ? 16 : 64;
                /* scaling_list (...) */
                int i_lastscale = 8;
                int i_nextscale = 8;
                for( int j = 0; j < i_size_of_scaling_list; j++ )
                {
                    if( i_nextscale != 0 )
                    {
                        /* delta_scale */
                        i_tmp = bs_read_se( &s );
                        i_nextscale = ( i_lastscale + i_tmp + 256 ) % 256;
                        /* useDefaultScalingMatrixFlag = ... */
                    }
                    /* scalinglist[j] */
                    i_lastscale = ( i_nextscale == 0 ) ? i_lastscale : i_nextscale;
                }
            }
        }
    }

    /* Skip i_log2_max_frame_num */
    p_sys->i_log2_max_frame_num = bs_read_ue( &s );
    if( p_sys->i_log2_max_frame_num > 12)
        p_sys->i_log2_max_frame_num = 12;
    /* Read poc_type */
    p_sys->i_pic_order_cnt_type = bs_read_ue( &s );
    if( p_sys->i_pic_order_cnt_type == 0 )
    {
        /* skip i_log2_max_poc_lsb */
        p_sys->i_log2_max_pic_order_cnt_lsb = bs_read_ue( &s );
        if( p_sys->i_log2_max_pic_order_cnt_lsb > 12 )
            p_sys->i_log2_max_pic_order_cnt_lsb = 12;
    }
    else if( p_sys->i_pic_order_cnt_type == 1 )
    {
        int i_cycle;
        /* skip b_delta_pic_order_always_zero */
        p_sys->i_delta_pic_order_always_zero_flag = bs_read( &s, 1 );
        /* skip i_offset_for_non_ref_pic */
        bs_read_se( &s );
        /* skip i_offset_for_top_to_bottom_field */
        bs_read_se( &s );
        /* read i_num_ref_frames_in_poc_cycle */
        i_cycle = bs_read_ue( &s );
        if( i_cycle > 256 ) i_cycle = 256;
        while( i_cycle > 0 )
        {
            /* skip i_offset_for_ref_frame */
            bs_read_se(&s );
            i_cycle--;
        }
    }
    /* i_num_ref_frames */
    bs_read_ue( &s );
    /* b_gaps_in_frame_num_value_allowed */
    bs_skip( &s, 1 );

    /* Read size */
    p_dec->fmt_out.video.i_width  = 16 * ( bs_read_ue( &s ) + 1 );
    p_dec->fmt_out.video.i_height = 16 * ( bs_read_ue( &s ) + 1 );

    /* b_frame_mbs_only */
    p_sys->b_frame_mbs_only = bs_read( &s, 1 );
    p_dec->fmt_out.video.i_height *=  ( 2 - p_sys->b_frame_mbs_only );
    if( p_sys->b_frame_mbs_only == 0 )
    {
        bs_skip( &s, 1 );
    }
    /* b_direct8x8_inference */
    bs_skip( &s, 1 );

    /* crop */
    i_tmp = bs_read( &s, 1 );
    if( i_tmp )
    {
        /* left */
        bs_read_ue( &s );
        /* right */
        bs_read_ue( &s );
        /* top */
        bs_read_ue( &s );
        /* bottom */
        bs_read_ue( &s );
    }

    /* vui */
    i_tmp = bs_read( &s, 1 );
    if( i_tmp )
    {
        /* read the aspect ratio part if any */
        i_tmp = bs_read( &s, 1 );
        if( i_tmp )
        {
            static const struct { int w, h; } sar[17] =
            {
                { 0,   0 }, { 1,   1 }, { 12, 11 }, { 10, 11 },
                { 16, 11 }, { 40, 33 }, { 24, 11 }, { 20, 11 },
                { 32, 11 }, { 80, 33 }, { 18, 11 }, { 15, 11 },
                { 64, 33 }, { 160,99 }, {  4,  3 }, {  3,  2 },
                {  2,  1 },
            };
            int i_sar = bs_read( &s, 8 );
            int w, h;

            if( i_sar < 17 )
            {
                w = sar[i_sar].w;
                h = sar[i_sar].h;
            }
            else if( i_sar == 255 )
            {
                w = bs_read( &s, 16 );
                h = bs_read( &s, 16 );
            }
            else
            {
                w = 0;
                h = 0;
            }

            if( w != 0 && h != 0 )
            {
                p_dec->fmt_out.video.i_sar_num = w;
                p_dec->fmt_out.video.i_sar_den = h;
            }
            else
            {
                p_dec->fmt_out.video.i_sar_num = 1;
                p_dec->fmt_out.video.i_sar_den = 1;
            }
        }
    }

    free( pb_dec );

    /* We have a new SPS */
    if( !p_sys->b_sps )
        msg_Dbg( p_dec, "found NAL_SPS (sps_id=%d)", i_sps_id );
    p_sys->b_sps = true;

    if( p_sys->pp_sps[i_sps_id] )
        block_Release( p_sys->pp_sps[i_sps_id] );
    p_sys->pp_sps[i_sps_id] = p_frag;
}
Beispiel #26
0
/*****************************************************************************
 * ParseNALBlock: parses annexB type NALs
 * All p_frag blocks are required to start with 0 0 0 1 4-byte startcode 
 *****************************************************************************/
static block_t *ParseNALBlock( decoder_t *p_dec, block_t *p_frag )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    block_t *p_pic = NULL;

    const int i_nal_ref_idc = (p_frag->p_buffer[4] >> 5)&0x03;
    const int i_nal_type = p_frag->p_buffer[4]&0x1f;

#define OUTPUT \
    do {                                                      \
        if( !p_sys->b_header && p_sys->slice.i_frame_type != BLOCK_FLAG_TYPE_I) \
            break;                                            \
                                                              \
        if( p_sys->slice.i_frame_type == BLOCK_FLAG_TYPE_I && p_sys->p_sps && p_sys->p_pps && !p_sys->b_header ) \
        { \
            block_t *p_sps = block_Duplicate( p_sys->p_sps ); \
            block_t *p_pps = block_Duplicate( p_sys->p_pps ); \
            p_sps->i_dts = p_sys->p_frame->i_dts;           \
            p_sps->i_pts = p_sys->p_frame->i_pts;           \
            block_ChainAppend( &p_sps, p_pps );               \
            block_ChainAppend( &p_sps, p_sys->p_frame );      \
            p_sys->b_header = VLC_TRUE;                       \
            p_pic = block_ChainGather( p_sps );               \
        } else { \
            p_pic = block_ChainGather( p_sys->p_frame ); \
        } \
        p_pic->i_length = 0;    /* FIXME */                   \
        p_pic->i_flags |= p_sys->slice.i_frame_type;          \
            \
        p_sys->slice.i_frame_type = 0;                        \
        p_sys->p_frame = NULL;                                \
        p_sys->b_slice = VLC_FALSE;                           \
    } while(0)

    if( p_sys->b_slice && ( !p_sys->b_sps || !p_sys->b_pps ) )
    {
        block_ChainRelease( p_sys->p_frame );
        msg_Warn( p_dec, "waiting for SPS/PPS" );

        /* Reset context */
        p_sys->slice.i_frame_type = 0;
        p_sys->p_frame = NULL;
        p_sys->b_slice = VLC_FALSE;
    }

    if( ( !p_sys->b_sps || !p_sys->b_pps ) &&
        i_nal_type >= NAL_SLICE && i_nal_type <= NAL_SLICE_IDR )
    {
        p_sys->b_slice = VLC_TRUE;
        /* Fragment will be discarded later on */
    }
    else if( i_nal_type >= NAL_SLICE && i_nal_type <= NAL_SLICE_IDR )
    {
        uint8_t *dec;
        int i_dec, i_first_mb, i_slice_type;
        slice_t slice;
        vlc_bool_t b_pic;
        bs_t s;

        /* do not convert the whole frame */
        nal_get_decoded( &dec, &i_dec, &p_frag->p_buffer[5],
                         __MIN( p_frag->i_buffer - 5, 60 ) );
        bs_init( &s, dec, i_dec );

        /* first_mb_in_slice */
        i_first_mb = bs_read_ue( &s );

        /* slice_type */
        switch( (i_slice_type = bs_read_ue( &s )) )
        {
        case 0: case 5:
            slice.i_frame_type = BLOCK_FLAG_TYPE_P;
            break;
        case 1: case 6:
            slice.i_frame_type = BLOCK_FLAG_TYPE_B;
            break;
        case 2: case 7:
            slice.i_frame_type = BLOCK_FLAG_TYPE_I;
            break;
        case 3: case 8: /* SP */
            slice.i_frame_type = BLOCK_FLAG_TYPE_P;
            break;
        case 4: case 9:
            slice.i_frame_type = BLOCK_FLAG_TYPE_I;
            break;
        default:
            slice.i_frame_type = 0;
            break;
        }

        /* */
        slice.i_nal_type = i_nal_type;
        slice.i_nal_ref_idc = i_nal_ref_idc;

        slice.i_pic_parameter_set_id = bs_read_ue( &s );
        slice.i_frame_num = bs_read( &s, p_sys->i_log2_max_frame_num + 4 );

        slice.i_field_pic_flag = 0;
        slice.i_bottom_field_flag = -1;
        if( !p_sys->b_frame_mbs_only )
        {
            /* field_pic_flag */
            slice.i_field_pic_flag = bs_read( &s, 1 );
            if( slice.i_field_pic_flag )
                slice.i_bottom_field_flag = bs_read( &s, 1 );
        }

        slice.i_idr_pic_id = p_sys->slice.i_idr_pic_id;
        if( slice.i_nal_type == NAL_SLICE_IDR )
            slice.i_idr_pic_id = bs_read_ue( &s );

        slice.i_pic_order_cnt_lsb = -1;
        slice.i_delta_pic_order_cnt_bottom = -1;
        slice.i_delta_pic_order_cnt0 = 0;
        slice.i_delta_pic_order_cnt1 = 0;
        if( p_sys->i_pic_order_cnt_type == 0 )
        {
            slice.i_pic_order_cnt_lsb = bs_read( &s, p_sys->i_log2_max_pic_order_cnt_lsb + 4 );
            if( p_sys->i_pic_order_present_flag && !slice.i_field_pic_flag )
                slice.i_delta_pic_order_cnt_bottom = bs_read_se( &s );
        }
        else if( p_sys->i_pic_order_cnt_type == 1 && !p_sys->i_delta_pic_order_always_zero_flag )
        {
            slice.i_delta_pic_order_cnt0 = bs_read_se( &s );
            if( p_sys->i_pic_order_present_flag && !slice.i_field_pic_flag )
                slice.i_delta_pic_order_cnt1 = bs_read_se( &s );
        }

        /* Detection of the first VCL NAL unit of a primary coded picture
         * (cf. 7.4.1.2.4) */
        b_pic = VLC_FALSE;
        if( slice.i_frame_num != p_sys->slice.i_frame_num ||
            slice.i_pic_parameter_set_id != p_sys->slice.i_pic_parameter_set_id ||
            slice.i_field_pic_flag != p_sys->slice.i_field_pic_flag ||
            slice.i_nal_ref_idc != p_sys->slice.i_nal_ref_idc )
            b_pic = VLC_TRUE;
        if( slice.i_bottom_field_flag != -1 && p_sys->slice.i_bottom_field_flag != -1 && slice.i_bottom_field_flag != p_sys->slice.i_bottom_field_flag )
            b_pic = VLC_TRUE;
        if( p_sys->i_pic_order_cnt_type == 0 &&
            ( slice.i_pic_order_cnt_lsb != p_sys->slice.i_pic_order_cnt_lsb ||
              slice.i_delta_pic_order_cnt_bottom != p_sys->slice.i_delta_pic_order_cnt_bottom ) )
            b_pic = VLC_TRUE;
        else if( p_sys->i_pic_order_cnt_type == 1 &&
                 ( slice.i_delta_pic_order_cnt0 != p_sys->slice.i_delta_pic_order_cnt0 ||
                   slice.i_delta_pic_order_cnt1 != p_sys->slice.i_delta_pic_order_cnt1 ) )
            b_pic = VLC_TRUE;
        if( ( slice.i_nal_type == NAL_SLICE_IDR || p_sys->slice.i_nal_type == NAL_SLICE_IDR ) &&
            ( slice.i_nal_type != p_sys->slice.i_nal_type || slice.i_idr_pic_id != p_sys->slice.i_idr_pic_id ) )
                b_pic = VLC_TRUE;

        /* */
        p_sys->slice = slice;

        if( b_pic && p_sys->b_slice )
            OUTPUT;

        p_sys->b_slice = VLC_TRUE;

        free( dec );
    }
    else if( i_nal_type == NAL_SPS )
    {
        uint8_t *dec;
        int     i_dec;
        bs_t s;
        int i_tmp;

        if( !p_sys->b_sps ) msg_Dbg( p_dec, "found NAL_SPS" );

        p_sys->b_sps = VLC_TRUE;

        nal_get_decoded( &dec, &i_dec, &p_frag->p_buffer[5],
                         p_frag->i_buffer - 5 );

        bs_init( &s, dec, i_dec );
        /* Skip profile(8), constraint_set012, reserver(5), level(8) */
        bs_skip( &s, 8 + 1+1+1 + 5 + 8 );
        /* sps id */
        bs_read_ue( &s );
        /* Skip i_log2_max_frame_num */
        p_sys->i_log2_max_frame_num = bs_read_ue( &s );
        if( p_sys->i_log2_max_frame_num > 12)
            p_sys->i_log2_max_frame_num = 12;
        /* Read poc_type */
        p_sys->i_pic_order_cnt_type = bs_read_ue( &s );
        if( p_sys->i_pic_order_cnt_type == 0 )
        {
            /* skip i_log2_max_poc_lsb */
            p_sys->i_log2_max_pic_order_cnt_lsb = bs_read_ue( &s );
            if( p_sys->i_log2_max_pic_order_cnt_lsb > 12 )
                p_sys->i_log2_max_pic_order_cnt_lsb = 12;
        }
        else if( p_sys->i_pic_order_cnt_type == 1 )
        {
            int i_cycle;
            /* skip b_delta_pic_order_always_zero */
            p_sys->i_delta_pic_order_always_zero_flag = bs_read( &s, 1 );
            /* skip i_offset_for_non_ref_pic */
            bs_read_se( &s );
            /* skip i_offset_for_top_to_bottom_field */
            bs_read_se( &s );
            /* read i_num_ref_frames_in_poc_cycle */
            i_cycle = bs_read_ue( &s );
            if( i_cycle > 256 ) i_cycle = 256;
            while( i_cycle > 0 )
            {
                /* skip i_offset_for_ref_frame */
                bs_read_se(&s );
            }
        }
        /* i_num_ref_frames */
        bs_read_ue( &s );
        /* b_gaps_in_frame_num_value_allowed */
        bs_skip( &s, 1 );

        /* Read size */
        p_dec->fmt_out.video.i_width  = 16 * ( bs_read_ue( &s ) + 1 );
        p_dec->fmt_out.video.i_height = 16 * ( bs_read_ue( &s ) + 1 );

        /* b_frame_mbs_only */
        p_sys->b_frame_mbs_only = bs_read( &s, 1 );
        if( p_sys->b_frame_mbs_only == 0 )
        {
            bs_skip( &s, 1 );
        }
        /* b_direct8x8_inference */
        bs_skip( &s, 1 );

        /* crop */
        i_tmp = bs_read( &s, 1 );
        if( i_tmp )
        {
            /* left */
            bs_read_ue( &s );
            /* right */
            bs_read_ue( &s );
            /* top */
            bs_read_ue( &s );
            /* bottom */
            bs_read_ue( &s );
        }

        /* vui */
        i_tmp = bs_read( &s, 1 );
        if( i_tmp )
        {
            /* read the aspect ratio part if any FIXME check it */
            i_tmp = bs_read( &s, 1 );
            if( i_tmp )
            {
                static const struct { int w, h; } sar[14] =
                {
                    { 0,   0 }, { 1,   1 }, { 12, 11 }, { 10, 11 },
                    { 16, 11 }, { 40, 33 }, { 24, 11 }, { 20, 11 },
                    { 32, 11 }, { 80, 33 }, { 18, 11 }, { 15, 11 },
                    { 64, 33 }, { 160,99 },
                };
                int i_sar = bs_read( &s, 8 );
                int w, h;

                if( i_sar < 14 )
                {
                    w = sar[i_sar].w;
                    h = sar[i_sar].h;
                }
                else
                {
                    w = bs_read( &s, 16 );
                    h = bs_read( &s, 16 );
                }
                if( h != 0 )
                    p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR * w /
                        h * p_dec->fmt_out.video.i_width /
                        p_dec->fmt_out.video.i_height;
                else
                    p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR;
            }
        }

        free( dec );

        if( p_sys->b_slice ) OUTPUT;

        /* We have a new SPS */
        if( p_sys->p_sps ) block_Release( p_sys->p_sps );
        p_sys->p_sps = p_frag;

        /* Do not append the SPS because we will insert it on keyframes */
        return p_pic;
    }
    else if( i_nal_type == NAL_PPS )
    {
        bs_t s;

        bs_init( &s, &p_frag->p_buffer[5], p_frag->i_buffer - 5 );
        bs_read_ue( &s ); // pps id
        bs_read_ue( &s ); // sps id
        bs_skip( &s, 1 ); // entropy coding mode flag
        p_sys->i_pic_order_present_flag = bs_read( &s, 1 );

        if( !p_sys->b_pps ) msg_Dbg( p_dec, "found NAL_PPS" );
        p_sys->b_pps = VLC_TRUE;

        /* TODO */

        if( p_sys->b_slice ) OUTPUT;

        /* We have a new PPS */
        if( p_sys->p_pps ) block_Release( p_sys->p_pps );
        p_sys->p_pps = p_frag;

        /* Do not append the PPS because we will insert it on keyframes */
        return p_pic;
    }
    else if( i_nal_type == NAL_AU_DELIMITER ||
             i_nal_type == NAL_SEI ||
             ( i_nal_type >= 13 && i_nal_type <= 18 ) )
    {
        if( p_sys->b_slice ) OUTPUT;
    }

#undef OUTPUT

    /* Append the block */
    block_ChainAppend( &p_sys->p_frame, p_frag );

    return p_pic;
}
Beispiel #27
0
/* ParseVOL:
 *  TODO:
 *      - support aspect ratio
 */
static int ParseVOL( decoder_t *p_dec, es_format_t *fmt,
                     uint8_t *p_vol, int i_vol )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    int i_vo_type, i_vo_ver_id, i_ar, i_shape;
    bs_t s;

    for( ;; )
    {
        if( p_vol[0] == 0x00 && p_vol[1] == 0x00 && p_vol[2] == 0x01 &&
            p_vol[3] >= 0x20 && p_vol[3] <= 0x2f ) break;

        p_vol++; i_vol--;
        if( i_vol <= 4 ) return VLC_EGENERIC;
    }

    bs_init( &s, &p_vol[4], i_vol - 4 );

    bs_skip( &s, 1 );   /* random access */
    i_vo_type = bs_read( &s, 8 );
    if( bs_read1( &s ) )
    {
        i_vo_ver_id = bs_read( &s, 4 );
        bs_skip( &s, 3 );
    }
    else
    {
        i_vo_ver_id = 1;
    }
    i_ar = bs_read( &s, 4 );
    if( i_ar == 0xf )
    {
        int i_ar_width, i_ar_height;

        i_ar_width = bs_read( &s, 8 );
        i_ar_height= bs_read( &s, 8 );
    }
    if( bs_read1( &s ) )
    {
        int i_chroma_format;
        int i_low_delay;

        /* vol control parameter */
        i_chroma_format = bs_read( &s, 2 );
        i_low_delay = bs_read1( &s );

        if( bs_read1( &s ) ) /* vbv parameters */
        {
            unsigned int i_bitrate, i_vbv_buffer_size, i_vbv_occupancy;
            i_bitrate = bs_read( &s, 15 ) << 15;
            bs_skip( &s, 1 );
            i_bitrate += bs_read( &s, 15 );
            bs_skip( &s, 1 );
            i_vbv_buffer_size = bs_read( &s, 15 ) << 3;
            bs_skip( &s, 1 );
            i_vbv_buffer_size += bs_read( &s, 3 );
            i_vbv_occupancy = bs_read( &s, 11 ) << 15;
            bs_skip( &s, 1 );
            i_vbv_occupancy += bs_read( &s, 15 );
            bs_skip( &s, 1 );

            p_dec->fmt_out.i_bitrate = i_bitrate * 400;
            p_dec->fmt_out.video.i_cpb_buffer = i_vbv_buffer_size * 16384;
            p_dec->p_sys->i_vbv_occupancy = i_vbv_occupancy * 64;
        }
    }
    /* shape 0->RECT, 1->BIN, 2->BIN_ONLY, 3->GRAY */
    i_shape = bs_read( &s, 2 );
    if( i_shape == 3 && i_vo_ver_id != 1 )
    {
        bs_skip( &s, 4 );
    }

    if( !bs_read1( &s ) ) return VLC_EGENERIC; /* Marker */

    p_sys->i_fps_num = bs_read( &s, 16 ); /* Time increment resolution*/
    if( !p_sys->i_fps_num ) p_sys->i_fps_num = 1;

    if( !bs_read1( &s ) ) return VLC_EGENERIC; /* Marker */

    if( bs_read1( &s ) )
    {
        int i_time_increment_bits = vlc_log2( p_sys->i_fps_num - 1 ) + 1;

        if( i_time_increment_bits < 1 ) i_time_increment_bits = 1;

        p_sys->i_fps_den = bs_read( &s, i_time_increment_bits );
    }
    if( i_shape == 0 )
    {
        bs_skip( &s, 1 );
        fmt->video.i_width = bs_read( &s, 13 );
        bs_skip( &s, 1 );
        fmt->video.i_height= bs_read( &s, 13 );
        bs_skip( &s, 1 );
    }

    return VLC_SUCCESS;
}
Beispiel #28
0
int h264_parse_sps( const uint8_t *p_sps_buf, int i_sps_size,
                    struct nal_sps *p_sps )
{
    uint8_t *pb_dec = NULL;
    int     i_dec = 0;
    bs_t s;
    int i_tmp;

    if (i_sps_size < 5 || (p_sps_buf[4] & 0x1f) != NAL_SPS)
        return -1;

    memset( p_sps, 0, sizeof(struct nal_sps) );
    CreateRbspFromNAL( &pb_dec, &i_dec, &p_sps_buf[5],
                      i_sps_size - 5 );

    bs_init( &s, pb_dec, i_dec );
    int i_profile_idc = bs_read( &s, 8 );
    p_sps->i_profile = i_profile_idc;
    p_sps->i_profile_compatibility = bs_read( &s, 8 );
    p_sps->i_level = bs_read( &s, 8 );
    /* sps id */
    p_sps->i_id = bs_read_ue( &s );
    if( p_sps->i_id >= SPS_MAX || p_sps->i_id < 0 )
    {
        free( pb_dec );
        return -1;
    }

    if( i_profile_idc == PROFILE_H264_HIGH || i_profile_idc == PROFILE_H264_HIGH_10 ||
        i_profile_idc == PROFILE_H264_HIGH_422 || i_profile_idc == PROFILE_H264_HIGH_444_PREDICTIVE ||
        i_profile_idc ==  PROFILE_H264_CAVLC_INTRA || i_profile_idc ==  PROFILE_H264_SVC_BASELINE ||
        i_profile_idc ==  PROFILE_H264_SVC_HIGH )
    {
        /* chroma_format_idc */
        const int i_chroma_format_idc = bs_read_ue( &s );
        if( i_chroma_format_idc == 3 )
            bs_skip( &s, 1 ); /* separate_colour_plane_flag */
        /* bit_depth_luma_minus8 */
        bs_read_ue( &s );
        /* bit_depth_chroma_minus8 */
        bs_read_ue( &s );
        /* qpprime_y_zero_transform_bypass_flag */
        bs_skip( &s, 1 );
        /* seq_scaling_matrix_present_flag */
        i_tmp = bs_read( &s, 1 );
        if( i_tmp )
        {
            for( int i = 0; i < ((3 != i_chroma_format_idc) ? 8 : 12); i++ )
            {
                /* seq_scaling_list_present_flag[i] */
                i_tmp = bs_read( &s, 1 );
                if( !i_tmp )
                    continue;
                const int i_size_of_scaling_list = (i < 6 ) ? 16 : 64;
                /* scaling_list (...) */
                int i_lastscale = 8;
                int i_nextscale = 8;
                for( int j = 0; j < i_size_of_scaling_list; j++ )
                {
                    if( i_nextscale != 0 )
                    {
                        /* delta_scale */
                        i_tmp = bs_read_se( &s );
                        i_nextscale = ( i_lastscale + i_tmp + 256 ) % 256;
                        /* useDefaultScalingMatrixFlag = ... */
                    }
                    /* scalinglist[j] */
                    i_lastscale = ( i_nextscale == 0 ) ? i_lastscale : i_nextscale;
                }
            }
        }
    }

    /* Skip i_log2_max_frame_num */
    p_sps->i_log2_max_frame_num = bs_read_ue( &s );
    if( p_sps->i_log2_max_frame_num > 12)
        p_sps->i_log2_max_frame_num = 12;
    /* Read poc_type */
    p_sps->i_pic_order_cnt_type = bs_read_ue( &s );
    if( p_sps->i_pic_order_cnt_type == 0 )
    {
        /* skip i_log2_max_poc_lsb */
        p_sps->i_log2_max_pic_order_cnt_lsb = bs_read_ue( &s );
        if( p_sps->i_log2_max_pic_order_cnt_lsb > 12 )
            p_sps->i_log2_max_pic_order_cnt_lsb = 12;
    }
    else if( p_sps->i_pic_order_cnt_type == 1 )
    {
        int i_cycle;
        /* skip b_delta_pic_order_always_zero */
        p_sps->i_delta_pic_order_always_zero_flag = bs_read( &s, 1 );
        /* skip i_offset_for_non_ref_pic */
        bs_read_se( &s );
        /* skip i_offset_for_top_to_bottom_field */
        bs_read_se( &s );
        /* read i_num_ref_frames_in_poc_cycle */
        i_cycle = bs_read_ue( &s );
        if( i_cycle > 256 ) i_cycle = 256;
        while( i_cycle > 0 )
        {
            /* skip i_offset_for_ref_frame */
            bs_read_se(&s );
            i_cycle--;
        }
    }
    /* i_num_ref_frames */
    bs_read_ue( &s );
    /* b_gaps_in_frame_num_value_allowed */
    bs_skip( &s, 1 );

    /* Read size */
    p_sps->i_width  = 16 * ( bs_read_ue( &s ) + 1 );
    p_sps->i_height = 16 * ( bs_read_ue( &s ) + 1 );

    /* b_frame_mbs_only */
    p_sps->b_frame_mbs_only = bs_read( &s, 1 );
    p_sps->i_height *=  ( 2 - p_sps->b_frame_mbs_only );
    if( p_sps->b_frame_mbs_only == 0 )
    {
        bs_skip( &s, 1 );
    }
    /* b_direct8x8_inference */
    bs_skip( &s, 1 );

    /* crop */
    i_tmp = bs_read( &s, 1 );
    if( i_tmp )
    {
        /* left */
        bs_read_ue( &s );
        /* right */
        bs_read_ue( &s );
        /* top */
        bs_read_ue( &s );
        /* bottom */
        bs_read_ue( &s );
    }

    /* vui */
    i_tmp = bs_read( &s, 1 );
    if( i_tmp )
    {
        p_sps->vui.b_valid = true;
        /* read the aspect ratio part if any */
        i_tmp = bs_read( &s, 1 );
        if( i_tmp )
        {
            static const struct { int w, h; } sar[17] =
            {
                { 0,   0 }, { 1,   1 }, { 12, 11 }, { 10, 11 },
                { 16, 11 }, { 40, 33 }, { 24, 11 }, { 20, 11 },
                { 32, 11 }, { 80, 33 }, { 18, 11 }, { 15, 11 },
                { 64, 33 }, { 160,99 }, {  4,  3 }, {  3,  2 },
                {  2,  1 },
            };
            int i_sar = bs_read( &s, 8 );
            int w, h;

            if( i_sar < 17 )
            {
                w = sar[i_sar].w;
                h = sar[i_sar].h;
            }
            else if( i_sar == 255 )
            {
                w = bs_read( &s, 16 );
                h = bs_read( &s, 16 );
            }
            else
            {
                w = 0;
                h = 0;
            }

            if( w != 0 && h != 0 )
            {
                p_sps->vui.i_sar_num = w;
                p_sps->vui.i_sar_den = h;
            }
            else
            {
                p_sps->vui.i_sar_num = 1;
                p_sps->vui.i_sar_den = 1;
            }
        }

        /* overscan */
        i_tmp = bs_read( &s, 1 );
        if ( i_tmp )
            bs_read( &s, 1 );

        /* video signal type */
        i_tmp = bs_read( &s, 1 );
        if( i_tmp )
        {
            bs_read( &s, 4 );
            /* colour desc */
            bs_read( &s, 1 );
            if ( i_tmp )
                bs_read( &s, 24 );
        }

        /* chroma loc info */
        i_tmp = bs_read( &s, 1 );
        if( i_tmp )
        {
            bs_read_ue( &s );
            bs_read_ue( &s );
        }

        /* timing info */
        p_sps->vui.b_timing_info_present_flag = bs_read( &s, 1 );
        if( p_sps->vui.b_timing_info_present_flag )
        {
            p_sps->vui.i_num_units_in_tick = bs_read( &s, 32 );
            p_sps->vui.i_time_scale = bs_read( &s, 32 );
            p_sps->vui.b_fixed_frame_rate = bs_read( &s, 1 );
        }

        /* Nal hrd & VC1 hrd parameters */
        p_sps->vui.b_cpb_dpb_delays_present_flag = false;
        for ( int i=0; i<2; i++ )
        {
            i_tmp = bs_read( &s, 1 );
            if( i_tmp )
            {
                p_sps->vui.b_cpb_dpb_delays_present_flag = true;
                uint32_t count = bs_read_ue( &s ) + 1;
                bs_read( &s, 4 );
                bs_read( &s, 4 );
                for( uint32_t i=0; i<count; i++ )
                {
                    bs_read_ue( &s );
                    bs_read_ue( &s );
                    bs_read( &s, 1 );
                }
                bs_read( &s, 5 );
                p_sps->vui.i_cpb_removal_delay_length_minus1 = bs_read( &s, 5 );
                p_sps->vui.i_dpb_output_delay_length_minus1 = bs_read( &s, 5 );
                bs_read( &s, 5 );
            }
        }

        if( p_sps->vui.b_cpb_dpb_delays_present_flag )
            bs_read( &s, 1 );

        /* pic struct info */
        p_sps->vui.b_pic_struct_present_flag = bs_read( &s, 1 );

        /* + unparsed remains */
    }

    free( pb_dec );

    return 0;
}
Beispiel #29
0
int read_cdp( obe_user_data_t *user_data )
{
    uint8_t *start = NULL, calc_cs = 0;
    int cc_count = 0;
    bs_read_t s;
    bs_read_init( &s, user_data->data, user_data->len );

    // cdp_header
    if( bs_read( &s, 16 ) != CDP_IDENTIFIER )
    {
        syslog( LOG_ERR, "CDP identifier not found \n" );
        return 1;
    }

    /* Verify Checksum */
    for( int i = 0; i < user_data->len - 1; i++ )
        calc_cs += user_data->data[i];

    calc_cs = calc_cs ? 256 - calc_cs : 0;
    if( calc_cs != user_data->data[user_data->len - 1] )
    {
        syslog( LOG_ERR, "Invalid checksum in Caption Distribution Packet \n" );
        return 1;
    }

    bs_skip( &s, 8 ); // cdp_length
    bs_skip( &s, 4 ); // cdp_frame_rate
    bs_skip( &s, 4 ); // reserved
    bs_skip( &s, 1 ); // time_code_present
    bs_skip( &s, 1 ); // ccdata_present
    bs_skip( &s, 1 ); // svcinfo_present
    bs_skip( &s, 1 ); // svc_info_start
    bs_skip( &s, 1 ); // svc_info_change
    bs_skip( &s, 1 ); // svc_info_complete

    /* caption_service_active seemingly unreliable */
    bs_skip( &s, 1 ); // caption_service_active
    bs_skip( &s, 1 ); // reserved
    bs_skip( &s, 16 ); // cdp_hdr_sequence_cntr

    while( !bs_read_eof( &s ) )
    {
        uint8_t section_id = bs_read( &s, 8 );
        if( section_id == CDP_TC_SECTION_ID )
        {
            /* Is this timecode guaranteed to match VITC? */
            bs_skip( &s, 2 ); // reserved
            bs_skip( &s, 2 ); // tc_10hrs
            bs_skip( &s, 4 ); // tc_1hrs
            bs_skip( &s, 1 ); // reserved
            bs_skip( &s, 3 ); // tc_10min
            bs_skip( &s, 4 ); // tc_1min
            bs_skip( &s, 1 ); // tc_field_flag
            bs_skip( &s, 3 ); // tc_10sec
            bs_skip( &s, 4 ); // tc_1sec
            bs_skip( &s, 1 ); // drop_frame_flag
            bs_skip( &s, 1 ); // zero
            bs_skip( &s, 2 ); // tc_10fr
            bs_skip( &s, 4 ); // tc_1fr
        }
        else if( section_id == CDP_CC_DATA_SECTION_ID )
        {
            cc_count = bs_read( &s, 8 ) & 0x1f;
            start = &user_data->data[bs_read_pos( &s ) / 8];
            for( int i = 0; i < cc_count; i++ )
            {
                bs_skip( &s, 5 ); // marker_bits
                bs_skip( &s, 1 ); // cc_valid
                bs_skip( &s, 2 ); // cc_type
                bs_skip( &s, 8 ); // cc_data_1
                bs_skip( &s, 8 ); // cc_data_2
            }
        }
        else if( section_id == CDP_CC_SVC_INFO_SECTION_ID )
        {
            /* TODO: pass this to muxer when user requests */
            bs_skip( &s, 1 ); // reserved
            bs_skip( &s, 1 ); // svc_info_start
            bs_skip( &s, 1 ); // svc_info_change
            bs_skip( &s, 1 ); // svc_info_complete
            int svc_count = bs_read( &s, 4 );
            for( int i = 0; i < svc_count; i++ )
            {
                bs_skip( &s, 1 ); // reserved
                bs_skip( &s, 1 ); // csn_size
                bs_skip( &s, 6 ); // caption_service_number (note: csn_size branch in spec)
                bs_skip( &s, 8 ); // svc_data_byte_1
                bs_skip( &s, 8 ); // svc_data_byte_2
                bs_skip( &s, 8 ); // svc_data_byte_3
                bs_skip( &s, 8 ); // svc_data_byte_4
                bs_skip( &s, 8 ); // svc_data_byte_5
                bs_skip( &s, 8 ); // svc_data_byte_6
            }
        }
        else if( section_id == CDP_FOOTER_SECTION_ID )
        {
            bs_skip( &s, 16 ); // cdp_ftr_sequence_cntr
            bs_skip( &s, 8 );  // packet_checksum
            break;
        }
        else // future_section
        {
            int future_len = bs_read( &s, 8 );
            for( int i = 0; i < future_len; i++ )
                bs_skip( &s, 8 );
        }
    }

    if( !cc_count )
        return 1;

    if( write_708_cc( user_data, start, cc_count ) < 0 )
        return -1;

    return 0;
}
Beispiel #30
0
void Parser::parse(int *pb_nal_start)
{
	h264_t *h = &h264;
    bs_t s;
    *pb_nal_start = 0;

    if( nal.i_type == NAL_SPS || nal.i_type == NAL_PPS )
        *pb_nal_start = 1;

    bs_init( &s, nal.p_payload, nal.i_payload );
    if( nal.i_type == NAL_SPS )
    {
        int i_tmp;

        i_tmp = bs_read( &s, 8 );
        bs_skip( &s, 1+1+1 + 5 + 8 );
        /* sps id */
        bs_read_ue( &s );

        if( i_tmp >= 100 )
        {
            b_hiprofile = 1;
			bs_read_ue( &s ); // chroma_format_idc
            bs_read_ue( &s ); // bit_depth_luma_minus8
            bs_read_ue( &s ); // bit_depth_chroma_minus8
            bs_skip( &s, 1 ); // qpprime_y_zero_transform_bypass_flag
            if( bs_read( &s, 1 ) ) // seq_scaling_matrix_present_flag
            {
                int i, j;
                for( i = 0; i < 8; i++ )
                {
                    if( bs_read( &s, 1 ) ) // seq_scaling_list_present_flag[i]
                    {
                        uint8 i_tmp = 8;
                        for( j = 0; j < (i<6?16:64); j++ )
                        {
                            i_tmp += bs_read_se( &s );
                            if( i_tmp == 0 )
                                break;
                        }
                    }
                }
            }
        }

        /* Skip i_log2_max_frame_num */
        h->i_log2_max_frame_num = bs_read_ue( &s ) + 4;
        /* Read poc_type */
        h->i_poc_type = bs_read_ue( &s );
        if( h->i_poc_type == 0 )
        {
            h->i_log2_max_poc_lsb = bs_read_ue( &s ) + 4;
        }
        else if( h->i_poc_type == 1 )
        {
            int i_cycle;
            /* skip b_delta_pic_order_always_zero */
            bs_skip( &s, 1 );
            /* skip i_offset_for_non_ref_pic */
            bs_read_se( &s );
            /* skip i_offset_for_top_to_bottom_field */
            bs_read_se( &s );
            /* read i_num_ref_frames_in_poc_cycle */
            i_cycle = bs_read_ue( &s ); 
            if( i_cycle > 256 ) i_cycle = 256;
            while( i_cycle > 0 )
            {
                /* skip i_offset_for_ref_frame */
                bs_read_se(&s );
            }
        }
        /* i_num_ref_frames */
        bs_read_ue( &s );
        /* b_gaps_in_frame_num_value_allowed */
        bs_skip( &s, 1 );

        /* Read size */
        h->i_width  = 16 * ( bs_read_ue( &s ) + 1 );
        h->i_height = 32 * ( bs_read_ue( &s ) + 1 );

        /* b_frame_mbs_only */
        i_tmp = bs_read( &s, 1 );
        if( i_tmp == 1 )
        {
			// fix: progressive, half height
			h->i_height /= 2;
		}
		else
		{
			// mb_adaptive_frame_field_flag
            bs_skip( &s, 1 );
        }
        /* b_direct8x8_inference */
        bs_skip( &s, 1 );

        /* crop ? */
        i_tmp = bs_read( &s, 1 );
        if( i_tmp )
        {
			// fix: no cropping

            /* left */
            //h->i_width -= 2 * bs_read_ue( &s );
            /* right */
            //h->i_width -= 2 * bs_read_ue( &s );
            /* top */
            //h->i_height -= 2 * bs_read_ue( &s );
            /* bottom */
            //h->i_height -= 2 * bs_read_ue( &s );
        }

        /* vui: ignored */
    }
    else if( nal.i_type >= NAL_SLICE && nal.i_type <= NAL_SLICE_IDR )
    {
        int i_tmp;

        /* i_first_mb */
        bs_read_ue( &s );
        /* picture type */
        switch( bs_read_ue( &s ) )
        {
            case 0: case 5: /* P */
            case 1: case 6: /* B */
            case 3: case 8: /* SP */
                h->b_key = 0;
                break;
            case 2: case 7: /* I */
            case 4: case 9: /* SI */
				// fix: key flags in high profile
                h->b_key = (nal.i_type == NAL_SLICE_IDR || (b_hiprofile && nal.i_type == NAL_SLICE));
                break;
        }
        /* pps id */
        bs_read_ue( &s );

        /* frame num */
        i_tmp = bs_read( &s, h->i_log2_max_frame_num );

        if( i_tmp != h->i_frame_num )
            *pb_nal_start = 1;

        h->i_frame_num = i_tmp;

        if( nal.i_type == NAL_SLICE_IDR )
        {
            i_tmp = bs_read_ue( &s );
            if( h->i_nal_type == NAL_SLICE_IDR && h->i_idr_pic_id != i_tmp )
                *pb_nal_start = 1;

            h->i_idr_pic_id = i_tmp;
        }

        if( h->i_poc_type == 0 )
        {
            i_tmp = bs_read( &s, h->i_log2_max_poc_lsb );
            if( i_tmp != h->i_poc )
                *pb_nal_start = 1;
            h->i_poc = i_tmp;
        }
    }
    h->i_nal_type = nal.i_type;
    h->i_ref_idc = nal.i_ref_idc;
}