Example #1
0
gboolean
mpeg4_util_parse_VOS (GstBuffer * buf, Mpeg4VisualObjectSequence * vos)
{
  GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buf);

  guint8 visual_object_sequence_start_code;

  /* start code prefix */
  SKIP (&reader, 24);

  READ_UINT8 (&reader, visual_object_sequence_start_code, 8);
  if (visual_object_sequence_start_code != MPEG4_PACKET_VOS)
    goto wrong_start_code;

  READ_UINT8 (&reader, vos->profile_and_level_indication, 8);

  return TRUE;

wrong_start_code:
  GST_WARNING ("got buffer with wrong start code");
  return FALSE;

error:
  GST_WARNING ("error parsing \"Visual Object\"");
  return FALSE;
}
static gboolean
parse_quant (GstBitReader * br, guint8 quant_mat[64],
    const guint8 default_quant_mat[64], guint8 * load_quant_mat)
{
  READ_UINT8 (br, *load_quant_mat, 1);
  if (*load_quant_mat) {
    guint i;
    guint8 val;

    val = 1;
    for (i = 0; i < 64; i++) {

      if (val != 0)
        READ_UINT8 (br, val, 8);

      if (val == 0) {
        if (i == 0)
          goto invalid_quant_mat;
        quant_mat[mpeg4_zigzag_8x8[i]] = quant_mat[mpeg4_zigzag_8x8[i - 1]];
      } else
        quant_mat[mpeg4_zigzag_8x8[i]] = val;
    }
  } else
    memcpy (quant_mat, default_quant_mat, 64);

  return TRUE;

failed:
  GST_WARNING ("failed parsing quant matrix");
  return FALSE;

invalid_quant_mat:
  GST_WARNING ("the first value should be non zero");
  goto failed;
}
Example #3
0
gboolean
mpeg_util_parse_picture_hdr (MPEGPictureHdr * hdr, GstBuffer * buffer)
{
  GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buffer);

  /* skip sync word */
  if (!gst_bit_reader_skip (&reader, 8 * 4))
    return FALSE;

  /* temperal sequence number */
  if (!gst_bit_reader_get_bits_uint16 (&reader, &hdr->tsn, 10))
    return FALSE;

  /* frame type */
  if (!gst_bit_reader_get_bits_uint8 (&reader, &hdr->pic_type, 3))
    return FALSE;

  if (hdr->pic_type == 0 || hdr->pic_type > 4)
    return FALSE;               /* Corrupted picture packet */

  /* VBV delay */
  if (!gst_bit_reader_get_bits_uint16 (&reader, &hdr->vbv_delay, 16))
    return FALSE;

  if (hdr->pic_type == P_FRAME || hdr->pic_type == B_FRAME) {

    READ_UINT8 (&reader, hdr->full_pel_forward_vector, 1);

    READ_UINT8 (&reader, hdr->f_code[0][0], 3);
    hdr->f_code[0][1] = hdr->f_code[0][0];
  } else {
    hdr->full_pel_forward_vector = 0;
    hdr->f_code[0][0] = hdr->f_code[0][1] = 0;
  }

  if (hdr->pic_type == B_FRAME) {
    READ_UINT8 (&reader, hdr->full_pel_backward_vector, 1);

    READ_UINT8 (&reader, hdr->f_code[1][0], 3);
    hdr->f_code[1][1] = hdr->f_code[1][0];
  } else {
    hdr->full_pel_backward_vector = 0;
    hdr->f_code[1][0] = hdr->f_code[1][1] = 0;
  }

  return TRUE;

error:
  GST_WARNING ("error parsing \"Picture Header\"");
  return FALSE;
}
/**
 * gst_mpeg4_parse_visual_object:
 * @vo: The #GstMpeg4VisualObject structure to fill
 * @signal_type: The #GstMpeg4VideoSignalType to fill or %NULL
 * @data: The data to parse, should contain the vo_start_code
 * but not the start code prefix
 * @size: The size of the @data to parse
 *
 * Parses @data containing the visual object packet, and fills
 * the @vo structure.
 *
 * Returns: a #GstMpeg4ParseResult
 */
GstMpeg4ParseResult
gst_mpeg4_parse_visual_object (GstMpeg4VisualObject * vo,
    GstMpeg4VideoSignalType * signal_type, const guint8 * data, gsize size)
{
  guint8 vo_start_code, type;
  GstBitReader br = GST_BIT_READER_INIT (data, size);

  g_return_val_if_fail (vo != NULL, GST_MPEG4_PARSER_ERROR);

  GST_DEBUG ("Parsing visual object");

  READ_UINT8 (&br, vo_start_code, 8);
  if (vo_start_code != GST_MPEG4_VISUAL_OBJ)
    goto wrong_start_code;

  /* set default values */
  vo->verid = 0x1;
  vo->priority = 1;

  READ_UINT8 (&br, vo->is_identifier, 1);
  if (vo->is_identifier) {
    READ_UINT8 (&br, vo->verid, 4);
    READ_UINT8 (&br, vo->priority, 3);
  }

  READ_UINT8 (&br, type, 4);
  vo->type = type;

  if ((type == GST_MPEG4_VIDEO_ID ||
          type == GST_MPEG4_STILL_TEXTURE_ID) && signal_type) {

    if (!parse_signal_type (&br, signal_type))
      goto failed;

  } else if (signal_type) {
    signal_type->type = 0;
  }

  return GST_MPEG4_PARSER_OK;

wrong_start_code:
  GST_WARNING ("got buffer with wrong start code");
  return GST_MPEG4_PARSER_ERROR;

failed:
  GST_WARNING ("failed parsing \"Visual Object\"");
  return GST_MPEG4_PARSER_ERROR;
}
/**
 * gst_mpeg4_parse_group_of_vop:
 * @gov: The #GstMpeg4GroupOfVOP structure to fill
 * @data: The data to parse
 * @size: The size of the @data to parse
 *
 * Parses @data containing the group of video object plane packet, and fills
 * the @gov structure.
 *
 * Returns: a #GstMpeg4ParseResult
 */
GstMpeg4ParseResult
gst_mpeg4_parse_group_of_vop (GstMpeg4GroupOfVOP *
    gov, const guint8 * data, gsize size)
{
  guint8 gov_start_code;
  GstBitReader br = GST_BIT_READER_INIT (data, size);

  g_return_val_if_fail (gov != NULL, GST_MPEG4_PARSER_ERROR);

  READ_UINT8 (&br, gov_start_code, 8);
  if (gov_start_code != GST_MPEG4_GROUP_OF_VOP)
    goto wrong_start_code;

  CHECK_REMAINING (&br, 65);

  gov->hours = gst_bit_reader_get_bits_uint8_unchecked (&br, 5);
  gov->minutes = gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
  /* marker bit */
  MARKER_UNCHECKED (&br);
  gov->seconds = gst_bit_reader_get_bits_uint8_unchecked (&br, 6);

  gov->closed = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
  gov->broken_link = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);

  return GST_MPEG4_PARSER_OK;

failed:
  GST_WARNING ("failed parsing \"Group of Video Object Plane\"");
  return GST_MPEG4_PARSER_ERROR;

wrong_start_code:
  GST_WARNING ("got buffer with wrong start code");
  goto failed;
}
Example #6
0
gboolean
mpeg_util_parse_sequence_hdr (MPEGSeqHdr * hdr, GstBuffer * buffer)
{
  GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buffer);
  guint8 dar_idx, par_idx;
  guint8 load_intra_flag, load_non_intra_flag;

  /* skip sync word */
  if (!gst_bit_reader_skip (&reader, 8 * 4))
    return FALSE;

  /* resolution */
  READ_UINT16 (&reader, hdr->width, 12);
  READ_UINT16 (&reader, hdr->height, 12);

  /* aspect ratio */
  READ_UINT8 (&reader, dar_idx, 4);
  set_par_from_dar (hdr, dar_idx);

  /* framerate */
  READ_UINT8 (&reader, par_idx, 4);
  set_fps_from_code (hdr, par_idx);

  /* bitrate */
  READ_UINT32 (&reader, hdr->bitrate, 18);

  if (!gst_bit_reader_skip (&reader, 1))
    return FALSE;

  /* VBV buffer size */
  READ_UINT16 (&reader, hdr->vbv_buffer, 10);

  /* constrained parameters flag */
  READ_UINT8 (&reader, hdr->constrained_parameters_flag, 1);

  /* intra quantizer matrix */
  READ_UINT8 (&reader, load_intra_flag, 1);
  if (load_intra_flag) {
    gint i;
    for (i = 0; i < 64; i++)
      READ_UINT8 (&reader, hdr->intra_quantizer_matrix[mpeg_zigzag_8x8[i]], 8);
  } else
    memcpy (hdr->intra_quantizer_matrix, default_intra_quantizer_matrix, 64);

  /* non intra quantizer matrix */
  READ_UINT8 (&reader, load_non_intra_flag, 1);
  if (load_non_intra_flag) {
    gint i;
    for (i = 0; i < 64; i++)
      READ_UINT8 (&reader, hdr->non_intra_quantizer_matrix[mpeg_zigzag_8x8[i]],
          8);
  } else
    memset (hdr->non_intra_quantizer_matrix, 16, 64);

  return TRUE;

