コード例 #1
0
ファイル: avc.c プロジェクト: wmyrda/tvheadend
static int
isom_write_avcc(sbuf_t *sb, const uint8_t *data, int len)
{
  if (len > 6) {
    /* check for h264 start code */
    if (RB32(data) == 0x00000001 ||
	RB24(data) == 0x000001) {
      uint8_t *buf=NULL, *end, *start;
      uint32_t *sps_size_array=0, *pps_size_array=0;
      uint32_t pps_count=0,sps_count=0;
      uint8_t **sps_array=0, **pps_array=0;
      int i;

      int ret = avc_parse_nal_units_buf(data, &buf, &len);
      if (ret < 0)
	return ret;
      start = buf;
      end = buf + len;

      /* look for sps and pps */
      while (buf < end) {
	unsigned int size;
	uint8_t nal_type;
	size = RB32(buf);
	nal_type = buf[4] & 0x1f;
	if (nal_type == 7) { /* SPS */
	  sps_array = realloc(sps_array,sizeof(uint8_t*)*(sps_count+1));
	  sps_size_array = realloc(sps_size_array,sizeof(uint32_t)*(sps_count+1));
	  sps_array[sps_count] = buf + 4;
	  sps_size_array[sps_count] = size;
	  sps_count++;
	} else if (nal_type == 8) { /* PPS */
	  pps_size_array = realloc(pps_size_array,sizeof(uint32_t)*(pps_count+1));
	  pps_array = realloc(pps_array,sizeof (uint8_t*)*(pps_count+1));
	  pps_array[pps_count] = buf + 4;
	  pps_size_array[pps_count] = size;
	  pps_count++;
	}
	buf += size + 4;
      }
      if(!sps_count || !pps_count) {
	free(start);
	if (sps_count)
	  free(sps_array);
	if (pps_count)
	  free(pps_array);
	return -1;
      }

      sbuf_put_byte(sb, 1); /* version */
      sbuf_put_byte(sb, sps_array[0][1]); /* profile */
      sbuf_put_byte(sb, sps_array[0][2]); /* profile compat */
      sbuf_put_byte(sb, sps_array[0][3]); /* level */
      sbuf_put_byte(sb, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 1 (11) */
      sbuf_put_byte(sb, 0xe0+sps_count); /* 3 bits reserved (111) + 5 bits number of sps (00001) */
      for (i=0;i<sps_count;i++) {
	sbuf_put_be16(sb, sps_size_array[i]);
	sbuf_append(sb, sps_array[i], sps_size_array[i]);
      }

      sbuf_put_byte(sb, pps_count); /* number of pps */
      for (i=0;i<pps_count;i++) {
	sbuf_put_be16(sb, pps_size_array[i]);
	sbuf_append(sb, pps_array[i], pps_size_array[i]);
      }
      free(start);

      if (sps_count)
	free(sps_array);
      if (pps_count)
	free(pps_array);
    } else {
      sbuf_append(sb, data, len);
    }
  }
  return 0;
}
コード例 #2
0
ファイル: DVDVideoCodecVDA.cpp プロジェクト: RoboSK/xbmc
const int isom_write_avcc(DllAvUtil *av_util_ctx, DllAvFormat *av_format_ctx,
  ByteIOContext *pb, const uint8_t *data, int len)
{
  // extradata from bytestream h264, convert to avcC atom data for bitstream
  if (len > 6)
  {
    /* check for h264 start code */
    if (VDA_RB32(data) == 0x00000001 || VDA_RB24(data) == 0x000001)
    {
      uint8_t *buf=NULL, *end, *start;
      uint32_t sps_size=0, pps_size=0;
      uint8_t *sps=0, *pps=0;

      int ret = avc_parse_nal_units_buf(av_util_ctx, av_format_ctx, data, &buf, &len);
      if (ret < 0)
        return ret;
      start = buf;
      end = buf + len;

      /* look for sps and pps */
      while (buf < end)
      {
        unsigned int size;
        uint8_t nal_type;
        size = VDA_RB32(buf);
        nal_type = buf[4] & 0x1f;
        if (nal_type == 7) /* SPS */
        {
          sps = buf + 4;
          sps_size = size;
        }
        else if (nal_type == 8) /* PPS */
        {
          pps = buf + 4;
          pps_size = size;
        }
        buf += size + 4;
      }
      assert(sps);

      av_format_ctx->put_byte(pb, 1); /* version */
      av_format_ctx->put_byte(pb, sps[1]); /* profile */
      av_format_ctx->put_byte(pb, sps[2]); /* profile compat */
      av_format_ctx->put_byte(pb, sps[3]); /* level */
      av_format_ctx->put_byte(pb, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 1 (11) */
      av_format_ctx->put_byte(pb, 0xe1); /* 3 bits reserved (111) + 5 bits number of sps (00001) */

      av_format_ctx->put_be16(pb, sps_size);
      av_format_ctx->put_buffer(pb, sps, sps_size);
      if (pps)
      {
        av_format_ctx->put_byte(pb, 1); /* number of pps */
        av_format_ctx->put_be16(pb, pps_size);
        av_format_ctx->put_buffer(pb, pps, pps_size);
      }
      av_util_ctx->av_free(start);
    }
    else
    {
      av_format_ctx->put_buffer(pb, data, len);
    }
  }
  return 0;
}
コード例 #3
0
ファイル: privatedecoder_vda.cpp プロジェクト: stunami/mythtv
const int isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len)
{
    // extradata from bytestream h264, convert to avcC atom data for bitstream
    if (len > 6)
    {
        /* check for h264 start code */
        if (VDA_RB32(data) == 0x00000001 || VDA_RB24(data) == 0x000001)
        {
            uint8_t *buf=NULL, *end, *start;
            uint32_t sps_size=0, pps_size=0;
            uint8_t *sps=0, *pps=0;

            int ret = avc_parse_nal_units_buf(data, &buf, &len);
            if (ret < 0)
                return ret;
            start = buf;
            end = buf + len;

            /* look for sps and pps */
            while (buf < end)
            {
                unsigned int size;
                uint8_t nal_type;
                size = VDA_RB32(buf);
                nal_type = buf[4] & 0x1f;
                if (nal_type == 7) /* SPS */
                {
                    sps = buf + 4;
                    sps_size = size;

                    //parse_sps(sps+1, sps_size-1);
                }
                else if (nal_type == 8) /* PPS */
                {
                    pps = buf + 4;
                    pps_size = size;
                }
                buf += size + 4;
            }
            if (!sps)
            {
                LOG(VB_GENERAL, LOG_ERR, LOC + "Invalid data (sps)");
                return -1;
            }

            avio_w8(pb, 1); /* version */
            avio_w8(pb, sps[1]); /* profile */
            avio_w8(pb, sps[2]); /* profile compat */
            avio_w8(pb, sps[3]); /* level */
            avio_w8(pb, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 1 (11) */
            avio_w8(pb, 0xe1); /* 3 bits reserved (111) + 5 bits number of sps (00001) */

            avio_wb16(pb, sps_size);
            avio_write(pb, sps, sps_size);
            if (pps)
            {
                avio_w8(pb, 1); /* number of pps */
                avio_wb16(pb, pps_size);
                avio_write(pb, pps, pps_size);
            }
            av_free(start);
        }
        else
        {
            avio_write(pb, data, len);
        }
    }
    return 0;
}