コード例 #1
0
/**
 * gst_mpeg4_next_resync:
 * @packet: The #GstMpeg4Packet to fill
 * @vop: The previously parsed #GstMpeg4VideoObjectPlane
 * @offset: offset from which to start the parsing
 * @data: The data to parse
 * @size: The size of the @data to parse
 *
 * Parses @data and fills @packet with the information of the next resync packet
 * found.
 *
 * Returns: a #GstMpeg4ParseResult
 */
static GstMpeg4ParseResult
gst_mpeg4_next_resync (GstMpeg4Packet * packet,
    const GstMpeg4VideoObjectPlane * vop, const guint8 * data, gsize size,
    gboolean first_resync_marker)
{
  guint markersize = 0, off1, off2;
  guint32 mask = 0xff, pattern = 0xff;
  GstByteReader br;

  gst_byte_reader_init (&br, data, size);

  g_return_val_if_fail (packet != NULL, GST_MPEG4_PARSER_ERROR);
  g_return_val_if_fail (vop != NULL, GST_MPEG4_PARSER_ERROR);

  markersize = compute_resync_marker_size (vop, &pattern, &mask);

  if (first_resync_marker) {
    off1 = 0;
  } else {
    off1 = gst_byte_reader_masked_scan_uint32 (&br, mask, pattern, 0, size);
  }

  if (off1 == -1)
    return GST_MPEG4_PARSER_NO_PACKET;

  GST_DEBUG ("Resync code found at %i", off1);

  packet->offset = off1;
  packet->type = GST_MPEG4_RESYNC;
  packet->marker_size = markersize;

  off2 = gst_byte_reader_masked_scan_uint32 (&br, mask, pattern,
      off1 + 2, size - off1 - 2);

  if (off2 == -1)
    return GST_MPEG4_PARSER_NO_PACKET_END;

  packet->size = off2 - off1;

  return GST_MPEG4_PARSER_OK;
}
コード例 #2
0
ファイル: mpeg4parser.c プロジェクト: 01org/libyami
/**
 * mpeg4_next_resync:
 * @packet: The #Mpeg4Packet to fill
 * @vop: The previously parsed #Mpeg4VideoObjectPlane
 * @offset: offset from which to start the parsing
 * @data: The data to parse
 * @size: The size of the @data to parse
 *
 * Parses @data and fills @packet with the information of the next resync packet
 * found.
 *
 * Returns: a #Mpeg4ParseResult
 */
static Mpeg4ParseResult
mpeg4_next_resync (Mpeg4Packet * packet,
    const Mpeg4VideoObjectPlane * vop, const uint8_t * data, size_t size,
    bool first_resync_marker)
{
  uint32_t markersize = 0, off1, off2;
  uint32_t mask = 0xff, pattern = 0xff;
  ByteReader br;

  byte_reader_init (&br, data, size);

  g_return_val_if_fail (packet != NULL, MPEG4_PARSER_ERROR);
  g_return_val_if_fail (vop != NULL, MPEG4_PARSER_ERROR);

  markersize = compute_resync_marker_size (vop, &pattern, &mask);

  if (first_resync_marker) {
    off1 = 0;
  } else {
    off1 = byte_reader_masked_scan_uint32 (&br, mask, pattern, 0, size);
  }

  if (off1 == -1)
    return MPEG4_PARSER_NO_PACKET;

  DEBUG ("Resync code found at %i", off1);

  packet->offset = off1;
  packet->type = MPEG4_RESYNC;
  packet->marker_size = markersize;

  off2 = byte_reader_masked_scan_uint32 (&br, mask, pattern,
      off1 + 2, size - off1 - 2);

  if (off2 == -1)
    return MPEG4_PARSER_NO_PACKET_END;

  packet->size = off2 - off1;

  return MPEG4_PARSER_OK;
}
コード例 #3
0
/**
 * 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;
}