error:
  GST_WARNING ("error parsing \"Sequence Header\"");
  return FALSE;
}
Example #7
0
gboolean
mpeg_util_parse_gop (MPEGGop * gop, GstBuffer * buffer)
{
  GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buffer);

  /* skip sync word */
  if (!gst_bit_reader_skip (&reader, 8 * 4))
    return FALSE;

  READ_UINT8 (&reader, gop->drop_frame_flag, 1);

  READ_UINT8 (&reader, gop->hour, 5);

  READ_UINT8 (&reader, gop->minute, 6);

  /* skip unused bit */
  if (!gst_bit_reader_skip (&reader, 1))
    return FALSE;

  READ_UINT8 (&reader, gop->second, 6);

  READ_UINT8 (&reader, gop->frame, 6);

  READ_UINT8 (&reader, gop->closed_gop, 1);

  READ_UINT8 (&reader, gop->broken_gop, 1);

  return TRUE;

error:
  GST_WARNING ("error parsing \"GOP\"");
  return FALSE;
}
static gboolean
parse_signal_type (GstBitReader * br, GstMpeg4VideoSignalType * signal_type)
{
  READ_UINT8 (br, signal_type->type, 1);

  if (signal_type->type) {

    READ_UINT8 (br, signal_type->format, 3);
    READ_UINT8 (br, signal_type->range, 1);
    READ_UINT8 (br, signal_type->color_description, 1);

    if (signal_type->color_description) {
      READ_UINT8 (br, signal_type->color_primaries, 8);
      READ_UINT8 (br, signal_type->transfer_characteristics, 8);
      READ_UINT8 (br, signal_type->matrix_coefficients, 8);
    }
  }

  return TRUE;

failed:
  GST_WARNING ("failed parsing \"Video Signal Type\"");

  return FALSE;
}
Example #9
0
gboolean
mpeg_util_parse_quant_matrix (MPEGQuantMatrix * qm, GstBuffer * buffer)
{
  GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buffer);
  guint8 load_intra_flag, load_non_intra_flag;

  /* skip sync word */
  if (!gst_bit_reader_skip (&reader, 8 * 4))
    return FALSE;

  /* skip extension code */
  if (!gst_bit_reader_skip (&reader, 4))
    return FALSE;

  /* intra quantizer matrix */
  READ_UINT8 (&reader, load_intra_flag, 1);
  if (load_intra_flag) {
    gint i;
    for (i = 0; i < 64; i++) {
      READ_UINT8 (&reader, qm->intra_quantizer_matrix[mpeg_zigzag_8x8[i]], 8);
    }
  } else
    memcpy (qm->intra_quantizer_matrix, default_intra_quantizer_matrix, 64);

  /* non intra quantizer matrix */
  READ_UINT8 (&reader, load_non_intra_flag, 1);
  if (load_non_intra_flag) {
    gint i;
    for (i = 0; i < 64; i++) {
      READ_UINT8 (&reader, qm->non_intra_quantizer_matrix[mpeg_zigzag_8x8[i]],
          8);
    }
  } else
    memset (qm->non_intra_quantizer_matrix, 16, 64);

  return TRUE;

error:
  GST_WARNING ("error parsing \"Quant Matrix Extension\"");
  return FALSE;

}
Example #10
0
gboolean
mpeg4_util_parse_GOV (GstBuffer * buf, Mpeg4GroupofVideoObjectPlane * gov)
{
  GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buf);

  guint8 gov_start_code;

  /* start code prefix */
  SKIP (&reader, 24);

  READ_UINT8 (&reader, gov_start_code, 8);
  if (gov_start_code != MPEG4_PACKET_GOV)
    goto wrong_start_code;

  READ_UINT8 (&reader, gov->hours, 5);
  READ_UINT8 (&reader, gov->minutes, 6);
  /* marker bit */
  SKIP (&reader, 1);
  READ_UINT8 (&reader, gov->seconds, 6);

  READ_UINT8 (&reader, gov->closed, 1);
  READ_UINT8 (&reader, gov->broken_link, 1);

  return TRUE;

error:
  GST_WARNING ("error parsing \"Group of Video Object Plane\"");
  return FALSE;

wrong_start_code:
  GST_WARNING ("got buffer with wrong start code");
  goto error;
}
Example #11
0
static gboolean
mpeg4_util_parse_quant (GstBitReader * reader, guint8 quant_mat[64],
    const guint8 default_quant_mat[64])
{
  guint8 load_quant_mat;

  READ_UINT8 (reader, load_quant_mat, 1);
  if (load_quant_mat) {
    guint i;
    guint8 val;

    val = 1;
    for (i = 0; i < 64; i++) {

      if (val != 0)
        READ_UINT8 (reader, val, 8);

      if (val == 0) {
        if (i == 0)
          goto invalid_quant_mat;
        quant_mat[mpeg4_zigzag_8x8[i]] = quant_mat[mpeg4_zigzag_8x8[i - 1]];
      } else
        quant_mat[mpeg4_zigzag_8x8[i]] = val;
    }
  } else
    memcpy (quant_mat, default_quant_mat, 64);

  return TRUE;

error:
  GST_WARNING ("error parsing quant matrix");
  return FALSE;

invalid_quant_mat:
  GST_WARNING ("the first value should be non zero");
  goto error;
}
Example #12
0
gboolean
mpeg4_util_parse_VO (GstBuffer * buf, Mpeg4VisualObject * vo)
{
  GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buf);

  guint8 visual_object_start_code;
  guint8 is_visual_object_identifier;

  /* set defualt values */
  vo->verid = 0x1;
  vo->priority = 1;

  /* start code prefix */
  SKIP (&reader, 24);

  READ_UINT8 (&reader, visual_object_start_code, 8);
  if (visual_object_start_code != MPEG4_PACKET_VO)
    goto wrong_start_code;

  READ_UINT8 (&reader, is_visual_object_identifier, 1);
  if (is_visual_object_identifier) {
    READ_UINT8 (&reader, vo->verid, 4);
    READ_UINT8 (&reader, vo->priority, 3);
  }

  READ_UINT8 (&reader, vo->type, 4);

  return TRUE;

wrong_start_code:
  GST_WARNING ("got buffer with wrong start code");
  return FALSE;

error:
  GST_WARNING ("error parsing \"Visual Object\"");
  return FALSE;
}
Example #13
0
gboolean
mpeg_util_parse_sequence_extension (MPEGSeqExtHdr * hdr, GstBuffer * buffer)
{
  GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buffer);;

  /* skip sync word */
  if (!gst_bit_reader_skip (&reader, 8 * 4))
    return FALSE;

  /* skip extension code */
  if (!gst_bit_reader_skip (&reader, 4))
    return FALSE;

  /* skip profile and level escape bit */
  if (!gst_bit_reader_skip (&reader, 1))
    return FALSE;

  READ_UINT8 (&reader, hdr->profile, 3);
  READ_UINT8 (&reader, hdr->level, 4);

  /* progressive */
  READ_UINT8 (&reader, hdr->progressive, 1);

  /* chroma format */
  READ_UINT8 (&reader, hdr->chroma_format, 2);

  /* resolution extension */
  READ_UINT8 (&reader, hdr->horiz_size_ext, 2);
  READ_UINT8 (&reader, hdr->vert_size_ext, 2);

  READ_UINT16 (&reader, hdr->bitrate_ext, 12);

  /* skip to framerate extension */
  if (!gst_bit_reader_skip (&reader, 9))
    return FALSE;

  /* framerate extension */
  READ_UINT8 (&reader, hdr->fps_n_ext, 2);
  READ_UINT8 (&reader, hdr->fps_d_ext, 2);

  return TRUE;

