Пример #1
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;
}
Пример #2
0
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;
}
Пример #3
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);
}
Пример #4
0
static BDID_DATA *_bdid_parse(BD_FILE_H *fp)
{
    BITSTREAM  bs;
    BDID_DATA *bdid = NULL;

    uint32_t   data_start, extension_data_start;
    uint8_t    tmp[16];

    if (bs_init(&bs, fp) < 0) {
        BD_DEBUG(DBG_NAV, "id.bdmv: read error\n");
        return NULL;
    }

    if (!_parse_header(&bs, &data_start, &extension_data_start)) {
        BD_DEBUG(DBG_NAV | DBG_CRIT, "id.bdmv: invalid header\n");
        return NULL;
    }

    if (bs_seek_byte(&bs, 40) < 0) {
        BD_DEBUG(DBG_NAV, "id.bdmv: read error\n");
        return NULL;
    }

    bdid = calloc(1, sizeof(BDID_DATA));
    if (!bdid) {
        BD_DEBUG(DBG_CRIT, "out of memory\n");
        return NULL;
    }

    bs_read_bytes(&bs, tmp, 4);
    str_print_hex(bdid->org_id, tmp, 4);

    bs_read_bytes(&bs, tmp, 16);
    str_print_hex(bdid->disc_id, tmp, 16);

    if (extension_data_start) {
        BD_DEBUG(DBG_NAV | DBG_CRIT, "id.bdmv: ignoring unknown extension data\n");
    }

    return bdid;
}
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);
}
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);
}