Example #1
0
int es_info_read(elementary_stream_info_t *es, bs_t *b) 
{ 
   int es_info_start = bs_pos(b); 
   es->stream_type = bs_read_u8(b); 
   bs_skip_u(b, 3); 
   es->elementary_PID = bs_read_u(b, 13);

   bs_skip_u(b, 4); 
   es->ES_info_length = bs_read_u(b, 12); 
   LOG_DEBUG_ARGS ("es_info_read: es_info_start = %d, bs_pos(b) = %d, b->end = %d", es_info_start, bs_pos(b), b->end - b->start);
   LOG_DEBUG_ARGS ("es_info_read pre-return %d", bs_pos(b) - es_info_start);
   
   LOG_DEBUG_ARGS ("es_info_read: PID = %d, streamType = 0x%x, ES_info_length = %d.  Calling read_descriptor_loop", 
      es->elementary_PID, es->stream_type, es->ES_info_length);
   
   read_descriptor_loop(es->descriptors, b, es->ES_info_length); 
   if (es->ES_info_length > MAX_ES_INFO_LEN) 
   {
      LOG_ERROR_ARGS("ES info length is 0x%02X, larger than maximum allowed 0x%02X", 
                     es->ES_info_length, MAX_ES_INFO_LEN); 
      reportAddErrorLogArgs("ES info length is 0x%02X, larger than maximum allowed 0x%02X", 
                     es->ES_info_length, MAX_ES_INFO_LEN); 
      SAFE_REPORT_TS_ERR(-60); 
      return 0;
   }

   LOG_DEBUG_ARGS ("es_info_read returning %d", bs_pos(b) - es_info_start);
   return bs_pos(b) - es_info_start;
}
// "factory methods"
int read_descriptor_loop(vqarray_t *desc_list, bs_t *b, int length) {
	int desc_start = bs_pos(b);

	while (length > bs_pos(b) - desc_start) {
		descriptor_t *desc = descriptor_new();
		desc = descriptor_read(desc, b);
		vqarray_add(desc_list, desc);
	}

	return bs_pos(b) - desc_start;
}
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;
}
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;
}
Example #5
0
File: set.c Project: submux/obe-vod
void x264_sei_pic_timing_write( x264_t *h, bs_t *s )
{
    x264_sps_t *sps = h->sps;
    bs_t q;
    uint8_t tmp_buf[100];
    bs_init( &q, tmp_buf, 100 );

    bs_realign( &q );

    if( sps->vui.b_nal_hrd_parameters_present || sps->vui.b_vcl_hrd_parameters_present )
    {
        bs_write( &q, sps->vui.hrd.i_cpb_removal_delay_length, h->fenc->i_cpb_delay - h->i_cpb_delay_pir_offset );
        bs_write( &q, sps->vui.hrd.i_dpb_output_delay_length, h->fenc->i_dpb_output_delay );
    }

    if( sps->vui.b_pic_struct_present )
    {
        bs_write( &q, 4, h->fenc->i_pic_struct-1 ); // We use index 0 for "Auto"

        // These clock timestamps are not standardised so we don't set them
        // They could be time of origin, capture or alternative ideal display
        for( int i = 0; i < num_clock_ts[h->fenc->i_pic_struct]; i++ )
            bs_write1( &q, 0 ); // clock_timestamp_flag
    }

    bs_align_10( &q );
    bs_flush( &q );

    x264_sei_write( s, tmp_buf, bs_pos( &q ) / 8, SEI_PIC_TIMING );
}
Example #6
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;
}
int es_info_read(elementary_stream_info_t *es, bs_t *b) {
	int es_info_start = bs_pos(b);
	es->stream_type = bs_read_u8(b);
	bs_skip_u(b, 3);
	es->elementary_PID = bs_read_u(b, 13);
	bs_skip_u(b, 4);
	es->ES_info_length = bs_read_u(b, 12);

	read_descriptor_loop(es->descriptors, b, es->ES_info_length);
	if (es->ES_info_length > MAX_ES_INFO_LEN) {
		LOG_ERROR_ARGS("ES info length is 0x%02X, larger than maximum allowed 0x%02X",
			es->ES_info_length, MAX_ES_INFO_LEN);
		SAFE_REPORT_TS_ERR(-60);
		return 0;
	}

	return bs_pos(b) - es_info_start;
}
Example #8
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;
}
Example #9
0
 int x264_rd_cost_mb( x264_t *h, int i_lambda2 )
{
    // backup mb_type because x264_macroblock_encode may change it to skip
    int i_type_bak = h->mb.i_type;
    int b_transform_bak = h->mb.b_transform_8x8;
    int i_ssd;
    int i_bits;

    x264_macroblock_encode( h );

    i_ssd = h->pixf.ssd[PIXEL_16x16]( h->mb.pic.p_fenc[0], h->mb.pic.i_stride[0],
                                      h->mb.pic.p_fdec[0], h->mb.pic.i_stride[0] )
          + h->pixf.ssd[PIXEL_8x8](   h->mb.pic.p_fenc[1], h->mb.pic.i_stride[1],
                                      h->mb.pic.p_fdec[1], h->mb.pic.i_stride[1] )
          + h->pixf.ssd[PIXEL_8x8](   h->mb.pic.p_fenc[2], h->mb.pic.i_stride[2],
                                      h->mb.pic.p_fdec[2], h->mb.pic.i_stride[2] );

    if( IS_SKIP( h->mb.i_type ) )
    {
        i_bits = 1;
    }
    else if( h->param.b_cabac )
    {
        x264_cabac_t cabac_tmp = h->cabac;
        bs_t bs_tmp = h->out.bs;
        cabac_tmp.s = &bs_tmp;
        x264_macroblock_write_cabac( h, &cabac_tmp );
        i_bits = x264_cabac_pos( &cabac_tmp ) - x264_cabac_pos( &h->cabac );
    }
    else
    {
        bs_t bs_tmp = h->out.bs;
        x264_macroblock_write_cavlc( h, &bs_tmp );
        i_bits = bs_pos( &bs_tmp ) - bs_pos( &h->out.bs );
    }
    h->mb.i_type = i_type_bak;
    h->mb.b_transform_8x8 = b_transform_bak;

    return i_ssd + i_bits * i_lambda2;
}
int pes_read(pes_packet_t *pes, uint8_t *buf, size_t len) {
	if (buf == NULL || pes == NULL)
		return 0;

	bs_t b;
	bs_init(&b, buf, len);

	int header_bytes = pes_read_header(&pes->header, &b);
	if (header_bytes > 0) {
		pes->payload.len = len - header_bytes;
		pes->payload.bytes = (uint8_t *) realloc(pes->payload.bytes, pes->payload.len);
		bs_read_bytes(&b, pes->payload.bytes, pes->payload.len);
	}
	return bs_pos(&b);
}
Example #11
0
File: mpls.c Project: CSRedRat/vlc
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 ) );
}
Example #12
0
int write_avcc(avcc_t* avcc, h264_stream_t* h, bs_t* b)
{
  bs_write_u8(b, 1); // configurationVersion = 1;
  bs_write_u8(b, avcc->AVCProfileIndication);
  bs_write_u8(b, avcc->profile_compatibility);
  bs_write_u8(b, avcc->AVCLevelIndication);
  bs_write_u(b, 6, 0x3F); // reserved = '111111'b;
  bs_write_u(b, 2, avcc->lengthSizeMinusOne);
  bs_write_u(b, 3, 0x07); // reserved = '111'b;

  bs_write_u(b, 5, avcc->numOfSequenceParameterSets);
  int i;
  for (i = 0; i < avcc->numOfSequenceParameterSets; i++)
  {
    int max_len = 1024; // FIXME
    uint8_t* buf = (uint8_t*)malloc(max_len);
    h->nal->nal_ref_idc = 3; // NAL_REF_IDC_PRIORITY_HIGHEST;
    h->nal->nal_unit_type = NAL_UNIT_TYPE_SPS;
    h->sps = avcc->sps_table[i];
    int len = write_nal_unit(h, buf, max_len);
    if (len < 0) { free(buf); continue; } // TODO report errors
    int sequenceParameterSetLength = len;
    bs_write_u(b, 16, sequenceParameterSetLength);
    bs_write_bytes(b, buf, len);
    free(buf);
  }

  bs_write_u(b, 8, avcc->numOfPictureParameterSets);
  for (i = 0; i < avcc->numOfPictureParameterSets; i++)
  {
    int max_len = 1024; // FIXME
    uint8_t* buf = (uint8_t*)malloc(max_len);
    h->nal->nal_ref_idc = 3; // NAL_REF_IDC_PRIORITY_HIGHEST;
    h->nal->nal_unit_type = NAL_UNIT_TYPE_PPS;
    h->pps = avcc->pps_table[i];
    int len = write_nal_unit(h, buf, max_len);
    if (len < 0) { free(buf); continue; } // TODO report errors
    int pictureParameterSetLength = len;
    bs_write_u(b, 16, pictureParameterSetLength);
    bs_write_bytes(b, buf, len);
    free(buf);
  }

  if (bs_overrun(b)) { return -1; }
  return bs_pos(b);
}
Example #13
0
int read_avcc(avcc_t* avcc, h264_stream_t* h, bs_t* b)
{
  avcc->configurationVersion = bs_read_u8(b);
  avcc->AVCProfileIndication = bs_read_u8(b);
  avcc->profile_compatibility = bs_read_u8(b);
  avcc->AVCLevelIndication = bs_read_u8(b);
  /* int reserved = */ bs_read_u(b, 6); // '111111'b;
  avcc->lengthSizeMinusOne = bs_read_u(b, 2);
  /* int reserved = */ bs_read_u(b, 3); // '111'b;

  avcc->numOfSequenceParameterSets = bs_read_u(b, 5);
  avcc->sps_table = (sps_t**)calloc(avcc->numOfSequenceParameterSets, sizeof(sps_t*));
  int i;
  for (i = 0; i < avcc->numOfSequenceParameterSets; i++)
  {
    int sequenceParameterSetLength = bs_read_u(b, 16);
    int len = sequenceParameterSetLength;
    uint8_t* buf = (uint8_t*)malloc(len);
    len = bs_read_bytes(b, buf, len);
    int rc = read_nal_unit(h, buf, len);
    free(buf);
    if (h->nal->nal_unit_type != NAL_UNIT_TYPE_SPS) { continue; } // TODO report errors
    if (rc < 0) { continue; }
    avcc->sps_table[i] = h->sps; // TODO copy data?
  }

  avcc->numOfPictureParameterSets = bs_read_u(b, 8);
  avcc->pps_table = (pps_t**)calloc(avcc->numOfSequenceParameterSets, sizeof(pps_t*));
  for (i = 0; i < avcc->numOfPictureParameterSets; i++)
  {
    int pictureParameterSetLength = bs_read_u(b, 16);
    int len = pictureParameterSetLength;
    uint8_t* buf = (uint8_t*)malloc(len);
    len = bs_read_bytes(b, buf, len);
    int rc = read_nal_unit(h, buf, len);
    free(buf);
    if (h->nal->nal_unit_type != NAL_UNIT_TYPE_PPS) { continue; } // TODO report errors
    if (rc < 0) { continue; }
    avcc->pps_table[i] = h->pps; // TODO copy data?
  }

  if (bs_overrun(b)) { return -1; }
  return bs_pos(b);
}
Example #14
0
File: set.c Project: submux/obe-vod
void x264_sei_recovery_point_write( x264_t *h, bs_t *s, int recovery_frame_cnt )
{
    bs_t q;
    uint8_t tmp_buf[100];
    bs_init( &q, tmp_buf, 100 );

    bs_realign( &q );

    bs_write_ue( &q, recovery_frame_cnt ); // recovery_frame_cnt
    bs_write1( &q, 1 );   //exact_match_flag 1
    bs_write1( &q, 0 );   //broken_link_flag 0
    bs_write( &q, 2, 0 ); //changing_slice_group 0

    bs_align_10( &q );
    bs_flush( &q );

    x264_sei_write( s, tmp_buf, bs_pos( &q ) / 8, SEI_RECOVERY_POINT );

}
Example #15
0
File: set.c Project: submux/obe-vod
void x264_sei_buffering_period_write( x264_t *h, bs_t *s )
{
    x264_sps_t *sps = h->sps;
    bs_t q;
    uint8_t tmp_buf[100];
    bs_init( &q, tmp_buf, 100 );

    bs_realign( &q );
    bs_write_ue( &q, sps->i_id );

    if( sps->vui.b_nal_hrd_parameters_present )
    {
        bs_write( &q, sps->vui.hrd.i_initial_cpb_removal_delay_length, h->initial_cpb_removal_delay );
        bs_write( &q, sps->vui.hrd.i_initial_cpb_removal_delay_length, h->initial_cpb_removal_delay_offset );
    }

    bs_align_10( &q );
    bs_flush( &q );

    x264_sei_write( s, tmp_buf, bs_pos( &q ) / 8, SEI_BUFFERING_PERIOD );
}
Example #16
0
File: set.c Project: submux/obe-vod
void x264_sei_frame_packing_write( x264_t *h, bs_t *s )
{
    bs_t q;
    uint8_t tmp_buf[100];
    bs_init( &q, tmp_buf, 100 );

    bs_realign( &q );

    bs_write_ue( &q, 0 );                         // frame_packing_arrangement_id
    bs_write1( &q, 0 );                           // frame_packing_arrangement_cancel_flag
    bs_write ( &q, 7, h->param.i_frame_packing ); // frame_packing_arrangement_type
    bs_write1( &q, 0 );                           // quincunx_sampling_flag

    // 0: views are unrelated, 1: left view is on the left, 2: left view is on the right
    bs_write ( &q, 6, 1 );                        // content_interpretation_type

    bs_write1( &q, 0 );                           // spatial_flipping_flag
    bs_write1( &q, 0 );                           // frame0_flipped_flag
    bs_write1( &q, 0 );                           // field_views_flag
    bs_write1( &q, h->param.i_frame_packing == 5 && !(h->fenc->i_frame&1) ); // current_frame_is_frame0_flag
    bs_write1( &q, 0 );                           // frame0_self_contained_flag
    bs_write1( &q, 0 );                           // frame1_self_contained_flag
    if ( /* quincunx_sampling_flag == 0 && */ h->param.i_frame_packing != 5 )
    {
        bs_write( &q, 4, 0 );                     // frame0_grid_position_x
        bs_write( &q, 4, 0 );                     // frame0_grid_position_y
        bs_write( &q, 4, 0 );                     // frame1_grid_position_x
        bs_write( &q, 4, 0 );                     // frame1_grid_position_y
    }
    bs_write( &q, 8, 0 );                         // frame_packing_arrangement_reserved_byte
    bs_write_ue( &q, 1 );                         // frame_packing_arrangement_repetition_period
    bs_write1( &q, 0 );                           // frame_packing_arrangement_extension_flag

    bs_align_10( &q );
    bs_flush( &q );

    x264_sei_write( s, tmp_buf, bs_pos( &q ) / 8, SEI_FRAME_PACKING );
}
Example #17
0
int conditional_access_section_read(conditional_access_section_t *cas, uint8_t *buf, size_t buf_len, uint32_t payload_unit_start_indicator,
                                    psi_table_buffer_t *catBuffer) 
{ 
   if (cas == NULL || buf == NULL) 
   {
      SAFE_REPORT_TS_ERR(-1); 
      return 0;
   }
   
   bs_t *b = NULL;

   if (!payload_unit_start_indicator &&  catBuffer->buffer == NULL)
   {
      // this TS packet is not start of table, and we have no cached table data
      LOG_WARN ("conditional_access_section_read: payload_unit_start_indicator not set and no cached data");
      return 0;
   }

   if (payload_unit_start_indicator)
   {
      uint8_t payloadStartPtr = buf[0];
      buf += (payloadStartPtr + 1);
      buf_len -= (payloadStartPtr + 1);
      LOG_DEBUG_ARGS ("conditional_access_section_read: payloadStartPtr = %d", payloadStartPtr);
   }

   // check for pat spanning multiple TS packets
   if (catBuffer->buffer != NULL)
   {
      LOG_DEBUG_ARGS ("conditional_access_section_read: catBuffer detected: catBufferAllocSz = %d, catBufferUsedSz = %d", 
         catBuffer->bufferAllocSz, catBuffer->bufferUsedSz);
      size_t numBytesToCopy = buf_len;
      if (buf_len > (catBuffer->bufferAllocSz - catBuffer->bufferUsedSz))
      {
         numBytesToCopy = catBuffer->bufferAllocSz - catBuffer->bufferUsedSz;
      }
         
      LOG_DEBUG_ARGS ("conditional_access_section_read: copying %d bytes to catBuffer", numBytesToCopy);
      memcpy (catBuffer->buffer + catBuffer->bufferUsedSz, buf, numBytesToCopy);
      catBuffer->bufferUsedSz += numBytesToCopy;
      
      if (catBuffer->bufferUsedSz < catBuffer->bufferAllocSz)
      {
         LOG_DEBUG ("conditional_access_section_read: catBuffer not yet full -- returning");
         return 0;
      }

      b = bs_new(catBuffer->buffer, catBuffer->bufferUsedSz);
   }
   else
   {
      b = bs_new(buf, buf_len);
   }
         
   cas->table_id = bs_read_u8(b); 
   if (cas->table_id != conditional_access_section) 
   {
      LOG_ERROR_ARGS("Table ID in CAT is 0x%02X instead of expected 0x%02X", 
                     cas->table_id, conditional_access_section); 
      reportAddErrorLogArgs("Table ID in CAT is 0x%02X instead of expected 0x%02X", 
                     cas->table_id, conditional_access_section); 
      SAFE_REPORT_TS_ERR(-30); 
      resetPSITableBuffer(catBuffer);
      bs_free (b);
      return 0;
   }
   
   // read byte 0

   cas->section_syntax_indicator = bs_read_u1(b); 
   if (!cas->section_syntax_indicator) 
   {
      LOG_ERROR("section_syntax_indicator not set in CAT"); 
      reportAddErrorLog("section_syntax_indicator not set in CAT"); 
      SAFE_REPORT_TS_ERR(-31); 
      resetPSITableBuffer(catBuffer);
      bs_free (b);
      return 0;
   }
   bs_skip_u(b, 3); // TODO read the zero bit, check it to be zero
   cas->section_length = bs_read_u(b, 12); 
   if (cas->section_length > 1021) // max CAT length 
   {
      LOG_ERROR_ARGS("CAT section length is 0x%02X, larger than maximum allowed 0x%02X", 
                     cas->section_length, MAX_SECTION_LEN); 
      reportAddErrorLogArgs("CAT section length is 0x%02X, larger than maximum allowed 0x%02X", 
                     cas->section_length, MAX_SECTION_LEN); 
      SAFE_REPORT_TS_ERR(-32); 
      resetPSITableBuffer(catBuffer);
      bs_free (b);
      return 0;
   }
   
   if (cas->section_length > bs_bytes_left(b))
   {
      LOG_DEBUG ("conditional_access_section_read: Detected section spans more than one TS packet -- allocating buffer");

      if (catBuffer->buffer != NULL)
      {
         // should never get here
         LOG_ERROR ("conditional_access_section_read: unexpected catBufffer");
         reportAddErrorLog ("conditional_access_section_read: unexpected catBufffer");
         resetPSITableBuffer(catBuffer);
      }

      catBuffer->bufferAllocSz = cas->section_length + 3;
      catBuffer->buffer = (uint8_t *)calloc (cas->section_length + 3, 1);
      memcpy (catBuffer->buffer, buf, buf_len);
      catBuffer->bufferUsedSz = buf_len;

      bs_free (b);
      return 0;
   }

   // read bytes 1-2
   bs_read_u16(b); 
   
   // read bytes 3,4
   bs_skip_u(b, 2); 
   cas->version_number = bs_read_u(b, 5); 
   cas->current_next_indicator = bs_read_u1(b); 
   if (!cas->current_next_indicator) LOG_WARN("This CAT is not yet applicable/n"); 
   
   // read byte 5
   
   cas->section_number = bs_read_u8(b); 
   cas->last_section_number = bs_read_u8(b); 
   if (cas->section_number != 0 || cas->last_section_number != 0) LOG_WARN("Multi-section CAT is not supported yet/n"); 
   
   // read bytes 6,7
   read_descriptor_loop(cas->descriptors, b, cas->section_length - 5 - 4 ); 

   // explanation: section_length gives us the length from the end of section_length
   // we used 5 bytes for the mandatory section fields, and will use another 4 bytes for CRC
   // the remaining bytes contain descriptors, most probably only one
   // again, it's much shorter in C :-)
   

   cas->CRC_32 = bs_read_u32(b); 
   
   // check CRC
   crc_t cas_crc = crc_init(); 
   cas_crc = crc_update(cas_crc, buf, bs_pos(b) - 4); 
   cas_crc = crc_finalize(cas_crc); 
   if (cas_crc != cas->CRC_32) 
   {
      LOG_ERROR_ARGS("CAT CRC_32 specified as 0x%08X, but calculated as 0x%08X", cas->CRC_32, cas_crc); 
      reportAddErrorLogArgs("CAT CRC_32 specified as 0x%08X, but calculated as 0x%08X", cas->CRC_32, cas_crc); 
      SAFE_REPORT_TS_ERR(-33); 
      resetPSITableBuffer(catBuffer);
      bs_free (b);
      return 0;
   } 

   
   bs_free(b); 
   resetPSITableBuffer(catBuffer);
   return 1;
}
Example #18
0
int program_map_section_read(program_map_section_t *pms, uint8_t *buf, size_t buf_size, uint32_t payload_unit_start_indicator,
   psi_table_buffer_t *pmtBuffer) 
{ 
   LOG_DEBUG ("program_map_section_read -- entering");
   if (pms == NULL || buf == NULL) 
   {
      SAFE_REPORT_TS_ERR(-1); 
      return 0;
   }

   bs_t *b = NULL;

   if (!payload_unit_start_indicator &&  pmtBuffer->buffer == NULL)
   {
      // this TS packet is not start of table, and we have no cached table data
      LOG_WARN ("program_map_section_read: payload_unit_start_indicator not set and no cached data");
      return 0;
   }

   if (payload_unit_start_indicator)
   {
      uint8_t payloadStartPtr = buf[0];
      buf += (payloadStartPtr + 1);
      buf_size -= (payloadStartPtr + 1);
      LOG_DEBUG_ARGS ("program_map_section_read: payloadStartPtr = %d", payloadStartPtr);
   }

   // check for pmt spanning multiple TS packets
   if (pmtBuffer->buffer != NULL)
   {
      LOG_DEBUG_ARGS ("program_map_section_read: pmtBuffer detected: pmtBufferAllocSz = %d, pmtBufferUsedSz = %d", pmtBuffer->bufferAllocSz, pmtBuffer->bufferUsedSz);
      size_t numBytesToCopy = buf_size;
      if (buf_size > (pmtBuffer->bufferAllocSz - pmtBuffer->bufferUsedSz))
      {
         numBytesToCopy = pmtBuffer->bufferAllocSz - pmtBuffer->bufferUsedSz;
      }
         
      LOG_DEBUG_ARGS ("program_map_section_read: copying %d bytes to pmtBuffer", numBytesToCopy);
      memcpy (pmtBuffer->buffer + pmtBuffer->bufferUsedSz, buf, numBytesToCopy);
      pmtBuffer->bufferUsedSz += numBytesToCopy;
      
      if (pmtBuffer->bufferUsedSz < pmtBuffer->bufferAllocSz)
      {
         LOG_DEBUG ("program_map_section_read: pmtBuffer not yet full -- returning");
         return 0;
      }

      b = bs_new(pmtBuffer->buffer, pmtBuffer->bufferUsedSz);
   }
   else
   {
      b = bs_new(buf, buf_size);
   }
      
   pms->table_id = bs_read_u8(b); 
   if (pms->table_id != TS_program_map_section) 
   {
      LOG_ERROR_ARGS("Table ID in PMT is 0x%02X instead of expected 0x%02X", pms->table_id, TS_program_map_section); 
      reportAddErrorLogArgs("Table ID in PMT is 0x%02X instead of expected 0x%02X", pms->table_id, TS_program_map_section); 
      SAFE_REPORT_TS_ERR(-40);
      resetPSITableBuffer(pmtBuffer);
      bs_free (b);
      return 0;
   }

   pms->section_syntax_indicator = bs_read_u1(b); 
   if (!pms->section_syntax_indicator) 
   {
      LOG_ERROR("section_syntax_indicator not set in PMT"); 
      reportAddErrorLog("section_syntax_indicator not set in PMT"); 
      SAFE_REPORT_TS_ERR(-41); 
      resetPSITableBuffer(pmtBuffer);
      bs_free (b);
      return 0;
   }
   
   bs_skip_u(b, 3); 

   pms->section_length = bs_read_u(b, 12); 
   if (pms->section_length > MAX_SECTION_LEN) 
   {
      LOG_ERROR_ARGS("PMT section length is 0x%02X, larger than maximum allowed 0x%02X", 
                     pms->section_length, MAX_SECTION_LEN); 
      reportAddErrorLogArgs("PMT section length is 0x%02X, larger than maximum allowed 0x%02X", 
                     pms->section_length, MAX_SECTION_LEN); 
      SAFE_REPORT_TS_ERR(-42); 
      resetPSITableBuffer(pmtBuffer);
      bs_free (b);
      return 0;
   }

   if (pms->section_length > bs_bytes_left(b))
   {
      LOG_DEBUG ("program_map_section_read: Detected section spans more than one TS packet -- allocating buffer");

      if (pmtBuffer->buffer != NULL)
      {
         // should never get here
         LOG_ERROR ("program_map_section_read: unexpected pmtBufffer");
         reportAddErrorLog ("program_map_section_read: unexpected pmtBufffer");
         resetPSITableBuffer(pmtBuffer);
      }

      pmtBuffer->bufferAllocSz = pms->section_length + 3;
      pmtBuffer->buffer = (uint8_t *)calloc (pms->section_length + 3, 1);
      memcpy (pmtBuffer->buffer, buf, buf_size);
      pmtBuffer->bufferUsedSz = buf_size;

      bs_free (b);
      return 0;
   }

   int section_start = bs_pos(b); 
   
   // bytes 0,1
   pms->program_number = bs_read_u16(b); 
   
   // byte 2;
   bs_skip_u(b, 2); 
   pms->version_number = bs_read_u(b, 5); 
   pms->current_next_indicator = bs_read_u1(b); 
   if (!pms->current_next_indicator) LOG_WARN("This PMT is not yet applicable/n"); 
   
   // bytes 3,4
   pms->section_number = bs_read_u8(b); 
   pms->last_section_number = bs_read_u8(b); 
   if (pms->section_number != 0 || pms->last_section_number != 0) 
   {
      LOG_ERROR("Multi-section PMT is not allowed/n"); 
      reportAddErrorLog("Multi-section PMT is not allowed/n"); 
      SAFE_REPORT_TS_ERR(-43); 
      resetPSITableBuffer(pmtBuffer);
      bs_free (b);
      return 0;
   }
   
   bs_skip_u(b, 3); 
   pms->PCR_PID = bs_read_u(b, 13); 
   if (pms->PCR_PID < GENERAL_PURPOSE_PID_MIN || pms->PCR_PID > GENERAL_PURPOSE_PID_MAX) 
   {
      LOG_ERROR_ARGS("PCR PID has invalid value 0x%02X", pms->PCR_PID); 
      reportAddErrorLogArgs("PCR PID has invalid value 0x%02X", pms->PCR_PID); 
      SAFE_REPORT_TS_ERR(-44); 
      resetPSITableBuffer(pmtBuffer);
      bs_free (b);
      return 0;
   }
 //  printf ("PCR PID = %d\n", pms->PCR_PID);
   bs_skip_u(b, 4); 
   
   pms->program_info_length = bs_read_u(b, 12); 
   if (pms->program_info_length > MAX_PROGRAM_INFO_LEN) 
   {
      LOG_ERROR_ARGS("PMT program info length is 0x%02X, larger than maximum allowed 0x%02X", 
                     pms->program_info_length, MAX_PROGRAM_INFO_LEN); 
      reportAddErrorLogArgs("PMT program info length is 0x%02X, larger than maximum allowed 0x%02X", 
                     pms->program_info_length, MAX_PROGRAM_INFO_LEN); 
      SAFE_REPORT_TS_ERR(-45); 
      resetPSITableBuffer(pmtBuffer);
      bs_free (b);
      return 0;
   }
   
   read_descriptor_loop(pms->descriptors, b, pms->program_info_length); 

   while (!bs_eof(b) && pms->section_length - (bs_pos(b) - section_start) > 4) // account for CRC
   {
      elementary_stream_info_t *es = es_info_new();
      es_info_read(es, b); 
      vqarray_add(pms->es_info, es);
   }
   
   pms->CRC_32 = bs_read_u32(b); 
   
   // check CRC
   crc_t pas_crc = crc_init(); 
   pas_crc = crc_update(pas_crc, b->start, bs_pos(b) - 4); 
   pas_crc = crc_finalize(pas_crc); 
   if (pas_crc != pms->CRC_32) 
   {
      LOG_ERROR_ARGS("PMT CRC_32 specified as 0x%08X, but calculated as 0x%08X", pms->CRC_32, pas_crc); 
      reportAddErrorLogArgs("PMT CRC_32 specified as 0x%08X, but calculated as 0x%08X", pms->CRC_32, pas_crc); 
      SAFE_REPORT_TS_ERR(-46); 
      resetPSITableBuffer(pmtBuffer);
      bs_free (b);
      return 0;
   } 
   else 
   {
      // LOG_DEBUG("PMT CRC_32 checked successfully");
   }
   
   int bytes_read = bs_pos(b); 
   bs_free(b); 

   resetPSITableBuffer(pmtBuffer);

   return bytes_read;
}
Example #19
0
//--------------------------------------------------------------------------------------------------------------------------------
//  Ray
///-------------------------------------------------------------------------------------------------------------------------------
bool COLLISION_WORLD::CastRay(
	const MATHVECTOR<float,3> & origin,
	const MATHVECTOR<float,3> & direction, const float length,
	const btCollisionObject * caster,
	COLLISION_CONTACT & contact,  //out
	CARDYNAMICS* cd, int w, //out pCarDyn, nWheel
	bool ignoreCars, bool camTilt, bool camDist) const
{
	btVector3 from = ToBulletVector(origin);
	btVector3 to = ToBulletVector(origin + direction * length);
	MyRayResultCallback res(from, to, caster, ignoreCars, camTilt, camDist);
	
	//  data to set
	MATHVECTOR<float,3> pos, norm;  float dist;
	const TRACKSURFACE * surf = TRACKSURFACE::None();
	btCollisionObject * col = NULL;  const BEZIER * bzr = NULL;
	
	world->rayTest(from, to, res);

	bool geometryHit = res.hasHit();
	if (geometryHit)
	{
		pos = ToMathVector<float>(res.m_hitPointWorld);
		norm = ToMathVector<float>(res.m_hitNormalWorld);
		dist = res.m_closestHitFraction * length;
		col = res.m_collisionObject;
		const TerData& td = pApp->scn->sc->td;

		if (col->isStaticObject() /*&& (c->getCollisionFlags() & btCollisionObject::CF_NO_CONTACT_RESPONSE == 0)*/)
		{
			long long ptrU = (long long)col->getCollisionShape()->getUserPointer(),
				su = ptrU & 0xFF00, mtr = ptrU & 0xFF;  //void*

			///  set surface, basing on shape type  -----------------

			if (ptrU)
			switch (su)
			{
				case SU_Road:  // road
				{
					int id = td.layerRoad.surfId;  // Road[mtr].
					surf = &pApp->pGame->surfaces[id];

					if (cd)
					{	cd->iWhOnRoad[w] = 1;   cd->whRoadMtr[w] = mtr;  cd->whTerMtr[w] = 0;  }
				}	break;

				case SU_Pipe:  // pipe
				{
					int id = td.layerRoad.surfId;
					surf = &pApp->pGame->surfaces[id];

					if (cd)
					{	cd->iWhOnRoad[w] = 2;   cd->whRoadMtr[w] = mtr+30;  cd->whTerMtr[w] = 0;  }
				}	break;

				case SU_Terrain:  // Terrain  get surface from blendmap mtr
				{
					int t = pApp->blendMapSize;
					float tws = td.fTerWorldSize;

					int mx = (pos[0] + 0.5*tws)/tws*t;  mx = std::max(0,std::min(t-1, mx));
					int my = (pos[1] + 0.5*tws)/tws*t;  my = std::max(0,std::min(t-1, t-1-my));

					int mtr = pApp->blendMtr[my*t + mx];

					int id = td.layersAll[td.layers[mtr]].surfId;
					surf = &pApp->pGame->surfaces[id];

					if (cd)                                              // mtr 0 = not on terrain
					{	cd->iWhOnRoad[w] = 0;   cd->whRoadMtr[w] = 60;  cd->whTerMtr[w] = mtr + 1;  }
				}	break;
				
				//case SU_RoadWall: //case SU_RoadColumn:
				//case SU_Vegetation: case SU_Border:
				//case SU_ObjectStatic: //case SU_ObjectDynamic:
				default:
				{
					int id = td.layerRoad.surfId;
					surf = &pApp->pGame->surfaces[id];

					if (cd)
					{	cd->iWhOnRoad[w] = 0;   cd->whRoadMtr[w] = 80;  cd->whTerMtr[w] = 0;  }
				}	break;
			}
			else  //if (ptrU == 0)
			{
				int id = td.layersAll[0].surfId;  //0 only 1st
				surf = &pApp->pGame->surfaces[id];

				if (cd)
				{	cd->iWhOnRoad[w] = 0;   cd->whRoadMtr[w] = 0;  cd->whTerMtr[w] = 1;  }

				/*void * ptr = col->getUserPointer();
				if (ptr != NULL)
				{
					const TRACK_OBJECT * const obj = reinterpret_cast <const TRACK_OBJECT * const> (ptr);
					assert(obj);
					surf = obj->GetSurface();
				}
				else  // track geometry
				{
					int shapeId = res.m_shapeId;
					//assert(shapeId >= 0 && shapeId < trackSurface.size());
					if (shapeId >= trackSurface.size() || shapeId < 0)  shapeId = 0;  //crash hf-
					if (trackSurface.size() > 0)
						surf = 0;//trackSurface[shapeId];
				}*/
			}
		}
		
		//  track bezierpatch collision
		if (track != NULL)
		{
			MATHVECTOR<float,3> bs_pos(origin[1], origin[2], origin[0]);  //bezierspace
			MATHVECTOR<float,3> bs_dir(direction[1], direction[2], direction[0]);
			MATHVECTOR<float,3> colpos, colnorm;
			const BEZIER * colpatch = NULL;
			bool bezierHit = track->CastRay(bs_pos, bs_dir, length, colpos, colpatch, colnorm);
			if (bezierHit)
			{
				pos = MATHVECTOR<float,3> (colpos[2], colpos[0], colpos[1]);
				norm = MATHVECTOR<float,3> (colnorm[2], colnorm[0], colnorm[1]);
				dist = (colpos - bs_pos).Magnitude();
				//surf = 0;//track->GetRoadSurface();
				bzr = colpatch;  col = NULL;

				int id = td.layerRoad.surfId;
				surf = &pApp->pGame->surfaces[id];

				if (cd)
				{	cd->iWhOnRoad[w] = 1;   cd->whRoadMtr[w] = 0;  cd->whTerMtr[w] = 0;  }
			}
		}

		contact.Set(pos, norm, dist, surf, bzr, col);
		return true;
	}
	
	//  should only happen on vehicle rollover
	contact.Set(origin + direction * length, -direction, length, surf, bzr, col);
	return false;
}
Example #20
0
int program_association_section_read(program_association_section_t *pas, uint8_t *buf, size_t buf_len, uint32_t payload_unit_start_indicator,
                                     psi_table_buffer_t *patBuffer)
{ 
   vqarray_t *programs;
   int num_programs = 0;

   if (pas == NULL || buf == NULL) 
   {
      SAFE_REPORT_TS_ERR(-1); 
      return 0;
   }

   bs_t *b = NULL;

   if (!payload_unit_start_indicator &&  patBuffer->buffer == NULL)
   {
      // this TS packet is not start of table, and we have no cached table data
      LOG_WARN ("program_association_section_read: payload_unit_start_indicator not set and no cached data");
      return 0;
   }

   if (payload_unit_start_indicator)
   {
      uint8_t payloadStartPtr = buf[0];
      buf += (payloadStartPtr + 1);
      buf_len -= (payloadStartPtr + 1);
      LOG_DEBUG_ARGS ("program_association_section_read: payloadStartPtr = %d", payloadStartPtr);
   }


   // check for pat spanning multiple TS packets
   if (patBuffer->buffer != NULL)
   {
      LOG_DEBUG_ARGS ("program_association_section_read: patBuffer detected: patBufferAllocSz = %d, patBufferUsedSz = %d", 
         patBuffer->bufferAllocSz, patBuffer->bufferUsedSz);
      size_t numBytesToCopy = buf_len;
      if (buf_len > (patBuffer->bufferAllocSz - patBuffer->bufferUsedSz))
      {
         numBytesToCopy = patBuffer->bufferAllocSz - patBuffer->bufferUsedSz;
      }
         
      LOG_DEBUG_ARGS ("program_association_section_read: copying %d bytes to patBuffer", numBytesToCopy);
      memcpy (patBuffer->buffer + patBuffer->bufferUsedSz, buf, numBytesToCopy);
      patBuffer->bufferUsedSz += numBytesToCopy;
      
      if (patBuffer->bufferUsedSz < patBuffer->bufferAllocSz)
      {
         LOG_DEBUG ("program_association_section_read: patBuffer not yet full -- returning");
         return 0;
      }

      b = bs_new(patBuffer->buffer, patBuffer->bufferUsedSz);
   }
   else
   {
      b = bs_new(buf, buf_len);
   }
      

   pas->table_id = bs_read_u8(b); 
   if (pas->table_id != program_association_section) 
   {
      LOG_ERROR_ARGS("Table ID in PAT is 0x%02X instead of expected 0x%02X", 
                     pas->table_id, program_association_section); 
      reportAddErrorLogArgs("Table ID in PAT is 0x%02X instead of expected 0x%02X", 
                     pas->table_id, program_association_section); 
      SAFE_REPORT_TS_ERR(-30); 
      resetPSITableBuffer(patBuffer);
      bs_free (b);
      return 0;
   }
   
   // read byte 0
   
   pas->section_syntax_indicator = bs_read_u1(b); 
   if (!pas->section_syntax_indicator) 
   {
      LOG_ERROR("section_syntax_indicator not set in PAT"); 
      reportAddErrorLog("section_syntax_indicator not set in PAT"); 
      SAFE_REPORT_TS_ERR(-31); 
      resetPSITableBuffer(patBuffer);
      bs_free (b);
      return 0;
   }
   bs_skip_u(b, 3); // TODO read the zero bit, check it to be zero
   pas->section_length = bs_read_u(b, 12); 
   if (pas->section_length > MAX_SECTION_LEN) 
   {
      LOG_ERROR_ARGS("PAT section length is 0x%02X, larger than maximum allowed 0x%02X", 
                     pas->section_length, MAX_SECTION_LEN); 
      reportAddErrorLogArgs("PAT section length is 0x%02X, larger than maximum allowed 0x%02X", 
                     pas->section_length, MAX_SECTION_LEN); 
      SAFE_REPORT_TS_ERR(-32); 
      resetPSITableBuffer(patBuffer);
      bs_free (b);
      return 0;
   }
   
   if (pas->section_length > bs_bytes_left(b))
   {
      LOG_DEBUG ("program_association_section_read: Detected section spans more than one TS packet -- allocating buffer");

      if (patBuffer->buffer != NULL)
      {
         // should never get here
         LOG_ERROR ("program_association_section_read: unexpected patBufffer");
         reportAddErrorLog ("program_association_section_read: unexpected patBufffer");
         resetPSITableBuffer(patBuffer);
      }

      patBuffer->bufferAllocSz = pas->section_length + 3;
      patBuffer->buffer = (uint8_t *)calloc (pas->section_length + 3, 1);
      memcpy (patBuffer->buffer, buf, buf_len);
      patBuffer->bufferUsedSz = buf_len;

      bs_free (b);
      return 0;
   }

   // read bytes 1,2
   
   pas->transport_stream_id = bs_read_u16(b); 
   
   // read bytes 3,4
   
   bs_skip_u(b, 2); 
   pas->version_number = bs_read_u(b, 5); 
   pas->current_next_indicator = bs_read_u1(b); 
   if (!pas->current_next_indicator) LOG_WARN("This PAT is not yet applicable/n"); 
   
   // read byte 5
   
   pas->section_number = bs_read_u8(b); 
   pas->last_section_number = bs_read_u8(b); 
   if (pas->section_number != 0 || pas->last_section_number != 0) LOG_WARN("Multi-section PAT is not supported yet/n"); 
   
   // read bytes 6,7
   
   num_programs = (pas->section_length - 5 - 4) / 4;  // Programs listed in the PAT
   // explanation: section_length gives us the length from the end of section_length
   // we used 5 bytes for the mandatory section fields, and will use another 4 bytes for CRC
   // the remaining bytes contain program information, which is 4 bytes per iteration
   // It's much shorter in C :-)

   // Read the program loop, but ignore the NIT PID "program"
   programs = vqarray_new();
   for (uint32_t i = 0; i < num_programs; i++)
   {
      program_info_t *prog = malloc(sizeof(program_info_t));
      prog->program_number = bs_read_u16(b);
      if (prog->program_number == 0) { // Skip the NIT PID program (not a real program)
         free(prog);
         bs_skip_u(b, 16);
         continue;
      }
      bs_skip_u(b, 3);
      prog->program_map_PID = bs_read_u(b, 13);
      vqarray_add(programs, (vqarray_elem_t*)prog);
   }

   // This is our true number of programs
   pas->_num_programs = vqarray_length(programs);
   
   if (pas->_num_programs > 1) LOG_WARN_ARGS("%zd programs found, but only SPTS is fully supported. Patches are welcome.", pas->_num_programs); 
   
   // Copy form our vqarray into the native array
   pas->programs = malloc(pas->_num_programs * sizeof(program_info_t)); 
   for (uint32_t i = 0; i < pas->_num_programs; i++) 
   {
      program_info_t* prog = (program_info_t*)vqarray_pop(programs);
      pas->programs[i] = *prog;
      free(prog);
   }
   vqarray_free(programs);
   
   pas->CRC_32 = bs_read_u32(b); 
   
   // check CRC
   crc_t pas_crc = crc_init(); 
   pas_crc = crc_update(pas_crc, buf, bs_pos(b) - 4); 
   pas_crc = crc_finalize(pas_crc); 
   if (pas_crc != pas->CRC_32) 
   {
      LOG_ERROR_ARGS("PAT CRC_32 specified as 0x%08X, but calculated as 0x%08X", pas->CRC_32, pas_crc); 
      reportAddErrorLogArgs("PAT CRC_32 specified as 0x%08X, but calculated as 0x%08X", pas->CRC_32, pas_crc); 
      SAFE_REPORT_TS_ERR(-33); 
      resetPSITableBuffer(patBuffer);
      bs_free (b);
      return 0;
   } 
   else 
   {
      // LOG_DEBUG("PAT CRC_32 checked successfully");
      // don't enable unless you want to see this every ~100ms
   }
   

   bs_free(b); 
            
   resetPSITableBuffer(patBuffer);

   return 1;
}
int bd_clpi_Parse( bd_clpi_t *p_clpi, bs_t *s, int i_id )
{
    const int i_start = bs_pos( s ) / 8;

    /* */
    if( bs_read( s, 32 ) != 0x48444D56 )
        return VLC_EGENERIC;
    const uint32_t i_version = bs_read( s, 32 );
    if( i_version != 0x30313030 && i_version != 0x30323030 )
        return VLC_EGENERIC;

    /* */
    const uint32_t i_sequence_start = bs_read( s, 32 );
    const uint32_t i_program_start = bs_read( s, 32 );
    const uint32_t i_cpi_start = bs_read( s, 32 );
    bs_skip( s, 32 );   /* mark start */
    bs_skip( s, 32 );   /* extension start */

    /* */
    p_clpi->i_id = i_id;

    /* Read sequence */
    bs_t ss = *s;
    bs_skip( &ss, 8 * ( i_start + i_sequence_start ) - bs_pos( s ) );
    bs_skip( &ss, 32 ); /* Length */
    bs_skip( &ss, 8 );
    bs_skip( &ss, 8 );  /* ATC sequence count (MUST be 1 ?) */
    bs_skip( &ss, 32 ); /* ATC start (MUST be 0) */
    const int i_stc = bs_read( &ss, 8 );
    bs_skip( &ss, 8 );  /* STC ID offset (MUST be 0 ? */

    p_clpi->p_stc = (bd_clpi_stc_t *)calloc( i_stc, sizeof(*p_clpi->p_stc) );			// sunqueen modify
    for( p_clpi->i_stc = 0; p_clpi->i_stc < i_stc; p_clpi->i_stc++ )
    {
        if( !p_clpi->p_stc )
            break;
        bd_clpi_stc_Parse( &p_clpi->p_stc[p_clpi->i_stc], &ss );
    }

    /* Program */
    bs_t ps = *s;
    bs_skip( &ps, 8 * ( i_start + i_program_start ) - bs_pos( s ) );
    bs_skip( &ps, 32 ); /* Length */
    bs_skip( &ps, 8 );
    bs_skip( &ps, 8 );  /* Program count (MUST be 1 ?) */
    bs_skip( &ps, 32 ); /* Program sequence start (MUST be 0) */
    p_clpi->i_pmt_pid = bs_read( &ps, 16 );
    const int i_stream = bs_read( &ps, 8 );
    bs_skip( &ps, 8 );  /* Group count (MUST be 1 ?) */

    p_clpi->p_stream = (bd_clpi_stream_t *)calloc( i_stream, sizeof(*p_clpi->p_stream) );			// sunqueen modify
    for( p_clpi->i_stream = 0; p_clpi->i_stream < i_stream; p_clpi->i_stream++ )
    {
        if( !p_clpi->p_stream )
            break;
        bd_clpi_stream_Parse( &p_clpi->p_stream[p_clpi->i_stream], &ps );
    }

    /* Read CPI */
    bs_t cs = *s;
    bs_skip( &cs, 8 * ( i_start + i_cpi_start ) - bs_pos( s ) );

    const uint32_t i_cpi_length = bs_read( &cs, 32 );
    if( i_cpi_length > 0 )
    {
        bs_skip( &cs, 12 );
        bs_skip( &cs, 4 );  /* Type (MUST be 1) */

        /* EPMap */
        const int i_epmap_start = bs_pos( &cs ) / 8;
        bs_skip( &cs, 8 );
        const int i_ep_map = bs_read( &cs, 8 );

        p_clpi->p_ep_map = (bd_clpi_ep_map_t *)calloc( i_ep_map, sizeof(*p_clpi->p_ep_map) );			// sunqueen modify
        for( p_clpi->i_ep_map = 0; p_clpi->i_ep_map < i_ep_map; p_clpi->i_ep_map++ )
        {
            if( !p_clpi->p_ep_map )
                break;

            if( bd_clpi_ep_map_Parse( &p_clpi->p_ep_map[p_clpi->i_ep_map],
                                      &cs, i_epmap_start ) )
                break;
        }
    }
    else
    {
        p_clpi->i_ep_map = 0;
        p_clpi->p_ep_map = NULL;
    }
    return VLC_SUCCESS;
}
Example #22
0
//7.3.1 NAL unit syntax
int structure(nal_unit)(h264_stream_t* h, uint8_t* buf, int size)
{
    nal_t* nal = h->nal;

    int nal_size = size;
    int rbsp_size = size;
    uint8_t* rbsp_buf = (uint8_t*)calloc(1, rbsp_size);

    if( is_reading )
    {
        int rc = nal_to_rbsp(buf, &nal_size, rbsp_buf, &rbsp_size);

        if (rc < 0) {
            free(rbsp_buf);    // handle conversion error
            return -1;
        }
    }

    if( is_writing )
    {
        rbsp_size = size*3/4; // NOTE this may have to be slightly smaller (3/4 smaller, worst case) in order to be guaranteed to fit
    }

    bs_t* b = bs_new(rbsp_buf, rbsp_size);
    value( forbidden_zero_bit, f(1, 0) );
    value( nal->nal_ref_idc, u(2) );
    value( nal->nal_unit_type, u(5) );

    switch ( nal->nal_unit_type )
    {
    case NAL_UNIT_TYPE_CODED_SLICE_IDR:
    case NAL_UNIT_TYPE_CODED_SLICE_NON_IDR:
    case NAL_UNIT_TYPE_CODED_SLICE_AUX:
        structure(slice_layer_rbsp)(h, b);
        break;

#ifdef HAVE_SEI
    case NAL_UNIT_TYPE_SEI:
        structure(sei_rbsp)(h, b);
        break;
#endif

    case NAL_UNIT_TYPE_SPS:
        structure(seq_parameter_set_rbsp)(h, b);
        break;

    case NAL_UNIT_TYPE_PPS:
        structure(pic_parameter_set_rbsp)(h, b);
        break;

    case NAL_UNIT_TYPE_AUD:
        structure(access_unit_delimiter_rbsp)(h, b);
        break;

    case NAL_UNIT_TYPE_END_OF_SEQUENCE:
        structure(end_of_seq_rbsp)(h, b);
        break;

    case NAL_UNIT_TYPE_END_OF_STREAM:
        structure(end_of_stream_rbsp)(h, b);
        break;

    case NAL_UNIT_TYPE_FILLER:
    case NAL_UNIT_TYPE_SPS_EXT:
    case NAL_UNIT_TYPE_UNSPECIFIED:
    case NAL_UNIT_TYPE_CODED_SLICE_DATA_PARTITION_A:
    case NAL_UNIT_TYPE_CODED_SLICE_DATA_PARTITION_B:
    case NAL_UNIT_TYPE_CODED_SLICE_DATA_PARTITION_C:
    default:
        return -1;
    }

    if (bs_overrun(b)) {
        bs_free(b);
        free(rbsp_buf);
        return -1;
    }

    if( is_writing )
    {
        // now get the actual size used
        rbsp_size = bs_pos(b);

        int rc = rbsp_to_nal(rbsp_buf, &rbsp_size, buf, &nal_size);
        if (rc < 0) {
            bs_free(b);
            free(rbsp_buf);
            return -1;
        }
    }

    bs_free(b);
    free(rbsp_buf);

    return nal_size;
}
Example #23
0
File: mpls.c Project: CSRedRat/vlc
void bd_mpls_play_item_Parse( bd_mpls_play_item_t *p_item, bs_t *s )
{
    const int i_length = bs_read( s, 16 );
    const int i_start = bs_pos( s ) / 8;

    char psz_name[5+1];
    for( int j = 0; j < 5; j++ )
        psz_name[j] = bs_read( s, 8 );
    psz_name[5] = '\0';

    p_item->clpi.i_id = strtol( psz_name, NULL, 10 );

    bs_skip( s, 32 );

    bs_skip( s, 11 );
    const bool b_angle = bs_read( s, 1 );

    p_item->i_connection = bs_read( s, 4 );
    p_item->clpi.i_stc_id = bs_read( s, 8 );
    p_item->i_in_time = bs_read( s, 32 );
    p_item->i_out_time = bs_read( s, 32 );
    bs_skip( s, 64 );
    bs_skip( s, 1 );
    bs_skip( s, 7 );
    p_item->i_still = bs_read( s, 8 );
    p_item->i_still_time = bs_read( s, 16 );
    if( p_item->i_still == BD_MPLS_PLAY_ITEM_STILL_NONE )
        p_item->i_still_time = 0;
    else if( p_item->i_still == BD_MPLS_PLAY_ITEM_STILL_INFINITE )
        p_item->i_still_time = INT_MAX;

    if( b_angle )
    {
        const int i_angle = bs_read( s, 8 );
        bs_skip( s, 6 );
        p_item->b_angle_different_audio = bs_read( s, 1 );
        p_item->b_angle_seamless = bs_read( s, 1 );

        p_item->p_clpi = calloc( i_angle, sizeof(*p_item->p_clpi) );
        for( p_item->i_clpi = 0; p_item->i_clpi < i_angle; p_item->i_clpi++ )
        {
            if( !p_item->p_clpi )
                break;

            bd_mpls_clpi_t *p_clpi = &p_item->p_clpi[p_item->i_clpi];

            char psz_name[5+1];
            for( int j = 0; j < 5; j++ )
                psz_name[j] = bs_read( s, 8 );
            psz_name[5] = '\0';

            p_clpi->i_id = strtol( psz_name, NULL, 10 );

            bs_skip( s, 32 );

            p_clpi->i_stc_id = bs_read( s, 8 );
        }
    }
    else
    {
        p_item->i_clpi = 0;
        p_item->p_clpi = NULL;
        p_item->b_angle_different_audio = false;
        p_item->b_angle_seamless = true;
    }

    /* STN Table */
    bs_skip( s, 16 );  /* Length */
    bs_skip( s, 16 );

    const int i_video = bs_read( s, 8 );
    const int i_audio = bs_read( s, 8 );
    const int i_pg = bs_read( s, 8 );
    const int i_ig = bs_read( s, 8 );
    const int i_audio_2 = bs_read( s, 8 );
    const int i_video_2 = bs_read( s, 8 );
    const int i_pip_pg = bs_read( s, 8 );
    bs_skip( s, 40 );

    p_item->i_stream = 0;
    p_item->p_stream = calloc( i_video + i_audio + i_pg + i_ig,
                               sizeof(*p_item->p_stream) );

    for( int j = 0; j < i_video; j++, p_item->i_stream++ )
    {
        if( !p_item->p_stream )
            break;

        bd_mpls_stream_Parse( &p_item->p_stream[p_item->i_stream], s,
                              BD_MPLS_STREAM_CLASS_PRIMARY_VIDEO );
    }
    for( int j = 0; j < i_audio; j++, p_item->i_stream++ )
    {
        if( !p_item->p_stream )
            break;

        bd_mpls_stream_Parse( &p_item->p_stream[p_item->i_stream], s,
                              BD_MPLS_STREAM_CLASS_PRIMARY_AUDIO );
    }
    for( int j = 0; j < i_pg; j++, p_item->i_stream++ )
    {
        if( !p_item->p_stream )
            break;

        bd_mpls_stream_Parse( &p_item->p_stream[p_item->i_stream], s,
                              BD_MPLS_STREAM_CLASS_PG );
    }
    for( int j = 0; j < i_ig; j++, p_item->i_stream++ )
    {
        if( !p_item->p_stream )
            break;

        bd_mpls_stream_Parse( &p_item->p_stream[p_item->i_stream], s,
                              BD_MPLS_STREAM_CLASS_IG );
    }
    for( int j = 0; j < i_audio_2; j++ )
    {
        /* TODO I need samples */
    }
    for( int j = 0; j < i_video_2; j++ )
    {
        /* TODO I need samples */
    }
    for( int j = 0; j < i_pip_pg; j++ )
    {
        /* TODO I need samples */
    }

    bs_skip( s, 8 * ( i_start + i_length ) - bs_pos( s ) );
}
int program_map_section_read(program_map_section_t *pms, uint8_t *buf, size_t buf_size) {
	if (pms == NULL || buf == NULL) {
		SAFE_REPORT_TS_ERR(-1);
		return 0;
	}

	bs_t *b = bs_new(buf, buf_size);

	pms->table_id = bs_read_u8(b);
	if (pms->table_id != TS_program_map_section) {
		LOG_ERROR_ARGS("Table ID in PMT is 0x%02X instead of expected 0x%02X", pms->table_id, TS_program_map_section);
		SAFE_REPORT_TS_ERR(-40);
		return 0;
	}

	pms->section_syntax_indicator = bs_read_u1(b);
	if (!pms->section_syntax_indicator) {
		LOG_ERROR("section_syntax_indicator not set in PMT");
		SAFE_REPORT_TS_ERR(-41);
		return 0;
	}

	bs_skip_u(b, 3);
	pms->section_length = bs_read_u(b, 12);
	if (pms->section_length > MAX_SECTION_LEN) {
		LOG_ERROR_ARGS("PMT section length is 0x%02X, larger than maximum allowed 0x%02X",
			pms->section_length, MAX_SECTION_LEN);
		SAFE_REPORT_TS_ERR(-42);
		return 0;
	}

	int section_start = bs_pos(b);

	// bytes 0,1
	pms->program_number = bs_read_u16(b);

	// byte 2;
	bs_skip_u(b, 2);
	pms->version_number = bs_read_u(b, 5);
	pms->current_next_indicator = bs_read_u1(b);
	if (!pms->current_next_indicator)
		LOG_WARN("This PMT is not yet applicable/n");

	// bytes 3,4
	pms->section_number = bs_read_u8(b);
	pms->last_section_number = bs_read_u8(b);
	if (pms->section_number != 0 || pms->last_section_number != 0) {
		LOG_ERROR("Multi-section PMT is not allowed/n");
		SAFE_REPORT_TS_ERR(-43);
		return 0;
	}

	bs_skip_u(b, 3);
	pms->PCR_PID = bs_read_u(b, 13);
	if (pms->PCR_PID < GENERAL_PURPOSE_PID_MIN || pms->PCR_PID > GENERAL_PURPOSE_PID_MAX) {
		LOG_ERROR_ARGS("PCR PID has invalid value 0x%02X", pms->PCR_PID);
		SAFE_REPORT_TS_ERR(-44);
		return 0;
	}
	bs_skip_u(b, 4);

	pms->program_info_length = bs_read_u(b, 12);
	if (pms->program_info_length > MAX_PROGRAM_INFO_LEN) {
		LOG_ERROR_ARGS("PMT program info length is 0x%02X, larger than maximum allowed 0x%02X",
			pms->program_info_length, MAX_PROGRAM_INFO_LEN);
		SAFE_REPORT_TS_ERR(-45);
		return 0;
	}

	read_descriptor_loop(pms->descriptors, b, pms->program_info_length);

	while (pms->section_length - (bs_pos(b) - section_start) > 4) { // account for CRC
		elementary_stream_info_t *es = es_info_new();
		es_info_read(es, b);
		vqarray_add(pms->es_info, es);
	}

	pms->CRC_32 = bs_read_u32(b);

	// check CRC
	crc_t pas_crc = crc_init();
	pas_crc = crc_update(pas_crc, buf, bs_pos(b) - 4);
	pas_crc = crc_finalize(pas_crc);
	if (pas_crc != pms->CRC_32) {
		LOG_ERROR_ARGS("PMT CRC_32 specified as 0x%08X, but calculated as 0x%08X", pms->CRC_32, pas_crc);
		SAFE_REPORT_TS_ERR(-46);
		return 0;
	} else {
		LOG_DEBUG("PMT CRC_32 checked successfully");
	}

	int bytes_read = bs_pos(b);
	bs_free(b);

	return bytes_read;
}
Example #25
0
File: mpls.c Project: CSRedRat/vlc
int bd_mpls_Parse( bd_mpls_t *p_mpls, bs_t *s, int i_id )
{
    const int i_start = bs_pos( s ) / 8;

    /* */
    if( bs_read( s, 32 ) != 0x4d504c53 )
        return VLC_EGENERIC;
    const uint32_t i_version = bs_read( s, 32 );
    if( i_version != 0x30313030 && i_version != 0x30323030 )
        return VLC_EGENERIC;

    const uint32_t i_play_item_start = bs_read( s, 32 );
    const uint32_t i_mark_start = bs_read( s, 32 );
    bs_skip( s, 32 );   /* Extension start */

    /* */
    p_mpls->i_id = i_id;

    /* Read AppInfo: ignored */

    /* Read Playlist */
    bs_t ps = *s;
    bs_skip( &ps, 8 * ( i_start + i_play_item_start ) - bs_pos( s ) );
    bs_skip( &ps, 32 ); /* Length */
    bs_skip( &ps, 16 );
    const int i_play_item = bs_read( &ps, 16 );
    const int i_sub_path = bs_read( &ps, 16 );

    p_mpls->p_play_item = calloc( i_play_item, sizeof(*p_mpls->p_play_item) );
    for( p_mpls->i_play_item = 0; p_mpls->i_play_item < i_play_item; p_mpls->i_play_item++ )
    {
        if( !p_mpls->p_play_item )
            break;
        bd_mpls_play_item_t *p_item = &p_mpls->p_play_item[p_mpls->i_play_item];

        bd_mpls_play_item_Parse( p_item, &ps );
    }
    p_mpls->p_sub_path = calloc( i_sub_path, sizeof(*p_mpls->p_sub_path) );
    for( p_mpls->i_sub_path = 0; p_mpls->i_sub_path < i_sub_path; p_mpls->i_sub_path++ )
    {
        if( !p_mpls->p_sub_path )
            break;
        bd_mpls_sub_path_t *p_sub = &p_mpls->p_sub_path[p_mpls->i_sub_path];

        bd_mpls_sub_path_Parse( p_sub, &ps );
    }

    /* Read Mark */
    bs_t ms = *s;
    bs_skip( &ms, 8 * ( i_start + i_mark_start ) - bs_pos( s ) );
    bs_skip( &ms, 32 );
    const int i_mark = bs_read( &ms, 16 );

    p_mpls->p_mark = calloc( i_mark, sizeof(*p_mpls->p_mark) );
    for( p_mpls->i_mark = 0; p_mpls->i_mark < i_mark; p_mpls->i_mark++ )
    {
        if( !p_mpls->p_mark )
            break;
        bd_mpls_mark_t *p_mark = &p_mpls->p_mark[p_mpls->i_mark];

        bd_mpls_mark_Parse( p_mark, &ms );
    }

    /* Read Extension: ignored */

    return VLC_SUCCESS;
}
int program_association_section_read(program_association_section_t *pas, uint8_t *buf, size_t buf_len) {
	if (pas == NULL || buf == NULL) {
		SAFE_REPORT_TS_ERR(-1);
		return 0;
	}

	bs_t *b = bs_new(buf, buf_len);

	pas->table_id = bs_read_u8(b);
	if (pas->table_id != program_association_section) {
		LOG_ERROR_ARGS("Table ID in PAT is 0x%02X instead of expected 0x%02X",
			pas->table_id, program_association_section);
		SAFE_REPORT_TS_ERR(-30);
		return 0;
	}

	// read byte 0

	pas->section_syntax_indicator = bs_read_u1(b);
	if (!pas->section_syntax_indicator) {
		LOG_ERROR("section_syntax_indicator not set in PAT");
		SAFE_REPORT_TS_ERR(-31);
		return 0;
	}
	bs_skip_u(b, 3); // TODO read the zero bit, check it to be zero
	pas->section_length = bs_read_u(b, 12);
	if (pas->section_length > MAX_SECTION_LEN) {
		LOG_ERROR_ARGS("PAT section length is 0x%02X, larger than maximum allowed 0x%02X",
			pas->section_length, MAX_SECTION_LEN);
		SAFE_REPORT_TS_ERR(-32);
		return 0;
	}

	// read bytes 1,2

	pas->transport_stream_id = bs_read_u16(b);

	// read bytes 3,4

	bs_skip_u(b, 2);
	pas->version_number = bs_read_u(b, 5);
	pas->current_next_indicator = bs_read_u1(b);
	if (!pas->current_next_indicator)
		LOG_WARN("This PAT is not yet applicable/n");

	// read byte 5

	pas->section_number = bs_read_u8(b);
	pas->last_section_number = bs_read_u8(b);
	if (pas->section_number != 0 || pas->last_section_number != 0)
		LOG_WARN("Multi-section PAT is not supported yet/n");

	// read bytes 6,7

	pas->_num_programs = (pas->section_length - 5 - 4) / 4;
	// explanation: section_length gives us the length from the end of section_length
	// we used 5 bytes for the mandatory section fields, and will use another 4 bytes for CRC
	// the remaining bytes contain program information, which is 4 bytes per iteration
	// It's much shorter in C :-)

	if (pas->_num_programs > 1)
		LOG_WARN_ARGS("%zd programs found, but only SPTS is fully supported. Patches are welcome.", pas->_num_programs);

	pas->programs = malloc(pas->_num_programs * sizeof(program_info_t));
	for (uint32_t i = 0; i < pas->_num_programs; i++) {
		pas->programs[i].program_number = bs_read_u16(b);
		bs_skip_u(b, 3);
		pas->programs[i].program_map_PID = bs_read_u(b, 13);
	}

	pas->CRC_32 = bs_read_u32(b);

	// check CRC
	crc_t pas_crc = crc_init();
	pas_crc = crc_update(pas_crc, buf, bs_pos(b) - 4);
	pas_crc = crc_finalize(pas_crc);
	if (pas_crc != pas->CRC_32) {
		LOG_ERROR_ARGS("PAT CRC_32 specified as 0x%08X, but calculated as 0x%08X", pas->CRC_32, pas_crc);
		SAFE_REPORT_TS_ERR(-33);
		return 0;
	} else {
		LOG_DEBUG("PAT CRC_32 checked successfully");
	}

	bs_free(b);
	return 1;
}
int pes_read_header(pes_header_t *ph, bs_t *b) {
	int PES_packet_start = bs_pos(b);

	// we *really* care about bytes 0..19, as we can cheat and manipulate PTS/DTS this way
	if (bs_bytes_left(b) < 20)
		return 0;

	// bytes 0..2
	uint32_t pes_packet_start_code = bs_read_u24(b);
	if (pes_packet_start_code != PES_PACKET_START_CODE_PREFIX) {
		int actually_read = bs_pos(b) - PES_packet_start;
		b->p -= actually_read; // undo the read
		LOG_WARN_ARGS("PES packet starts with 0x%06X instead of expected start code 0x%06X, skipping it",
			pes_packet_start_code, PES_PACKET_START_CODE_PREFIX);
		return 0; // bail out! something is fishy!
	}

	// bytes 3..5
	ph->stream_id = bs_read_u8(b);
	ph->PES_packet_length = bs_read_u16(b);

	if (HAS_PES_HEADER(ph->stream_id)) {
		// byte 6
		bs_skip_u(b, 2);
		ph->PES_scrambling_control = bs_read_u(b, 2);
		ph->PES_priority = bs_read_u1(b);
		ph->data_alignment_indicator = bs_read_u1(b);
		ph->copyright = bs_read_u1(b);
		ph->original_or_copy = bs_read_u1(b);

		// byte 7
		ph->PTS_DTS_flags = bs_read_u(b, 2);
		ph->ESCR_flag = bs_read_u1(b);
		ph->ES_rate_flag = bs_read_u1(b);
		ph->DSM_trick_mode_flag = bs_read_u1(b);
		ph->additional_copy_info_flag = bs_read_u1(b);
		ph->PES_CRC_flag = bs_read_u1(b);
		ph->PES_extension_flag = bs_read_u1(b);

		// byte 8
		ph->PES_header_data_length = bs_read_u8(b);

		int PES_packet_optional_start = bs_pos(b);

		// byte 9..14
		if (ph->PTS_DTS_flags & PES_PTS_FLAG) {
			bs_skip_u(b, 4);
			ph->PTS = bs_read_90khz_timestamp(b);
		}
		// byte 15..19
		if (ph->PTS_DTS_flags & PES_DTS_FLAG) {
			bs_skip_u(b, 4);
			ph->DTS = bs_read_90khz_timestamp(b);
		}

		if (ph->ESCR_flag) {
			bs_skip_u(b, 2);
			ph->ESCR_base = bs_read_90khz_timestamp(b);
			ph->ESCR_extension = bs_read_u(b, 9);
			bs_skip_u1(b);
		}
		if (ph->ES_rate_flag) {
			bs_skip_u1(b);
			ph->ES_rate = bs_read_u(b, 22);
			bs_skip_u1(b);
		}
		if (ph->DSM_trick_mode_flag) {
			ph->trick_mode_control = bs_read_u(b, 3);
			switch (ph->trick_mode_control) {
			case PES_DSM_TRICK_MODE_CTL_FAST_FORWARD:
			case PES_DSM_TRICK_MODE_CTL_FAST_REVERSE:
				ph->field_id = bs_read_u(b, 2);
				ph->intra_slice_refresh = bs_read_u1(b);
				ph->frequency_truncation = bs_read_u(b, 2);
				break;

			case PES_DSM_TRICK_MODE_CTL_SLOW_MOTION:
			case PES_DSM_TRICK_MODE_CTL_SLOW_REVERSE:
				ph->rep_cntrl = bs_read_u(b, 5);
				break;

			case PES_DSM_TRICK_MODE_CTL_FREEZE_FRAME:
				ph->field_id = bs_read_u(b, 2);
				bs_skip_u(b, 3);
				break;

			default:
				bs_skip_u(b, 5);
				break;
			}
		}
		if (ph->additional_copy_info_flag) {
			bs_skip_u1(b);
			ph->additional_copy_info = bs_read_u(b, 7);
		}
		if (ph->PES_CRC_flag) {
			ph->previous_PES_packet_CRC = bs_read_u16(b);
		}
		if (ph->PES_extension_flag) {
			ph->PES_private_data_flag = bs_read_u1(b);
			ph->pack_header_field_flag = bs_read_u1(b);
			ph->program_packet_sequence_counter_flag = bs_read_u1(b);
			ph->PSTD_buffer_flag = bs_read_u1(b);
			bs_skip_u(b, 3);
			ph->PES_extension_flag_2 = bs_read_u1(b);

			if (ph->PES_private_data_flag)
				bs_read_bytes(b, ph->PES_private_data, 16);

			if (ph->pack_header_field_flag) {
				// whoever discovers the need for pack_header() is welcome to implement it.
				// I haven't.
				ph->pack_field_length = bs_read_u8(b);
				bs_skip_bytes(b, ph->pack_field_length);
			}
			if (ph->program_packet_sequence_counter_flag) {
				bs_skip_u1(b);
				ph->program_packet_sequence_counter = bs_read_u(b, 7);
				bs_skip_u1(b);
				ph->MPEG1_MPEG2_identifier = bs_read_u1(b);
				ph->original_stuff_length = bs_read_u(b, 6);
			}
			if (ph->PSTD_buffer_flag) {
				bs_skip_u(b, 2);
				ph->PSTD_buffer_scale = bs_read_u1(b);
				ph->PSTD_buffer_size = bs_read_u(b, 13);
			}
			if (ph->PES_extension_flag_2) {
				int PES_extension_field_start = bs_pos(b);
				bs_skip_u1(b);
				ph->PES_extension_field_length = bs_read_u(b, 7);
				ph->stream_id_extension_flag = bs_read_u1(b);
				if (!ph->stream_id_extension_flag) {
					ph->stream_id_extension = bs_read_u(b, 7);
				} else {
					bs_skip_u(b, 6);
					ph->tref_extension_flag = bs_read_u1(b);
					if (ph->tref_extension_flag) {
						bs_skip_u(b, 4);
						ph->TREF = bs_read_90khz_timestamp(b);
					}
				}
				int PES_extension_bytes_left = bs_pos(b) - PES_extension_field_start;
				if (PES_extension_bytes_left > 0)
					bs_skip_bytes(b, PES_extension_bytes_left);
			}
		}

		int PES_optional_bytes_read = bs_pos(b) - PES_packet_optional_start;
		int stuffing_bytes_len = ph->PES_header_data_length - PES_optional_bytes_read; // if any
		if (stuffing_bytes_len > 0)
			bs_skip_bytes(b, stuffing_bytes_len);
	}
	return (bs_pos(b) - PES_packet_start);
}
Example #28
0
File: mpls.c Project: CSRedRat/vlc
/* MPLS */
void bd_mpls_stream_Parse( bd_mpls_stream_t *p_stream, bs_t *s, int i_class )
{
    /* Stream entry parsing */
    const int i_entry_length = bs_read( s, 8 );
    const int i_entry_start = bs_pos( s ) / 8;

    p_stream->i_type = bs_read( s, 8 );
    p_stream->i_class = i_class;
    if( p_stream->i_type == BD_MPLS_STREAM_TYPE_PLAY_ITEM )
    {
        p_stream->play_item.i_pid = bs_read( s, 16 );
    }
    else if( p_stream->i_type == BD_MPLS_STREAM_TYPE_SUB_PATH )
    {
        p_stream->sub_path.i_sub_path_id = bs_read( s, 8 );
        p_stream->sub_path.i_sub_clip_id = bs_read( s, 8 );
        p_stream->sub_path.i_pid = bs_read( s, 16 );
    }
    else if( p_stream->i_type == BD_MPLS_STREAM_TYPE_IN_MUX_SUB_PATH )
    {
        p_stream->in_mux_sub_path.i_sub_path_id = bs_read( s, 8 );
        p_stream->in_mux_sub_path.i_pid = bs_read( s, 16 );
    }
    bs_skip( s, 8 * ( i_entry_start + i_entry_length ) - bs_pos( s ) );

    /* Stream attributes parsing */
    const int i_attributes_length = bs_read( s, 8 );
    const int i_attributes_start = bs_pos( s ) / 8;

    p_stream->i_stream_type = bs_read( s, 8 );
    strcpy( p_stream->psz_language, "" );
    p_stream->i_charset = -1;

    if( p_stream->i_stream_type == 0x02 || /* MPEG-I/II */
        p_stream->i_stream_type == 0x1b || /* AVC */
        p_stream->i_stream_type == 0xea )  /* VC-1 */
    {
        /* Video */
    }
    else if( ( p_stream->i_stream_type >= 0x80 && p_stream->i_stream_type <= 0x8f ) ||
             ( p_stream->i_stream_type >= 0xa0 && p_stream->i_stream_type <= 0xaf ) )
    {
        /* Audio */
        bs_skip( s, 4 );
        bs_skip( s, 4 );
        for( int i = 0; i < 3; i++ )
            p_stream->psz_language[i] = bs_read( s, 8 );
        p_stream->psz_language[3] = '\0';
    }
    else if( p_stream->i_stream_type == 0x90 ||   /* PG stream */
             p_stream->i_stream_type == 0x91 )    /* IG stream */
    {
        for( int i = 0; i < 3; i++ )
            p_stream->psz_language[i] = bs_read( s, 8 );
        p_stream->psz_language[3] = '\0';
    }
    else if( p_stream->i_stream_type == 0x92 )    /* Text stream */
    {
        p_stream->i_charset = bs_read( s, 8 );
        for( int i = 0; i < 3; i++ )
            p_stream->psz_language[i] = bs_read( s, 8 );
        p_stream->psz_language[3] = '\0';
    }

    bs_skip( s, 8 * ( i_attributes_start + i_attributes_length ) - bs_pos( s ) );
}
int pes_header_write(pes_header_t *ph, bs_t *b) {

	// TODO: add support for PES-level stuffing

	int start_pos = bs_pos(b);
	bs_write_u24(b, PES_PACKET_START_CODE_PREFIX);
	bs_write_u8(b, ph->stream_id);
	bs_write_u16(b, ph->PES_packet_length);

	if (HAS_PES_HEADER(ph->stream_id)) {

		bs_write_u(b, 2, 0x02);
		bs_write_u(b, 2, ph->PES_scrambling_control);
		bs_write_u1(b, ph->PES_priority);
		bs_write_u1(b, ph->data_alignment_indicator);
		bs_write_u1(b, ph->copyright);
		bs_write_u1(b, ph->original_or_copy);

		bs_write_u(b, 2, ph->PTS_DTS_flags);
		bs_write_u1(b, ph->ESCR_flag);
		bs_write_u1(b, ph->ES_rate_flag);
		bs_write_u1(b, ph->DSM_trick_mode_flag);
		bs_write_u1(b, ph->additional_copy_info_flag);
		bs_write_u1(b, ph->PES_CRC_flag);
		bs_write_u1(b, ph->PES_extension_flag);

		bs_write_u8(b, ph->PES_header_data_length);

		if (ph->PTS_DTS_flags & PES_PTS_FLAG) {
			bs_write_u(b, 4, 0x02);
			bs_write_90khz_timestamp(b, ph->PTS);
		}

		if (ph->PTS_DTS_flags & PES_DTS_FLAG) {
			bs_write_u(b, 4, 0x01);
			bs_write_90khz_timestamp(b, ph->DTS);
		}

		if (ph->ESCR_flag) {
			bs_write_reserved(b, 2);
			bs_write_90khz_timestamp(b, ph->ESCR_base);
			bs_write_u(b, 9, ph->ESCR_extension);
			bs_write_marker_bit(b);
		}
		if (ph->ES_rate_flag) {
			bs_write_marker_bit(b);
			bs_write_u(b, 22, ph->ES_rate);
			bs_write_marker_bit(b);
		}
		if (ph->DSM_trick_mode_flag) {
			bs_write_u(b, 3, ph->trick_mode_control);

			switch (ph->trick_mode_control) {
			case PES_DSM_TRICK_MODE_CTL_FAST_FORWARD:
			case PES_DSM_TRICK_MODE_CTL_FAST_REVERSE:
				bs_write_u(b, 2, ph->field_id);
				bs_write_u1(b, ph->intra_slice_refresh);
				bs_write_u(b, 2, ph->frequency_truncation);

				break;

			case PES_DSM_TRICK_MODE_CTL_SLOW_MOTION:
			case PES_DSM_TRICK_MODE_CTL_SLOW_REVERSE:
				bs_write_u(b, 5, ph->rep_cntrl);
				break;

			case PES_DSM_TRICK_MODE_CTL_FREEZE_FRAME:
				bs_write_u(b, 2, ph->field_id);
				bs_write_reserved(b, 3);
				break;

			default:
				bs_write_reserved(b, 5);
				break;
			}
		}

		if (ph->additional_copy_info_flag) {
			bs_write_marker_bit(b);
			bs_write_u(b, 7, ph->additional_copy_info);
		}
		if (ph->PES_CRC_flag) {
			bs_write_u16(b, ph->previous_PES_packet_CRC);
		}
		if (ph->PES_extension_flag) {
			bs_write_u1(b, ph->PES_private_data_flag);
			bs_write_u1(b, 0); // pack_header not supported
			bs_write_u1(b, ph->program_packet_sequence_counter_flag);
			bs_write_u1(b, ph->PSTD_buffer_flag);
			bs_write_reserved(b, 3);
			bs_write_u1(b, ph->PES_extension_flag_2);

			if (ph->PES_private_data_flag) {
				bs_write_bytes(b, ph->PES_private_data, 16);
			}

			if (ph->program_packet_sequence_counter_flag) {
				bs_write_marker_bit(b);
				bs_write_u(b, 7, ph->program_packet_sequence_counter);
				bs_write_marker_bit(b);
				bs_write_u1(b, ph->MPEG1_MPEG2_identifier);
				bs_write_u(b, 6, ph->original_stuff_length);
			}

			if (ph->PSTD_buffer_flag) {
				bs_write_u(b, 2, 0x01);
				bs_write_u1(b, ph->PSTD_buffer_scale);
				bs_write_u(b, 13, ph->PSTD_buffer_size);
			}

			if (ph->PES_extension_flag_2) {
				bs_write_marker_bit(b);
				bs_write_u(b, 7, ph->PES_extension_field_length);
				bs_write_u1(b, ph->stream_id_extension_flag);

				if (!ph->stream_id_extension_flag) {
					bs_write_u(b, 7, ph->stream_id_extension);
				} else {
					bs_write_reserved(b, 6);
					bs_write_u1(b, ph->tref_extension_flag);

					if (ph->tref_extension_flag) {
						bs_write_reserved(b, 4);
						bs_write_90khz_timestamp(b, ph->TREF);
					}
				}
			}
		}
	}
	return (bs_pos(b) - start_pos);
}