error:
  GST_WARNING ("error parsing \"Sequence Extension\"");
  return FALSE;
}
Example #14
0
static gboolean
gst_vdp_h264_dec_set_sink_caps (GstBaseVideoDecoder * base_video_decoder,
    GstCaps * caps)
{
  GstVdpH264Dec *h264_dec;
  GstStructure *structure;
  const GValue *value;

  h264_dec = GST_VDP_H264_DEC (base_video_decoder);

  structure = gst_caps_get_structure (caps, 0);
  /* packetized video has a codec_data */
  if ((value = gst_structure_get_value (structure, "codec_data"))) {
    GstBuffer *buf;
    GstBitReader reader;
    guint8 version;
    guint8 n_sps, n_pps;
    gint i;

    GST_DEBUG_OBJECT (h264_dec, "have packetized h264");
    h264_dec->packetized = TRUE;

    buf = gst_value_get_buffer (value);
    GST_MEMDUMP ("avcC:", GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));

    /* parse the avcC data */
    if (GST_BUFFER_SIZE (buf) < 7) {
      GST_ERROR_OBJECT (h264_dec, "avcC size %u < 7", GST_BUFFER_SIZE (buf));
      return FALSE;
    }

    gst_bit_reader_init_from_buffer (&reader, buf);

    READ_UINT8 (&reader, version, 8);
    if (version != 1)
      return FALSE;

    SKIP (&reader, 30);

    READ_UINT8 (&reader, h264_dec->nal_length_size, 2);
    h264_dec->nal_length_size += 1;
    GST_DEBUG_OBJECT (h264_dec, "nal length %u", h264_dec->nal_length_size);

    SKIP (&reader, 3);

    READ_UINT8 (&reader, n_sps, 5);
    for (i = 0; i < n_sps; i++) {
      guint16 sps_length;
      guint8 *data;

      READ_UINT16 (&reader, sps_length, 16);
      sps_length -= 1;
      SKIP (&reader, 8);

      data = GST_BUFFER_DATA (buf) + gst_bit_reader_get_pos (&reader) / 8;
      if (!gst_h264_parser_parse_sequence (h264_dec->parser, data, sps_length))
        return FALSE;

      SKIP (&reader, sps_length * 8);
    }

    READ_UINT8 (&reader, n_pps, 8);
    for (i = 0; i < n_pps; i++) {
      guint16 pps_length;
      guint8 *data;

      READ_UINT16 (&reader, pps_length, 16);
      pps_length -= 1;
      SKIP (&reader, 8);

      data = GST_BUFFER_DATA (buf) + gst_bit_reader_get_pos (&reader) / 8;
      if (!gst_h264_parser_parse_picture (h264_dec->parser, data, pps_length))
        return FALSE;

      SKIP (&reader, pps_length * 8);
    }
  }

  return TRUE;
}
Example #15
0
gboolean
mpeg4_util_parse_VOP (GstBuffer * buf, Mpeg4VideoObjectLayer * vol,
    Mpeg4VideoObjectPlane * vop)
{
  GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buf);

  guint8 vop_start_code;
  guint8 modulo_time_base;

  /* set default values */
  vop->modulo_time_base = 0;
  vop->rounding_type = 0;
  vop->top_field_first = 1;
  vop->alternate_vertical_scan_flag = 0;
  vop->fcode_forward = 1;
  vop->fcode_backward = 1;

  /* start code prefix */
  SKIP (&reader, 24);

  READ_UINT8 (&reader, vop_start_code, 8);
  if (vop_start_code != MPEG4_PACKET_VOP)
    goto wrong_start_code;

  READ_UINT8 (&reader, vop->coding_type, 2);

  READ_UINT8 (&reader, modulo_time_base, 1);
  while (modulo_time_base) {
    vop->modulo_time_base++;

    READ_UINT8 (&reader, modulo_time_base, 1);
  }

  /* marker bit */
  SKIP (&reader, 1);
  READ_UINT16 (&reader, vop->time_increment, vol->vop_time_increment_bits);
  /* marker bit */
  SKIP (&reader, 1);

  READ_UINT8 (&reader, vop->coded, 1);
  if (!vop->coded)
    return TRUE;

  if (vop->coding_type == P_VOP)
    READ_UINT8 (&reader, vop->rounding_type, 1);

  READ_UINT8 (&reader, vop->intra_dc_vlc_thr, 3);

  if (vol->interlaced) {
    READ_UINT8 (&reader, vop->top_field_first, 1);
    READ_UINT8 (&reader, vop->alternate_vertical_scan_flag, 1);
  }

  READ_UINT16 (&reader, vop->quant, vol->quant_precision);

  if (vop->coding_type != I_VOP) {
    READ_UINT8 (&reader, vop->fcode_forward, 3);
    CHECK_ALLOWED (vop->fcode_forward, 1, 7);
  }

  if (vop->coding_type == B_VOP) {
    READ_UINT8 (&reader, vop->fcode_backward, 3);
    CHECK_ALLOWED (vop->fcode_backward, 1, 7);
  }

  return TRUE;

error:
  GST_WARNING ("error parsing \"Video Object Plane\"");
  return FALSE;

wrong_start_code:
  GST_WARNING ("got buffer with wrong start code");
  goto error;
}
Example #16
0
static GstFlowReturn
gst_vdp_mpeg4_dec_parse_data (GstBaseVideoDecoder * base_video_decoder,
    GstBuffer * buf, gboolean at_eos, GstVideoFrame * frame)
{
  GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buf);
  guint8 start_code;
  GstMpeg4Frame *mpeg4_frame;

  GstFlowReturn ret = GST_FLOW_OK;

  /* start code prefix */
  SKIP (&reader, 24);

  /* start_code */
  READ_UINT8 (&reader, start_code, 8);

  mpeg4_frame = GST_MPEG4_FRAME_CAST (frame);

  /* collect packages */
  if (start_code == MPEG4_PACKET_VOS) {
    if (mpeg4_frame->vop_buf)
      ret = gst_base_video_decoder_have_frame (base_video_decoder, FALSE,
          (GstVideoFrame **) & mpeg4_frame);

    gst_buffer_replace (&mpeg4_frame->vos_buf, buf);
  }

  else if (start_code == MPEG4_PACKET_EVOS) {
    if (mpeg4_frame->vop_buf)
      ret = gst_base_video_decoder_have_frame (base_video_decoder, FALSE,
          (GstVideoFrame **) & mpeg4_frame);
  }

  else if (start_code == MPEG4_PACKET_VO)
    gst_buffer_replace (&mpeg4_frame->vo_buf, buf);

  else if (start_code >= MPEG4_PACKET_VOL_MIN &&
      start_code <= MPEG4_PACKET_VOL_MAX)
    gst_buffer_replace (&mpeg4_frame->vol_buf, buf);

  else if (start_code == MPEG4_PACKET_GOV) {
    if (mpeg4_frame->vop_buf)
      ret = gst_base_video_decoder_have_frame (base_video_decoder, FALSE,
          (GstVideoFrame **) & mpeg4_frame);

    gst_buffer_replace (&mpeg4_frame->gov_buf, buf);
  }

  else if (start_code == MPEG4_PACKET_VOP) {
    if (mpeg4_frame->vop_buf)
      ret = gst_base_video_decoder_have_frame (base_video_decoder, FALSE,
          (GstVideoFrame **) & mpeg4_frame);

    mpeg4_frame->vop_buf = buf;
  }

  else
    gst_buffer_unref (buf);


  if (at_eos && mpeg4_frame->vop_buf)
    ret = gst_base_video_decoder_have_frame (base_video_decoder, TRUE,
        (GstVideoFrame **) & mpeg4_frame);

  return ret;

error:
  gst_buffer_unref (buf);
  GST_WARNING ("error parsing packet");
  return GST_FLOW_OK;
}
/**
 * gst_mpeg4_parse_video_object_plane:
 * @vop: The #GstMpeg4VideoObjectPlane currently being parsed
 * @sprite_trajectory: A #GstMpeg4SpriteTrajectory to fill or %NULL
 * @vol: The #GstMpeg4VideoObjectLayer structure to fill
 * @data: The data to parse
 * @size: The size of the @data to parse
 *
 * Parses @data containing the video object plane packet, and fills the @vol
 * structure.
 *
 * Returns: a #GstMpeg4ParseResult
 */
