static gboolean
gst_ac3_parse_frame_header_eac3 (GstAc3Parse * ac3parse, GstBuffer * buf,
    gint skip, guint * frame_size, guint * rate, guint * chans, guint * blks,
    guint * sid)
{
  GstBitReader bits = GST_BIT_READER_INIT_FROM_BUFFER (buf);
  guint16 frmsiz, sample_rate, blocks;
  guint8 strmtyp, fscod, fscod2, acmod, lfe_on, strmid, numblkscod;

  GST_LOG_OBJECT (ac3parse, "parsing e-ac3");

  gst_bit_reader_skip_unchecked (&bits, skip * 8);

  gst_bit_reader_skip_unchecked (&bits, 16);
  strmtyp = gst_bit_reader_get_bits_uint8_unchecked (&bits, 2); /* strmtyp     */
  if (G_UNLIKELY (strmtyp == 3)) {
    GST_DEBUG_OBJECT (ac3parse, "bad strmtyp %d", strmtyp);
    return FALSE;
  }

  strmid = gst_bit_reader_get_bits_uint8_unchecked (&bits, 3);  /* substreamid */
  frmsiz = gst_bit_reader_get_bits_uint16_unchecked (&bits, 11);        /* frmsiz      */
  fscod = gst_bit_reader_get_bits_uint8_unchecked (&bits, 2);   /* fscod       */
  if (fscod == 3) {
    fscod2 = gst_bit_reader_get_bits_uint8_unchecked (&bits, 2);        /* fscod2      */
    if (G_UNLIKELY (fscod2 == 3)) {
      GST_DEBUG_OBJECT (ac3parse, "invalid fscod2");
      return FALSE;
    }
    sample_rate = fscod_rates[fscod2] / 2;
    blocks = 6;
  } else {
    numblkscod = gst_bit_reader_get_bits_uint8_unchecked (&bits, 2);    /* numblkscod  */
    sample_rate = fscod_rates[fscod];
    blocks = numblks[numblkscod];
  }

  acmod = gst_bit_reader_get_bits_uint8_unchecked (&bits, 3);   /* acmod       */
  lfe_on = gst_bit_reader_get_bits_uint8_unchecked (&bits, 1);  /* lfeon       */

  gst_bit_reader_skip_unchecked (&bits, 5);     /* bsid        */

  if (frame_size)
    *frame_size = (frmsiz + 1) * 2;
  if (rate)
    *rate = sample_rate;
  if (chans)
    *chans = acmod_chans[acmod] + lfe_on;
  if (blks)
    *blks = blocks;
  if (sid)
    *sid = (strmtyp & 0x1) << 3 | strmid;

  return TRUE;
}
Пример #2
0
static gboolean
gst_ac3_parse_frame_header (GstAc3Parse * parse, GstBuffer * buf, gint skip,
    guint * framesize, guint * rate, guint * chans, guint * blocks,
    guint * sid, gboolean * eac)
{
  GstBitReader bits;
  guint16 sync;
  guint8 bsid;
  GstMapInfo map;
  gboolean ret = FALSE;

  gst_buffer_map (buf, &map, GST_MAP_READ);
  gst_bit_reader_init (&bits, map.data, map.size);

  GST_MEMDUMP_OBJECT (parse, "AC3 frame sync", map.data, MIN (map.size, 16));

  gst_bit_reader_skip_unchecked (&bits, skip * 8);

  sync = gst_bit_reader_get_bits_uint16_unchecked (&bits, 16);
  gst_bit_reader_skip_unchecked (&bits, 16 + 8);
  bsid = gst_bit_reader_peek_bits_uint8_unchecked (&bits, 5);

  if (G_UNLIKELY (sync != 0x0b77))
    goto cleanup;

  GST_LOG_OBJECT (parse, "bsid = %d", bsid);

  if (bsid <= 10) {
    if (eac)
      *eac = FALSE;
    ret = gst_ac3_parse_frame_header_ac3 (parse, buf, skip, framesize, rate,
        chans, blocks, sid);
    goto cleanup;
  } else if (bsid <= 16) {
    if (eac)
      *eac = TRUE;
    ret = gst_ac3_parse_frame_header_eac3 (parse, buf, skip, framesize, rate,
        chans, blocks, sid);
    goto cleanup;
  } else {
    GST_DEBUG_OBJECT (parse, "unexpected bsid %d", bsid);
    ret = FALSE;
    goto cleanup;
  }

  GST_DEBUG_OBJECT (parse, "unexpected bsid %d", bsid);

cleanup:
  gst_buffer_unmap (buf, &map);

  return ret;
}
static gboolean
gst_ac3_parse_frame_header (GstAc3Parse * parse, GstBuffer * buf, gint skip,
    guint * framesize, guint * rate, guint * chans, guint * blocks,
    guint * sid, gboolean * eac)
{
  GstBitReader bits = GST_BIT_READER_INIT_FROM_BUFFER (buf);
  guint16 sync;
  guint8 bsid;

  GST_MEMDUMP_OBJECT (parse, "AC3 frame sync", GST_BUFFER_DATA (buf), 16);

  gst_bit_reader_skip_unchecked (&bits, skip * 8);

  sync = gst_bit_reader_get_bits_uint16_unchecked (&bits, 16);
  gst_bit_reader_skip_unchecked (&bits, 16 + 8);
  bsid = gst_bit_reader_peek_bits_uint8_unchecked (&bits, 5);

  if (G_UNLIKELY (sync != 0x0b77))
    return FALSE;

  GST_LOG_OBJECT (parse, "bsid = %d", bsid);

  if (bsid <= 10) {
    if (eac)
      *eac = FALSE;
    return gst_ac3_parse_frame_header_ac3 (parse, buf, skip, framesize, rate,
        chans, blocks, sid);
  } else if (bsid <= 16) {
    if (eac)
      *eac = TRUE;
    return gst_ac3_parse_frame_header_eac3 (parse, buf, skip, framesize, rate,
        chans, blocks, sid);
  } else {
    GST_DEBUG_OBJECT (parse, "unexpected bsid %d", bsid);
    return FALSE;
  }
}
Пример #4
0
static GstFlowReturn
gst_vdp_h264_dec_parse_data (GstBaseVideoDecoder * base_video_decoder,
    GstBuffer * buf, gboolean at_eos, GstVideoFrame * frame)
{
  GstVdpH264Dec *h264_dec = GST_VDP_H264_DEC (base_video_decoder);
  GstBitReader reader;
  GstNalUnit nal_unit;
  guint8 forbidden_zero_bit;

  guint8 *data;
  guint size;
  gint i;

  GstFlowReturn ret = GST_FLOW_OK;

  GST_MEMDUMP ("data", GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));

  gst_bit_reader_init_from_buffer (&reader, buf);

  if (gst_bit_reader_get_remaining (&reader) <
      h264_dec->nal_length_size * 8 + 7)
    goto invalid_packet;

  /* skip nal_length or sync code */
  gst_bit_reader_skip_unchecked (&reader, h264_dec->nal_length_size * 8);

  forbidden_zero_bit = gst_bit_reader_get_bits_uint8_unchecked (&reader, 1);

  if (forbidden_zero_bit != 0) {
    GST_WARNING ("forbidden_zero_bit != 0");
    return GST_FLOW_ERROR;
  }

  nal_unit.ref_idc = gst_bit_reader_get_bits_uint16_unchecked (&reader, 2);
  GST_DEBUG ("nal_ref_idc: %u", nal_unit.ref_idc);

  /* read nal_unit_type */
  nal_unit.type = gst_bit_reader_get_bits_uint16_unchecked (&reader, 5);

  GST_DEBUG ("nal_unit_type: %u", nal_unit.type);
  if (nal_unit.type == 14 || nal_unit.type == 20) {
    if (!gst_bit_reader_skip (&reader, 24))
      goto invalid_packet;
  }
  nal_unit.IdrPicFlag = (nal_unit.type == 5 ? 1 : 0);

  data = GST_BUFFER_DATA (buf) + gst_bit_reader_get_pos (&reader) / 8;
  size = gst_bit_reader_get_remaining (&reader) / 8;

  i = size - 1;
  while ((gint) size > 0 && data[i] == 0x00) {
    size--;
    i--;
  }

  if (GST_VIDEO_FRAME_FLAG_IS_SET (frame, GST_H264_FRAME_GOT_PRIMARY)) {
    if (nal_unit.type == GST_NAL_SPS || nal_unit.type == GST_NAL_PPS ||
        nal_unit.type == GST_NAL_SEI || nal_unit.type == GST_NAL_AU_DELIMITER ||
        (nal_unit.type >= 14 && nal_unit.type <= 18))
      ret =
          gst_base_video_decoder_have_frame (base_video_decoder, FALSE, &frame);
  }

  if (nal_unit.type >= GST_NAL_SLICE && nal_unit.type <= GST_NAL_SLICE_IDR) {
    GstH264Slice slice;

    if (!gst_h264_parser_parse_slice_header (h264_dec->parser, &slice, data,
            size, nal_unit))
      goto invalid_packet;

    if (slice.redundant_pic_cnt == 0) {
      if (GST_VIDEO_FRAME_FLAG_IS_SET (frame, GST_H264_FRAME_GOT_PRIMARY)) {
        GstH264Slice *p_slice;
        guint8 pic_order_cnt_type, p_pic_order_cnt_type;
        gboolean finish_frame = FALSE;

        p_slice = &(GST_H264_FRAME_CAST (frame)->slice_hdr);
        pic_order_cnt_type = slice.picture->sequence->pic_order_cnt_type;
        p_pic_order_cnt_type = p_slice->picture->sequence->pic_order_cnt_type;

        if (slice.frame_num != p_slice->frame_num)
          finish_frame = TRUE;

        else if (slice.picture != p_slice->picture)
          finish_frame = TRUE;

        else if (slice.bottom_field_flag != p_slice->bottom_field_flag)
          finish_frame = TRUE;

        else if (nal_unit.ref_idc != p_slice->nal_unit.ref_idc &&
            (nal_unit.ref_idc == 0 || p_slice->nal_unit.ref_idc == 0))
          finish_frame = TRUE;

        else if ((pic_order_cnt_type == 0 && p_pic_order_cnt_type == 0) &&
            (slice.pic_order_cnt_lsb != p_slice->pic_order_cnt_lsb ||
                slice.delta_pic_order_cnt_bottom !=
                p_slice->delta_pic_order_cnt_bottom))
          finish_frame = TRUE;

        else if ((p_pic_order_cnt_type == 1 && p_pic_order_cnt_type == 1) &&
            (slice.delta_pic_order_cnt[0] != p_slice->delta_pic_order_cnt[0] ||
                slice.delta_pic_order_cnt[1] !=
                p_slice->delta_pic_order_cnt[1]))
          finish_frame = TRUE;

        if (finish_frame)
          ret =
              gst_base_video_decoder_have_frame (base_video_decoder, FALSE,
              &frame);

      }

      if (!GST_VIDEO_FRAME_FLAG_IS_SET (frame, GST_H264_FRAME_GOT_PRIMARY)) {
        if (GST_H264_IS_I_SLICE (slice.type)
            || GST_H264_IS_SI_SLICE (slice.type))
          GST_VIDEO_FRAME_FLAG_SET (frame, GST_VIDEO_FRAME_FLAG_KEYFRAME);

        GST_H264_FRAME_CAST (frame)->slice_hdr = slice;
        GST_VIDEO_FRAME_FLAG_SET (frame, GST_H264_FRAME_GOT_PRIMARY);
      }
    }
    gst_h264_frame_add_slice ((GstH264Frame *) frame, buf);
  }

  if (nal_unit.type == GST_NAL_SPS) {
    if (!gst_h264_parser_parse_sequence (h264_dec->parser, data, size))
      goto invalid_packet;
  }

  if (nal_unit.type == GST_NAL_PPS) {
    if (!gst_h264_parser_parse_picture (h264_dec->parser, data, size))
      goto invalid_packet;
  }

  gst_buffer_unref (buf);
  return ret;