GstMpeg4ParseResult
gst_mpeg4_parse_video_object_plane (GstMpeg4VideoObjectPlane * vop,
    GstMpeg4SpriteTrajectory * sprite_trajectory,
    GstMpeg4VideoObjectLayer * vol, const guint8 * data, gsize size)
{
  guint8 vop_start_code, coding_type, modulo_time_base;
  GstBitReader br = GST_BIT_READER_INIT (data, size);

  g_return_val_if_fail (vop != NULL, GST_MPEG4_PARSER_ERROR);

  if (vol->shape == GST_MPEG4_BINARY_ONLY) {
    /* TODO: implement binary only shapes */
    GST_WARNING ("Binary only shapes not supported");
    goto failed;
  }

  READ_UINT8 (&br, vop_start_code, 8);
  if (vop_start_code != GST_MPEG4_VIDEO_OBJ_PLANE)
    goto wrong_start_code;


  /* set default values */
  vop->modulo_time_base = 0;
  vop->rounding_type = 0;
  vop->top_field_first = 1;
  vop->alternate_vertical_scan_flag = 0;
  vop->fcode_forward = 1;
  vop->fcode_backward = 1;

  /*  Compute macroblock informations */
  if (vol->interlaced)
    vop->mb_height = (2 * (vol->height + 31) / 32);
  else
    vop->mb_height = (vol->height + 15) / 16;

  vop->mb_width = (vol->width + 15) / 16;
  vop->mb_num = vop->mb_height * vop->mb_width;

  READ_UINT8 (&br, coding_type, 2);
  vop->coding_type = coding_type;

  READ_UINT8 (&br, modulo_time_base, 1);
  while (modulo_time_base) {
    vop->modulo_time_base++;

    READ_UINT8 (&br, modulo_time_base, 1);
  }

  CHECK_REMAINING (&br, vol->vop_time_increment_bits + 3);

  MARKER_UNCHECKED (&br);
  vop->time_increment =
      gst_bit_reader_get_bits_uint16_unchecked (&br,
      vol->vop_time_increment_bits);
  MARKER_UNCHECKED (&br);

  vop->coded = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
  if (!vop->coded)
    return GST_MPEG4_PARSER_OK;

  if (vol->newpred_enable) {
    guint16 nbbits =
        vop->time_increment + 3 < 15 ? vop->time_increment + 3 : 15;

    READ_UINT16 (&br, vop->id, nbbits);
    READ_UINT8 (&br, vop->id_for_prediction_indication, 1);
    if (vop->id_for_prediction_indication) {
      /* Would be nice if the standard actually told us... */
      READ_UINT16 (&br, vop->id, nbbits);
      CHECK_MARKER (&br);
    }
  }

  if (vol->shape != GST_MPEG4_BINARY_ONLY &&
      (vop->coding_type == GST_MPEG4_P_VOP ||
          (vop->coding_type == GST_MPEG4_S_VOP &&
              vol->sprite_enable == GST_MPEG4_SPRITE_GMG)))
    READ_UINT8 (&br, vop->rounding_type, 1);

  if ((vol->reduced_resolution_vop_enable) &&
      (vol->shape == GST_MPEG4_RECTANGULAR ||
          (vop->coding_type = GST_MPEG4_P_VOP ||
              vop->coding_type == GST_MPEG4_I_VOP)))
    READ_UINT8 (&br, vop->reduced_resolution, 1);

  if (vol->shape != GST_MPEG4_RECTANGULAR) {
    if (vol->sprite_enable == GST_MPEG4_SPRITE_STATIC &&
        vop->coding_type == GST_MPEG4_I_VOP) {
      CHECK_REMAINING (&br, 55);

      vop->width = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
      MARKER_UNCHECKED (&br);

      vop->height = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
      MARKER_UNCHECKED (&br);

      vop->horizontal_mc_spatial_ref =
          gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
      MARKER_UNCHECKED (&br);

      vop->vertical_mc_spatial_ref =
          gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
      MARKER_UNCHECKED (&br);

      /* Recompute the Macroblock informations
       * accordingly to the new values */
      if (vol->interlaced)
        vop->mb_height = (2 * (vol->height + 31) / 32);
      else
        vop->mb_height = (vol->height + 15) / 16;

      vop->mb_width = (vol->width + 15) / 16;
      vop->mb_num = vop->mb_height * vop->mb_width;
    }

    if ((vol->shape != GST_MPEG4_BINARY_ONLY) &&
        vol->scalability && vol->enhancement_type)
      READ_UINT8 (&br, vop->background_composition, 1);

    READ_UINT8 (&br, vop->change_conv_ratio_disable, 1);

    READ_UINT8 (&br, vop->constant_alpha, 1);
    if (vop->constant_alpha)
      READ_UINT8 (&br, vop->constant_alpha_value, 1);
  }

  if (vol->shape != GST_MPEG4_BINARY_ONLY) {
    if (!vol->complexity_estimation_disable) {
      GST_WARNING ("Complexity estimation not supported");
      goto failed;
    }

    READ_UINT8 (&br, vop->intra_dc_vlc_thr, 3);

    if (vol->interlaced) {
      READ_UINT8 (&br, vop->top_field_first, 1);
      READ_UINT8 (&br, vop->alternate_vertical_scan_flag, 1);
    }
  }

  if ((vol->sprite_enable == GST_MPEG4_SPRITE_STATIC ||
          vol->sprite_enable == GST_MPEG4_SPRITE_GMG) &&
      vop->coding_type == GST_MPEG4_S_VOP) {

    /* only if @sprite_trajectory is not NULL we parse it */
    if (sprite_trajectory && vol->no_of_sprite_warping_points)
      parse_sprite_trajectory (&br, sprite_trajectory,
          vol->no_of_sprite_warping_points);

    if (vol->sprite_brightness_change) {
      GST_WARNING ("sprite_brightness_change not supported");
      goto failed;
    }

    if (vol->sprite_enable == GST_MPEG4_SPRITE_STATIC) {
      GST_WARNING ("sprite enable static not supported");
      goto failed;
    }
  }

  if (vol->shape != GST_MPEG4_BINARY_ONLY) {
    READ_UINT16 (&br, vop->quant, vol->quant_precision);

    if (vol->shape == GST_MPEG4_GRAYSCALE) {
      /* TODO implement grayscale support */
      GST_WARNING ("Grayscale shapes no supported");

      /* TODO implement me */
      goto failed;
    }

    if (vop->coding_type != GST_MPEG4_I_VOP) {
      READ_UINT8 (&br, vop->fcode_forward, 3);
      CHECK_ALLOWED (vop->fcode_forward, 1, 7);
    }

    if (vop->coding_type == GST_MPEG4_B_VOP) {
      READ_UINT8 (&br, vop->fcode_backward, 3);
      CHECK_ALLOWED (vop->fcode_backward, 1, 7);
    }
  }

  if (!vol->scalability) {
    if (vol->shape != GST_MPEG4_RECTANGULAR)
      READ_UINT8 (&br, vop->shape_coding_type, 1);

  } else {
    if (vol->enhancement_type) {
      READ_UINT8 (&br, vop->load_backward_shape, 1);

      if (vop->load_backward_shape) {
        GST_WARNING ("Load backward shape not supported");
        goto failed;
      }

      READ_UINT8 (&br, vop->ref_select_code, 2);
    }
  }

  vop->size = gst_bit_reader_get_pos (&br);
  /* More things to possibly parse ... */

  return GST_MPEG4_PARSER_OK;

failed:
  GST_WARNING ("failed parsing \"Video Object Plane\"");
  return GST_MPEG4_PARSER_ERROR;

wrong_start_code:
  GST_WARNING ("got buffer with wrong start code");
  goto failed;
}
Example #18
0
gboolean
mpeg_util_parse_picture_coding_extension (MPEGPictureExt * ext,
    GstBuffer * buffer)
{
  GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buffer);

  /* skip sync word */
  if (!gst_bit_reader_skip (&reader, 8 * 4))
    return FALSE;

  /* skip extension code */
  if (!gst_bit_reader_skip (&reader, 4))
    return FALSE;

  /* f_code */
  READ_UINT8 (&reader, ext->f_code[0][0], 4);
  READ_UINT8 (&reader, ext->f_code[0][1], 4);
  READ_UINT8 (&reader, ext->f_code[1][0], 4);
  READ_UINT8 (&reader, ext->f_code[1][1], 4);

  /* intra DC precision */
  READ_UINT8 (&reader, ext->intra_dc_precision, 2);

  /* picture structure */
  READ_UINT8 (&reader, ext->picture_structure, 2);

  /* top field first */
  READ_UINT8 (&reader, ext->top_field_first, 1);

  /* frame pred frame dct */
  READ_UINT8 (&reader, ext->frame_pred_frame_dct, 1);

  /* concealment motion vectors */
  READ_UINT8 (&reader, ext->concealment_motion_vectors, 1);

  /* q scale type */
  READ_UINT8 (&reader, ext->q_scale_type, 1);

  /* intra vlc format */
  READ_UINT8 (&reader, ext->intra_vlc_format, 1);

  /* alternate scan */
  READ_UINT8 (&reader, ext->alternate_scan, 1);

  /* repeat first field */
  READ_UINT8 (&reader, ext->repeat_first_field, 1);

  /* chroma_420_type */
  READ_UINT8 (&reader, ext->chroma_420_type, 1);

  /* progressive_frame */
  READ_UINT8 (&reader, ext->progressive_frame, 1);

  return TRUE;

error:
  GST_WARNING ("error parsing \"Picture Coding Extension\"");
  return FALSE;
}
Example #19
0
gboolean
mpeg4_util_parse_VOL (GstBuffer * buf, Mpeg4VisualObject * vo,
    Mpeg4VideoObjectLayer * vol)
{
  GstBitReader reader = GST_BIT_READER_INIT_FROM_BUFFER (buf);

  guint8 video_object_layer_start_code;
  guint8 aspect_ratio_info;
  guint8 control_parameters;
  guint8 not_8_bit;

  /* set default values */
  vol->verid = vo->verid;
  vol->priority = vo->priority;

  vol->low_delay = FALSE;
  vol->chroma_format = 1;
  vol->vbv_parameters = FALSE;
  vol->quant_precision = 5;
  vol->bits_per_pixel = 8;
  vol->quarter_sample = FALSE;

  /* start code prefix */
  SKIP (&reader, 24);

  READ_UINT8 (&reader, video_object_layer_start_code, 8);
  if (!(video_object_layer_start_code >= MPEG4_PACKET_VOL_MIN &&
          video_object_layer_start_code <= MPEG4_PACKET_VOL_MAX))
    goto wrong_start_code;

  READ_UINT8 (&reader, vol->random_accesible_vol, 1);
  READ_UINT8 (&reader, vol->video_object_type_indication, 8);

  READ_UINT8 (&reader, vol->is_object_layer_identifier, 1);
  if (vol->is_object_layer_identifier) {
    READ_UINT8 (&reader, vol->verid, 4);
    READ_UINT8 (&reader, vol->priority, 3);
  }

  READ_UINT8 (&reader, aspect_ratio_info, 4);
  if (aspect_ratio_info != 0xff)
    mpeg4_util_par_from_info (aspect_ratio_info, &vol->par_n, &vol->par_d);

  else {
    READ_UINT8 (&reader, vol->par_n, 8);
    CHECK_ALLOWED (vol->par_n, 1, 255);
    READ_UINT8 (&reader, vol->par_d, 8);
    CHECK_ALLOWED (vol->par_d, 1, 255);
  }

  READ_UINT8 (&reader, control_parameters, 1);
  if (control_parameters) {
    READ_UINT8 (&reader, vol->chroma_format, 2);
    READ_UINT8 (&reader, vol->low_delay, 1);

    READ_UINT8 (&reader, vol->vbv_parameters, 1);
    if (vol->vbv_parameters) {
      guint16 first_half, latter_half;
      guint8 latter_part;

      READ_UINT16 (&reader, first_half, 15);
      SKIP (&reader, 1);
      READ_UINT16 (&reader, latter_half, 15);
      SKIP (&reader, 1);
      vol->bit_rate = (first_half << 15) | latter_half;

      READ_UINT16 (&reader, first_half, 15);
      SKIP (&reader, 1);
      READ_UINT8 (&reader, latter_part, 3);
      SKIP (&reader, 1);
      vol->vbv_buffer_size = (first_half << 15) | latter_part;
    }
  }

  READ_UINT8 (&reader, vol->shape, 2);
  if (vol->shape != 0x0)
    goto invalid_shape;

  /* marker_bit */
  SKIP (&reader, 1);
  READ_UINT16 (&reader, vol->vop_time_increment_resolution, 16);
  CHECK_ALLOWED (vol->vop_time_increment_resolution, 1, G_MAXUINT16);
  vol->vop_time_increment_bits =
      g_bit_storage (vol->vop_time_increment_resolution);
  /* marker_bit */
  SKIP (&reader, 1);

  READ_UINT8 (&reader, vol->fixed_vop_rate, 1);
  if (vol->fixed_vop_rate)
    READ_UINT16 (&reader, vol->fixed_vop_time_increment,
        vol->vop_time_increment_bits);

  /* marker bit */
  SKIP (&reader, 1);
  READ_UINT16 (&reader, vol->width, 13);
  /* marker bit */
  SKIP (&reader, 1);
  READ_UINT16 (&reader, vol->height, 13);
  /* marker bit */
  SKIP (&reader, 1);

  READ_UINT8 (&reader, vol->interlaced, 1);
  READ_UINT8 (&reader, vol->obmc_disable, 1);

  if (vol->verid == 0x1) {
    READ_UINT8 (&reader, vol->sprite_enable, 1);
  } else
    READ_UINT8 (&reader, vol->sprite_enable, 2);

  if (vol->sprite_enable != 0x0)
    goto invalid_sprite_enable;

  READ_UINT8 (&reader, not_8_bit, 1);
  if (not_8_bit) {
    READ_UINT8 (&reader, vol->quant_precision, 4);
    CHECK_ALLOWED (vol->quant_precision, 3, 9);

    READ_UINT8 (&reader, vol->bits_per_pixel, 4);
    CHECK_ALLOWED (vol->bits_per_pixel, 4, 12);
  }


  READ_UINT8 (&reader, vol->quant_type, 1);
  if (vol->quant_type) {
    if (!mpeg4_util_parse_quant (&reader, vol->intra_quant_mat,
            default_intra_quant_mat))
      goto error;

    if (!mpeg4_util_parse_quant (&reader, vol->non_intra_quant_mat,
            default_non_intra_quant_mat))
      goto error;
  } else {
    memset (&vol->intra_quant_mat, 0, 64);
    memset (&vol->non_intra_quant_mat, 0, 64);
  }

  if (vol->verid != 0x1)
    READ_UINT8 (&reader, vol->quarter_sample, 1);

  READ_UINT8 (&reader, vol->complexity_estimation_disable, 1);
  if (!vol->complexity_estimation_disable)
    goto complexity_estimation_error;

  READ_UINT8 (&reader, vol->resync_marker_disable, 1);

  return TRUE;

error:
  GST_WARNING ("error parsing \"Video Object Layer\"");
  return FALSE;

wrong_start_code:
  GST_WARNING ("got buffer with wrong start code");
  goto error;

invalid_shape:
  GST_WARNING ("we only support rectangular shape");
  goto error;

invalid_sprite_enable:
  GST_WARNING ("we only support sprite_enable == 0");
  goto error;

complexity_estimation_error:
  GST_WARNING ("don't support complexity estimation");
  goto error;
}
/**
 * gst_mpeg4_parse_video_plane_with_short_header:
 * @shorthdr: The #GstMpeg4VideoPlaneShortHdr to parse
 * @data: The data to parse
 * @size: The size of the @data to parse
 */
GstMpeg4ParseResult
gst_mpeg4_parse_video_plane_short_header (GstMpeg4VideoPlaneShortHdr *
    shorthdr, const guint8 * data, gsize size)
{
  guint8 zero_bits;

  GstBitReader br = GST_BIT_READER_INIT (data, size);

  g_return_val_if_fail (shorthdr != NULL, GST_MPEG4_PARSER_ERROR);

  if (gst_bit_reader_get_remaining (&br) < 48)
    goto failed;

  if (gst_bit_reader_get_bits_uint32_unchecked (&br, 22) != 0x20)
    goto failed;

  shorthdr->temporal_reference =
      gst_bit_reader_get_bits_uint8_unchecked (&br, 8);
  CHECK_MARKER (&br);
  zero_bits = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
  if (zero_bits != 0x00)
    goto failed;

  shorthdr->split_screen_indicator =
      gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
  shorthdr->document_camera_indicator =
      gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
  shorthdr->full_picture_freeze_release =
      gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
  shorthdr->source_format = gst_bit_reader_get_bits_uint8_unchecked (&br, 3);

  /* Set parameters/Table 6-25 */
  switch (shorthdr->source_format) {
    case 0x01:
      shorthdr->vop_width = 128;
      shorthdr->vop_height = 96;
      shorthdr->num_macroblocks_in_gob = 8;
      shorthdr->num_gobs_in_vop = 6;
      break;
    case 0x02:
      shorthdr->vop_width = 176;
      shorthdr->vop_height = 144;
      shorthdr->num_macroblocks_in_gob = 11;
      shorthdr->num_gobs_in_vop = 9;
      break;
    case 0x03:
      shorthdr->vop_width = 352;
      shorthdr->vop_height = 288;
      shorthdr->num_macroblocks_in_gob = 22;
      shorthdr->num_gobs_in_vop = 18;
      break;
    case 0x04:
      shorthdr->vop_width = 704;
      shorthdr->vop_height = 576;
      shorthdr->num_macroblocks_in_gob = 88;
      shorthdr->num_gobs_in_vop = 18;
      break;
    case 0x05:
      shorthdr->vop_width = 1408;
      shorthdr->vop_height = 1152;
      shorthdr->num_macroblocks_in_gob = 352;
      shorthdr->num_gobs_in_vop = 18;
      break;
    default:
      shorthdr->vop_width = 0;
      shorthdr->vop_height = 0;
      shorthdr->num_macroblocks_in_gob = 0;
      shorthdr->num_gobs_in_vop = 0;
  }

  shorthdr->picture_coding_type =
      gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
  zero_bits = gst_bit_reader_get_bits_uint8_unchecked (&br, 4);

  if (zero_bits != 0x00)
    goto failed;

  shorthdr->vop_quant = gst_bit_reader_get_bits_uint8_unchecked (&br, 5);
  zero_bits = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);

  if (zero_bits != 0x00)
    goto failed;

  do {
    READ_UINT8 (&br, shorthdr->pei, 1);

    if (shorthdr->pei == 1)
      READ_UINT8 (&br, shorthdr->psupp, 8);

  } while (shorthdr->pei == 1);

  shorthdr->size = gst_bit_reader_get_pos (&br);

  return GST_MPEG4_PARSER_OK;

failed:
  GST_WARNING ("Could not parse the Plane short header");

  return GST_MPEG4_PARSER_ERROR;
}
/**
 * gst_mpeg4_parse_video_packet_header:
 * @videopackethdr: The #GstMpeg4VideoPacketHdr structure to fill
 * @vol: The last parsed #GstMpeg4VideoObjectLayer, will be updated
 * with the informations found during the parsing
 * @vop: The last parsed #GstMpeg4VideoObjectPlane, will be updated
 * with the informations found during the parsing
 * @sprite_trajectory: A #GstMpeg4SpriteTrajectory to fill or %NULL
 * with the informations found during the parsing
 * @data: The data to parse, should be set after the resync marker.
 * @size: The size of the data to parse
 *
 * Parsers @data containing the video packet header
 * and fills the @videopackethdr structure
 */