invalid_packet:
  GST_WARNING ("Invalid packet size!");
  gst_buffer_unref (buf);

  return GST_FLOW_OK;
}
Пример #5
0
static GstFlowReturn
gst_vdp_mpeg_dec_parse_data (GstBaseVideoDecoder * base_video_decoder,
    GstBuffer * buf, gboolean at_eos, GstVideoFrame * frame)
{
  GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (base_video_decoder);

  GstVdpMpegFrame *mpeg_frame;
  GstFlowReturn ret = GST_FLOW_OK;
  GstBitReader b_reader = GST_BIT_READER_INIT_FROM_BUFFER (buf);
  guint8 start_code;

  if (gst_bit_reader_get_remaining (&b_reader) < 8 * 3 + 8)
    return GST_FLOW_ERROR;

  /* skip sync_code */
  gst_bit_reader_skip_unchecked (&b_reader, 8 * 3);

  /* start_code */
  start_code = gst_bit_reader_get_bits_uint8_unchecked (&b_reader, 8);

  mpeg_frame = GST_VDP_MPEG_FRAME_CAST (frame);

  if (start_code >= MPEG_PACKET_SLICE_MIN
      && start_code <= MPEG_PACKET_SLICE_MAX) {
    GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SLICE");

    gst_vdp_mpeg_frame_add_slice (mpeg_frame, buf);
    goto done;
  }

  switch (start_code) {
    case MPEG_PACKET_SEQUENCE:
      GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SEQUENCE");

      if (mpeg_dec->prev_packet != -1)
        ret = gst_base_video_decoder_have_frame (base_video_decoder, FALSE,
            (GstVideoFrame **) & mpeg_frame);

      mpeg_frame->seq = buf;
      break;

    case MPEG_PACKET_PICTURE:
      GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_PICTURE");

      if (mpeg_dec->prev_packet != MPEG_PACKET_SEQUENCE &&
          mpeg_dec->prev_packet != MPEG_PACKET_GOP)
        ret = gst_base_video_decoder_have_frame (base_video_decoder, FALSE,
            (GstVideoFrame **) & mpeg_frame);

      mpeg_frame->pic = buf;
      break;

    case MPEG_PACKET_GOP:
      GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_GOP");

      if (mpeg_dec->prev_packet != MPEG_PACKET_SEQUENCE)
        ret = gst_base_video_decoder_have_frame (base_video_decoder, FALSE,
            (GstVideoFrame **) & mpeg_frame);

      mpeg_frame->gop = buf;
      break;

    case MPEG_PACKET_EXTENSION:
    {
      guint8 ext_code;

      /* ext_code */
      if (!gst_bit_reader_get_bits_uint8 (&b_reader, &ext_code, 4)) {
        ret = GST_FLOW_ERROR;
        gst_buffer_unref (buf);
        goto done;
      }

      GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXTENSION: %d", ext_code);

      switch (ext_code) {
        case MPEG_PACKET_EXT_SEQUENCE:
          GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_SEQUENCE");


          mpeg_frame->seq_ext = buf;

          /* so that we don't finish the frame if we get a MPEG_PACKET_PICTURE
           * or MPEG_PACKET_GOP after this */
          start_code = MPEG_PACKET_SEQUENCE;
          break;

        case MPEG_PACKET_EXT_SEQUENCE_DISPLAY:
          GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_SEQUENCE_DISPLAY");

          /* so that we don't finish the frame if we get a MPEG_PACKET_PICTURE
           * or MPEG_PACKET_GOP after this */
          start_code = MPEG_PACKET_SEQUENCE;
          break;

        case MPEG_PACKET_EXT_PICTURE_CODING:
          GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_PICTURE_CODING");

          mpeg_frame->pic_ext = buf;
          break;

        case MPEG_PACKET_EXT_QUANT_MATRIX:
          GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_QUANT_MATRIX");

          mpeg_frame->qm_ext = buf;
          break;

        default:
          gst_buffer_unref (buf);
      }
      break;
    }

    default:
      gst_buffer_unref (buf);
  }

  if (at_eos && mpeg_frame->slices)
    ret = gst_base_video_decoder_have_frame (base_video_decoder, TRUE, NULL);

done:
  mpeg_dec->prev_packet = start_code;

  return ret;
}
Пример #6
0
static gboolean
gst_ac3_parse_frame_header_ac3 (GstAc3Parse * ac3parse, GstBuffer * buf,
    gint skip, guint * frame_size, guint * rate, guint * chans, guint * blks,
    guint * sid)
{
  GstBitReader bits;
  GstMapInfo map;
  guint8 fscod, frmsizcod, bsid, acmod, lfe_on, rate_scale;
  gboolean ret = FALSE;

  GST_LOG_OBJECT (ac3parse, "parsing ac3");

  gst_buffer_map (buf, &map, GST_MAP_READ);
  gst_bit_reader_init (&bits, map.data, map.size);
  gst_bit_reader_skip_unchecked (&bits, skip * 8);

  gst_bit_reader_skip_unchecked (&bits, 16 + 16);
  fscod = gst_bit_reader_get_bits_uint8_unchecked (&bits, 2);
  frmsizcod = gst_bit_reader_get_bits_uint8_unchecked (&bits, 6);

  if (G_UNLIKELY (fscod == 3 || frmsizcod >= G_N_ELEMENTS (frmsizcod_table))) {
    GST_DEBUG_OBJECT (ac3parse, "bad fscod=%d frmsizcod=%d", fscod, frmsizcod);
    goto cleanup;
  }

  bsid = gst_bit_reader_get_bits_uint8_unchecked (&bits, 5);
  gst_bit_reader_skip_unchecked (&bits, 3);     /* bsmod */
  acmod = gst_bit_reader_get_bits_uint8_unchecked (&bits, 3);

  /* spec not quite clear here: decoder should decode if less than 8,
   * but seemingly only defines 6 and 8 cases */
  /* Files with 9 and 10 happen, and seem to comply with the <= 8
     format, so let them through. The spec says nothing about 9 and 10 */
  if (bsid > 10) {
    GST_DEBUG_OBJECT (ac3parse, "unexpected bsid=%d", bsid);
    goto cleanup;
  } else if (bsid != 8 && bsid != 6) {
    GST_DEBUG_OBJECT (ac3parse, "undefined bsid=%d", bsid);
  }

  if ((acmod & 0x1) && (acmod != 0x1))  /* 3 front channels */
    gst_bit_reader_skip_unchecked (&bits, 2);
  if ((acmod & 0x4))            /* if a surround channel exists */
    gst_bit_reader_skip_unchecked (&bits, 2);
  if (acmod == 0x2)             /* if in 2/0 mode */
    gst_bit_reader_skip_unchecked (&bits, 2);

  lfe_on = gst_bit_reader_get_bits_uint8_unchecked (&bits, 1);

  /* 6/8->0, 9->1, 10->2,
     see http://matroska.org/technical/specs/codecid/index.html */
  rate_scale = (CLAMP (bsid, 8, 10) - 8);

  if (frame_size)
    *frame_size = frmsizcod_table[frmsizcod].frame_size[fscod] * 2;
  if (rate)
    *rate = fscod_rates[fscod] >> rate_scale;
  if (chans)
    *chans = acmod_chans[acmod] + lfe_on;
  if (blks)
    *blks = 6;
  if (sid)
    *sid = 0;

  ret = TRUE;

cleanup:
  gst_buffer_unmap (buf, &map);

  return ret;
}