GstMpeg4ParseResult
gst_mpeg4_parse_video_packet_header (GstMpeg4VideoPacketHdr * videopackethdr,
    GstMpeg4VideoObjectLayer * vol, GstMpeg4VideoObjectPlane * vop,
    GstMpeg4SpriteTrajectory * sprite_trajectory, const guint8 * data,
    gsize size)
{
  guint8 markersize;
  GstBitReader br = GST_BIT_READER_INIT (data, size);

  g_return_val_if_fail (videopackethdr != NULL, GST_MPEG4_PARSER_ERROR);
  g_return_val_if_fail (vol != NULL, GST_MPEG4_PARSER_ERROR);

  markersize = compute_resync_marker_size (vop, NULL, NULL);

  CHECK_REMAINING (&br, markersize);

  if (gst_bit_reader_get_bits_uint32_unchecked (&br, markersize) != 0x01)
    goto failed;

  if (vol->shape != GST_MPEG4_RECTANGULAR) {
    READ_UINT8 (&br, videopackethdr->header_extension_code, 1);
    if (vol->sprite_enable == GST_MPEG4_SPRITE_STATIC &&
        vop->coding_type == GST_MPEG4_I_VOP) {

      CHECK_REMAINING (&br, 56);

      U_READ_UINT16 (&br, vop->width, 13);
      CHECK_MARKER (&br);
      U_READ_UINT16 (&br, vop->height, 13);
      CHECK_MARKER (&br);
      U_READ_UINT16 (&br, vop->horizontal_mc_spatial_ref, 13);
      CHECK_MARKER (&br);
      U_READ_UINT16 (&br, vop->vertical_mc_spatial_ref, 13);
      CHECK_MARKER (&br);

      /* Update macroblock infirmations */
      vop->mb_height = (vop->height + 15) / 16;
      vop->mb_width = (vop->width + 15) / 16;
      vop->mb_num = vop->mb_height * vop->mb_width;
    }
  }

  READ_UINT16 (&br, videopackethdr->macroblock_number,
      g_bit_storage (vop->mb_num - 1));

  if (vol->shape != GST_MPEG4_BINARY_ONLY)
    READ_UINT16 (&br, videopackethdr->quant_scale, vol->quant_precision);

  if (vol->shape == GST_MPEG4_RECTANGULAR)
    READ_UINT8 (&br, videopackethdr->header_extension_code, 1);

  if (videopackethdr->header_extension_code) {
    guint timeincr = 0;
    guint8 bit = 0, coding_type;

    do {
      READ_UINT8 (&br, bit, 1);
      timeincr++;
    } while (bit);

    vol->vop_time_increment_bits = timeincr;

    CHECK_MARKER (&br);
    READ_UINT16 (&br, vop->time_increment, timeincr);
    CHECK_MARKER (&br);
    READ_UINT8 (&br, coding_type, 2);
    vop->coding_type = coding_type;

    if (vol->shape != GST_MPEG4_RECTANGULAR) {
      READ_UINT8 (&br, vop->change_conv_ratio_disable, 1);
      if (vop->coding_type != GST_MPEG4_I_VOP)
        READ_UINT8 (&br, vop->shape_coding_type, 1);
    }

    if (vol->shape != GST_MPEG4_BINARY_ONLY) {
      READ_UINT8 (&br, vop->intra_dc_vlc_thr, 3);

      if (sprite_trajectory && vol->sprite_enable == GST_MPEG4_SPRITE_GMG &&
          vop->coding_type == GST_MPEG4_S_VOP &&
          vol->no_of_sprite_warping_points > 0) {

        parse_sprite_trajectory (&br, sprite_trajectory,
            vol->no_of_sprite_warping_points);
      }

      if (vol->reduced_resolution_vop_enable &&
          vol->shape == GST_MPEG4_RECTANGULAR &&
          (vop->coding_type == GST_MPEG4_P_VOP ||
              vop->coding_type == GST_MPEG4_I_VOP))
        READ_UINT8 (&br, vop->reduced_resolution, 1);

      if (vop->coding_type != GST_MPEG4_I_VOP) {
        READ_UINT8 (&br, vop->fcode_forward, 3);
        CHECK_ALLOWED (vop->fcode_forward, 1, 7);
      }

      if (vop->coding_type == GST_MPEG4_B_VOP) {
        READ_UINT8 (&br, vop->fcode_backward, 3);
        CHECK_ALLOWED (vop->fcode_backward, 1, 7);
      }
    }
  }

  if (vol->newpred_enable) {
    guint16 nbbits =
        vol->vop_time_increment_bits + 3 < 15 ? vop->time_increment + 3 : 15;

    READ_UINT16 (&br, vop->id, nbbits);
    READ_UINT8 (&br, vop->id_for_prediction_indication, 1);
    if (vop->id_for_prediction_indication) {
      /* Would be nice if the standard actually told us... */
      READ_UINT16 (&br, vop->id, nbbits);
      CHECK_MARKER (&br);
    }
  }

  videopackethdr->size = gst_bit_reader_get_pos (&br);

failed:
  GST_DEBUG ("Failed to parse video packet header");

  return GST_MPEG4_PARSER_NO_PACKET;
}
/**
 * gst_mpeg4_parse_video_object_layer:
 * @vol: The #GstMpeg4VideoObjectLayer structure to fill
 * @vo: The #GstMpeg4VisualObject currently being parsed or %NULL
 * @data: The data to parse
 * @size: The size of the @data to parse
 *
 * Parses @data containing the video object layer packet, and fills
 * the @vol structure.
 *
 * Returns: a #GstMpeg4ParseResult
 */
GstMpeg4ParseResult
gst_mpeg4_parse_video_object_layer (GstMpeg4VideoObjectLayer * vol,
    GstMpeg4VisualObject * vo, const guint8 * data, gsize size)
{
  guint8 video_object_layer_start_code;

  /* Used for enums types */
  guint8 tmp;
  GstBitReader br = GST_BIT_READER_INIT (data, size);

  g_return_val_if_fail (vol != NULL, GST_MPEG4_PARSER_ERROR);

  GST_DEBUG ("Parsing video object layer");

  READ_UINT8 (&br, video_object_layer_start_code, 8);
  if (!(video_object_layer_start_code >= GST_MPEG4_VIDEO_LAYER_FIRST &&
          video_object_layer_start_code <= GST_MPEG4_VIDEO_LAYER_LAST))
    goto wrong_start_code;

  /* set default values */
  if (vo) {
    vol->verid = vo->verid;
    vol->priority = vo->priority;
  } else {
    vol->verid = 1;
    vol->priority = 0;
  }

  vol->low_delay = FALSE;
  vol->chroma_format = 1;
  vol->vbv_parameters = FALSE;
  vol->quant_precision = 5;
  vol->bits_per_pixel = 8;
  vol->quarter_sample = FALSE;
  vol->newpred_enable = FALSE;
  vol->interlaced = 0;
  vol->width = 0;
  vol->height = 0;

  READ_UINT8 (&br, vol->random_accessible_vol, 1);
  READ_UINT8 (&br, vol->video_object_type_indication, 8);

  READ_UINT8 (&br, vol->is_object_layer_identifier, 1);
  if (vol->is_object_layer_identifier) {
    READ_UINT8 (&br, vol->verid, 4);
    READ_UINT8 (&br, vol->priority, 3);
  }

  READ_UINT8 (&br, tmp, 4);
  vol->aspect_ratio_info = tmp;
  if (vol->aspect_ratio_info != GST_MPEG4_EXTENDED_PAR) {
    mpeg4_util_par_from_info (vol->aspect_ratio_info, &vol->par_width,
        &vol->par_height);

  } else {
    gint v;

    READ_UINT8 (&br, vol->par_width, 8);
    v = vol->par_width;
    CHECK_ALLOWED (v, 1, 255);

    READ_UINT8 (&br, vol->par_height, 8);
    v = vol->par_height;
    CHECK_ALLOWED (v, 1, 255);
  }
  GST_DEBUG ("Pixel aspect ratio %d/%d", vol->par_width, vol->par_width);

  READ_UINT8 (&br, vol->control_parameters, 1);
  if (vol->control_parameters) {
    guint8 chroma_format;

    READ_UINT8 (&br, chroma_format, 2);
    vol->chroma_format = chroma_format;
    READ_UINT8 (&br, vol->low_delay, 1);

    READ_UINT8 (&br, vol->vbv_parameters, 1);
    if (vol->vbv_parameters) {
      CHECK_REMAINING (&br, 79);

      vol->first_half_bitrate =
          gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
      MARKER_UNCHECKED (&br);

      vol->latter_half_bitrate =
          gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
      MARKER_UNCHECKED (&br);

      vol->bit_rate =
          (vol->first_half_bitrate << 15) | vol->latter_half_bitrate;

      vol->first_half_vbv_buffer_size =
          gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
      MARKER_UNCHECKED (&br);

      vol->latter_half_vbv_buffer_size =
          gst_bit_reader_get_bits_uint8_unchecked (&br, 3);

      vol->vbv_buffer_size = (vol->first_half_vbv_buffer_size << 15) |
          vol->latter_half_vbv_buffer_size;

      vol->first_half_vbv_occupancy =
          gst_bit_reader_get_bits_uint16_unchecked (&br, 11);
      MARKER_UNCHECKED (&br);

      vol->latter_half_vbv_occupancy =
          gst_bit_reader_get_bits_uint16_unchecked (&br, 15);
      MARKER_UNCHECKED (&br);
    }
  }

  READ_UINT8 (&br, tmp, 2);
  vol->shape = tmp;

  if (vol->shape == GST_MPEG4_GRAYSCALE) {
    /* TODO support grayscale shapes, for now we just pass */

    /* Something the standard starts to define... */
    GST_WARNING ("Grayscale shaped not supported");
    goto failed;
  }

  if (vol->shape == GST_MPEG4_GRAYSCALE && vol->verid != 0x01)
    READ_UINT8 (&br, vol->shape_extension, 4);

  CHECK_REMAINING (&br, 19);

  MARKER_UNCHECKED (&br);
  vol->vop_time_increment_resolution =
      gst_bit_reader_get_bits_uint16_unchecked (&br, 16);
  if (vol->vop_time_increment_resolution < 1) {
    GST_WARNING ("value not in allowed range. value: %d, range %d-%d",
        vol->vop_time_increment_resolution, 1, G_MAXUINT16);
    goto failed;
  }
  vol->vop_time_increment_bits =
      g_bit_storage (vol->vop_time_increment_resolution);

  MARKER_UNCHECKED (&br);
  vol->fixed_vop_rate = gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
  if (vol->fixed_vop_rate)
    READ_UINT16 (&br, vol->fixed_vop_time_increment,
        vol->vop_time_increment_bits);

  if (vol->shape != GST_MPEG4_BINARY_ONLY) {
    if (vol->shape == GST_MPEG4_RECTANGULAR) {
      CHECK_REMAINING (&br, 29);

      MARKER_UNCHECKED (&br);
      vol->width = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
      MARKER_UNCHECKED (&br);
      vol->height = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
      MARKER_UNCHECKED (&br);
    }

    READ_UINT8 (&br, vol->interlaced, 1);
    READ_UINT8 (&br, vol->obmc_disable, 1);

    if (vol->verid == 0x1)
      READ_UINT8 (&br, tmp, 1);
    else
      READ_UINT8 (&br, tmp, 2);
    vol->sprite_enable = tmp;

    if (vol->sprite_enable == GST_MPEG4_SPRITE_STATIC ||
        vol->sprite_enable == GST_MPEG4_SPRITE_GMG) {

      if (vol->sprite_enable == GST_MPEG4_SPRITE_GMG)
        CHECK_REMAINING (&br, 9);
      else {
        CHECK_REMAINING (&br, 65);

        vol->sprite_width = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
        MARKER_UNCHECKED (&br);

        vol->sprite_height = gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
        MARKER_UNCHECKED (&br);

        vol->sprite_left_coordinate =
            gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
        MARKER_UNCHECKED (&br);

        vol->sprite_top_coordinate =
            gst_bit_reader_get_bits_uint16_unchecked (&br, 13);
        MARKER_UNCHECKED (&br);
      }
      vol->no_of_sprite_warping_points =
          gst_bit_reader_get_bits_uint8_unchecked (&br, 6);
      vol->sprite_warping_accuracy =
          gst_bit_reader_get_bits_uint8_unchecked (&br, 2);
      vol->sprite_brightness_change =
          gst_bit_reader_get_bits_uint8_unchecked (&br, 1);

      if (vol->sprite_enable != GST_MPEG4_SPRITE_GMG)
        vol->low_latency_sprite_enable =
            gst_bit_reader_get_bits_uint8_unchecked (&br, 1);
    }

    if (vol->verid != 0x1 && vol->shape != GST_MPEG4_RECTANGULAR)
      READ_UINT8 (&br, vol->sadct_disable, 1);

    READ_UINT8 (&br, vol->not_8_bit, 1);
    if (vol->not_8_bit) {
      READ_UINT8 (&br, vol->quant_precision, 4);
      CHECK_ALLOWED (vol->quant_precision, 3, 9);

      READ_UINT8 (&br, vol->bits_per_pixel, 4);
      CHECK_ALLOWED (vol->bits_per_pixel, 4, 12);
    }

    if (vol->shape == GST_MPEG4_GRAYSCALE) {
      /* We don't actually support it */
      READ_UINT8 (&br, vol->no_gray_quant_update, 1);
      READ_UINT8 (&br, vol->composition_method, 1);
      READ_UINT8 (&br, vol->linear_composition, 1);
    }

    READ_UINT8 (&br, vol->quant_type, 1);
    if (vol->quant_type) {
      if (!parse_quant (&br, vol->intra_quant_mat, default_intra_quant_mat,
              &vol->load_intra_quant_mat))
        goto failed;

      if (!parse_quant (&br, vol->non_intra_quant_mat,
              default_non_intra_quant_mat, &vol->load_non_intra_quant_mat))
        goto failed;

      if (vol->shape == GST_MPEG4_GRAYSCALE) {
        /* Something the standard starts to define... */
        GST_WARNING ("Grayscale shaped not supported");
        goto failed;
      }

    } else {
      memset (&vol->intra_quant_mat, 0, 64);
      memset (&vol->non_intra_quant_mat, 0, 64);
    }

    if (vol->verid != 0x1)
      READ_UINT8 (&br, vol->quarter_sample, 1);

    READ_UINT8 (&br, vol->complexity_estimation_disable, 1);
    if (!vol->complexity_estimation_disable) {
      guint8 estimation_method;
      guint8 estimation_disable;

      /* skip unneeded properties */
      READ_UINT8 (&br, estimation_method, 2);
      if (estimation_method < 2) {
        READ_UINT8 (&br, estimation_disable, 1);
        if (!estimation_disable)
          SKIP (&br, 6);
        READ_UINT8 (&br, estimation_disable, 1);
        if (!estimation_disable)
          SKIP (&br, 4);
        CHECK_MARKER (&br);
        READ_UINT8 (&br, estimation_disable, 1);
        if (!estimation_disable)
          SKIP (&br, 4);
        READ_UINT8 (&br, estimation_disable, 1);
        if (!estimation_disable)
          SKIP (&br, 6);
        CHECK_MARKER (&br);

        if (estimation_method == 1) {
          READ_UINT8 (&br, estimation_disable, 1);
          if (!estimation_disable)
            SKIP (&br, 2);
        }
      }
    }

    READ_UINT8 (&br, vol->resync_marker_disable, 1);
    READ_UINT8 (&br, vol->data_partitioned, 1);

    if (vol->data_partitioned)
      READ_UINT8 (&br, vol->reversible_vlc, 1);

    if (vol->verid != 0x01) {
      READ_UINT8 (&br, vol->newpred_enable, 1);
      if (vol->newpred_enable)
        /* requested_upstream_message_type and newpred_segment_type */
        SKIP (&br, 3);

      READ_UINT8 (&br, vol->reduced_resolution_vop_enable, 1);
    }

    READ_UINT8 (&br, vol->scalability, 1);
    if (vol->scalability) {
      SKIP (&br, 26);           /* Few not needed props */
      READ_UINT8 (&br, vol->enhancement_type, 1);
    }

    /* More unused infos */
  } else if (vol->verid != 0x01) {
    GST_WARNING ("Binary only shapes not fully supported");
    goto failed;
  }
  /* ... */

  return GST_MPEG4_PARSER_OK;

failed:
  GST_WARNING ("failed parsing \"Video Object Layer\"");
  return GST_MPEG4_PARSER_ERROR;

wrong_start_code:
  GST_WARNING ("got buffer with wrong start code");
  goto failed;
}
/**
 * gst_mpeg4_parse_visual_object_sequence:
 * @vos: The #GstMpeg4VisualObjectSequence structure to fill
 * @data: The data to parse, should contain the visual_object_sequence_start_code
 * but not the start code prefix
 * @size: The size of the @data to parse
 *
 * Parses @data containing the visual object sequence packet, and fills
 * the @vos structure.
 *
 * Returns: a #GstMpeg4ParseResult
 */
GstMpeg4ParseResult
gst_mpeg4_parse_visual_object_sequence (GstMpeg4VisualObjectSequence * vos,
    const guint8 * data, gsize size)
{
  guint8 vos_start_code;
  GstBitReader br = GST_BIT_READER_INIT (data, size);

  g_return_val_if_fail (vos != NULL, GST_MPEG4_PARSER_ERROR);

  READ_UINT8 (&br, vos_start_code, 8);
  if (vos_start_code != GST_MPEG4_VISUAL_OBJ_SEQ_START)
    goto wrong_start_code;

  READ_UINT8 (&br, vos->profile_and_level_indication, 8);

  switch (vos->profile_and_level_indication) {
    case 0x01:
      vos->profile = GST_MPEG4_PROFILE_SIMPLE;
      vos->level = GST_MPEG4_LEVEL1;
      break;
    case 0x02:
      vos->profile = GST_MPEG4_PROFILE_SIMPLE;
      vos->level = GST_MPEG4_LEVEL2;
      break;
    case 0x03:
      vos->profile = GST_MPEG4_PROFILE_SIMPLE;
      vos->level = GST_MPEG4_LEVEL3;
      break;
    case 0x08:
      vos->profile = GST_MPEG4_PROFILE_SIMPLE;
      vos->level = GST_MPEG4_LEVEL0;
      break;
    case 0x10:
      vos->profile = GST_MPEG4_PROFILE_SIMPLE_SCALABLE;
      vos->level = GST_MPEG4_LEVEL0;
      break;
    case 0x11:
      vos->profile = GST_MPEG4_PROFILE_SIMPLE_SCALABLE;
      vos->level = GST_MPEG4_LEVEL1;
      break;
    case 0x12:
      vos->profile = GST_MPEG4_PROFILE_SIMPLE_SCALABLE;
      vos->level = GST_MPEG4_LEVEL2;
      break;
    case 0x21:
      vos->profile = GST_MPEG4_PROFILE_CORE;
      vos->level = GST_MPEG4_LEVEL1;
      break;
    case 0x22:
      vos->profile = GST_MPEG4_PROFILE_CORE;
      vos->level = GST_MPEG4_LEVEL2;
      break;
    case 0x32:
      vos->profile = GST_MPEG4_PROFILE_MAIN;
      vos->level = GST_MPEG4_LEVEL2;
      break;
    case 0x33:
      vos->profile = GST_MPEG4_PROFILE_MAIN;
      vos->level = GST_MPEG4_LEVEL3;
      break;
    case 0x34:
      vos->profile = GST_MPEG4_PROFILE_MAIN;
      vos->level = GST_MPEG4_LEVEL4;
      break;
    case 0x42:
      vos->profile = GST_MPEG4_PROFILE_N_BIT;
      vos->level = GST_MPEG4_LEVEL2;
      break;
    case 0x51:
      vos->profile = GST_MPEG4_PROFILE_SCALABLE_TEXTURE;
      vos->level = GST_MPEG4_LEVEL1;
      break;
    case 0x61:
      vos->profile = GST_MPEG4_PROFILE_SIMPLE_FACE_ANIMATION;
      vos->level = GST_MPEG4_LEVEL1;
      break;
    case 0x62:
      vos->profile = GST_MPEG4_PROFILE_SIMPLE_FACE_ANIMATION;
      vos->level = GST_MPEG4_LEVEL2;
      break;
    case 0x63:
      vos->profile = GST_MPEG4_PROFILE_SIMPLE_FBA;
      vos->level = GST_MPEG4_LEVEL1;
      break;
    case 0x64:
      vos->profile = GST_MPEG4_PROFILE_SIMPLE_FBA;
      vos->level = GST_MPEG4_LEVEL2;
      break;
    case 0x71:
      vos->profile = GST_MPEG4_PROFILE_BASIC_ANIMATED_TEXTURE;
      vos->level = GST_MPEG4_LEVEL1;
      break;
    case 0x72:
      vos->profile = GST_MPEG4_PROFILE_BASIC_ANIMATED_TEXTURE;
      vos->level = GST_MPEG4_LEVEL2;
      break;
    case 0x81:
      vos->profile = GST_MPEG4_PROFILE_HYBRID;
      vos->level = GST_MPEG4_LEVEL1;
      break;
    case 0x82:
      vos->profile = GST_MPEG4_PROFILE_HYBRID;
      vos->level = GST_MPEG4_LEVEL2;
      break;
    case 0x91:
      vos->profile = GST_MPEG4_PROFILE_ADVANCED_REALTIME_SIMPLE;
      vos->level = GST_MPEG4_LEVEL1;
      break;
    case 0x92:
      vos->profile = GST_MPEG4_PROFILE_ADVANCED_REALTIME_SIMPLE;
      vos->level = GST_MPEG4_LEVEL2;
      break;
    case 0x93:
      vos->profile = GST_MPEG4_PROFILE_ADVANCED_REALTIME_SIMPLE;
      vos->level = GST_MPEG4_LEVEL3;
      break;
    case 0x94:
      vos->profile = GST_MPEG4_PROFILE_ADVANCED_REALTIME_SIMPLE;
      vos->level = GST_MPEG4_LEVEL4;
      break;
    case 0xa1:
      vos->profile = GST_MPEG4_PROFILE_CORE_SCALABLE;
      vos->level = GST_MPEG4_LEVEL1;
      break;
    case 0xa2:
      vos->profile = GST_MPEG4_PROFILE_CORE_SCALABLE;
      vos->level = GST_MPEG4_LEVEL2;
      break;
    case 0xa3:
      vos->profile = GST_MPEG4_PROFILE_CORE_SCALABLE;
      vos->level = GST_MPEG4_LEVEL3;
      break;
    case 0xb1:
      vos->profile = GST_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
      vos->level = GST_MPEG4_LEVEL1;
      break;
    case 0xb2:
      vos->profile = GST_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
      vos->level = GST_MPEG4_LEVEL2;
      break;
    case 0xb3:
      vos->profile = GST_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
      vos->level = GST_MPEG4_LEVEL3;
      break;
    case 0xb4:
      vos->profile = GST_MPEG4_PROFILE_ADVANCED_CODING_EFFICIENCY;
      vos->level = GST_MPEG4_LEVEL4;
      break;
    case 0xc1:
      vos->profile = GST_MPEG4_PROFILE_ADVANCED_CORE;
      vos->level = GST_MPEG4_LEVEL1;
      break;
    case 0xc2:
      vos->profile = GST_MPEG4_PROFILE_ADVANCED_CORE;
      vos->level = GST_MPEG4_LEVEL2;
      break;
    case 0xc3:
      vos->profile = GST_MPEG4_PROFILE_ADVANCED_CORE;
      vos->level = GST_MPEG4_LEVEL3;
      break;
    case 0xd1:
      vos->profile = GST_MPEG4_PROFILE_ADVANCED_SCALABLE_TEXTURE;
      vos->level = GST_MPEG4_LEVEL1;
      break;
    case 0xd2:
      vos->profile = GST_MPEG4_PROFILE_ADVANCED_SCALABLE_TEXTURE;
      vos->level = GST_MPEG4_LEVEL2;
      break;
    case 0xd3:
      vos->profile = GST_MPEG4_PROFILE_ADVANCED_SCALABLE_TEXTURE;
      vos->level = GST_MPEG4_LEVEL3;
      break;
    case 0xe1:
      vos->profile = GST_MPEG4_PROFILE_SIMPLE_STUDIO;
      vos->level = GST_MPEG4_LEVEL1;
      break;
    case 0xe2:
      vos->profile = GST_MPEG4_PROFILE_SIMPLE_STUDIO;
      vos->level = GST_MPEG4_LEVEL2;
      break;
    case 0xe3:
      vos->profile = GST_MPEG4_PROFILE_SIMPLE_STUDIO;
      vos->level = GST_MPEG4_LEVEL3;
      break;
    case 0xe4:
      vos->profile = GST_MPEG4_PROFILE_SIMPLE_STUDIO;
      vos->level = GST_MPEG4_LEVEL4;
      break;
    case 0xe5:
      vos->profile = GST_MPEG4_PROFILE_CORE_STUDIO;
      vos->level = GST_MPEG4_LEVEL1;
      break;
    case 0xe6:
      vos->profile = GST_MPEG4_PROFILE_CORE_STUDIO;
      vos->level = GST_MPEG4_LEVEL2;
      break;
    case 0xe7:
      vos->profile = GST_MPEG4_PROFILE_CORE_STUDIO;
      vos->level = GST_MPEG4_LEVEL3;
      break;
    case 0xe8:
      vos->profile = GST_MPEG4_PROFILE_CORE_STUDIO;
      vos->level = GST_MPEG4_LEVEL4;
      break;
    case 0xf0:
      vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
      vos->level = GST_MPEG4_LEVEL0;
      break;
    case 0xf1:
      vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
      vos->level = GST_MPEG4_LEVEL1;
      break;
    case 0xf2:
      vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
      vos->level = GST_MPEG4_LEVEL2;
      break;
    case 0xf3:
      vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
      vos->level = GST_MPEG4_LEVEL3;
      break;
    case 0xf4:
      vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
      vos->level = GST_MPEG4_LEVEL4;
      break;
    case 0xf5:
      vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
      vos->level = GST_MPEG4_LEVEL5;
      break;
    case 0xf7:
      vos->profile = GST_MPEG4_PROFILE_ADVANCED_SIMPLE;
      vos->level = GST_MPEG4_LEVEL3b;
      break;
    case 0xf8:
      vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
      vos->level = GST_MPEG4_LEVEL0;
      break;
    case 0xf9:
      vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
      vos->level = GST_MPEG4_LEVEL1;
      break;
    case 0xfa:
      vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
      vos->level = GST_MPEG4_LEVEL2;
      break;
    case 0xfb:
      vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
      vos->level = GST_MPEG4_LEVEL3;
      break;
    case 0xfc:
      vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
      vos->level = GST_MPEG4_LEVEL4;
      break;
    case 0xfd:
      vos->profile = GST_MPEG4_PROFILE_FINE_GRANULARITY_SCALABLE;
      vos->level = GST_MPEG4_LEVEL5;
      break;
    default:
      vos->profile = GST_MPEG4_PROFILE_RESERVED;
      vos->level = GST_MPEG4_LEVEL_RESERVED;
      break;
  }

  return GST_MPEG4_PARSER_OK;

wrong_start_code:
  GST_WARNING ("got buffer with wrong start code");
  return GST_MPEG4_PARSER_ERROR;

failed:
  GST_WARNING ("failed parsing \"Visual Object\"");
  return GST_MPEG4_PARSER_ERROR;
}