Пример #1
0
int write_avcc(avcc_t* avcc, h264_stream_t* h, bs_t* b)
{
  bs_write_u8(b, 1); // configurationVersion = 1;
  bs_write_u8(b, avcc->AVCProfileIndication);
  bs_write_u8(b, avcc->profile_compatibility);
  bs_write_u8(b, avcc->AVCLevelIndication);
  bs_write_u(b, 6, 0x3F); // reserved = '111111'b;
  bs_write_u(b, 2, avcc->lengthSizeMinusOne);
  bs_write_u(b, 3, 0x07); // reserved = '111'b;

  bs_write_u(b, 5, avcc->numOfSequenceParameterSets);
  int i;
  for (i = 0; i < avcc->numOfSequenceParameterSets; i++)
  {
    int max_len = 1024; // FIXME
    uint8_t* buf = (uint8_t*)malloc(max_len);
    h->nal->nal_ref_idc = 3; // NAL_REF_IDC_PRIORITY_HIGHEST;
    h->nal->nal_unit_type = NAL_UNIT_TYPE_SPS;
    h->sps = avcc->sps_table[i];
    int len = write_nal_unit(h, buf, max_len);
    if (len < 0) { free(buf); continue; } // TODO report errors
    int sequenceParameterSetLength = len;
    bs_write_u(b, 16, sequenceParameterSetLength);
    bs_write_bytes(b, buf, len);
    free(buf);
  }

  bs_write_u(b, 8, avcc->numOfPictureParameterSets);
  for (i = 0; i < avcc->numOfPictureParameterSets; i++)
  {
    int max_len = 1024; // FIXME
    uint8_t* buf = (uint8_t*)malloc(max_len);
    h->nal->nal_ref_idc = 3; // NAL_REF_IDC_PRIORITY_HIGHEST;
    h->nal->nal_unit_type = NAL_UNIT_TYPE_PPS;
    h->pps = avcc->pps_table[i];
    int len = write_nal_unit(h, buf, max_len);
    if (len < 0) { free(buf); continue; } // TODO report errors
    int pictureParameterSetLength = len;
    bs_write_u(b, 16, pictureParameterSetLength);
    bs_write_bytes(b, buf, len);
    free(buf);
  }

  if (bs_overrun(b)) { return -1; }
  return bs_pos(b);
}
Пример #2
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);
}
Пример #3
0
//7.3.1 NAL unit syntax
int structure(nal_unit)(h264_stream_t* h, uint8_t* buf, int size)
{
    nal_t* nal = h->nal;

    int nal_size = size;
    int rbsp_size = size;
    uint8_t* rbsp_buf = (uint8_t*)calloc(1, rbsp_size);

    if( is_reading )
    {
        int rc = nal_to_rbsp(buf, &nal_size, rbsp_buf, &rbsp_size);

        if (rc < 0) {
            free(rbsp_buf);    // handle conversion error
            return -1;
        }
    }

    if( is_writing )
    {
        rbsp_size = size*3/4; // NOTE this may have to be slightly smaller (3/4 smaller, worst case) in order to be guaranteed to fit
    }

    bs_t* b = bs_new(rbsp_buf, rbsp_size);
    value( forbidden_zero_bit, f(1, 0) );
    value( nal->nal_ref_idc, u(2) );
    value( nal->nal_unit_type, u(5) );

    switch ( nal->nal_unit_type )
    {
    case NAL_UNIT_TYPE_CODED_SLICE_IDR:
    case NAL_UNIT_TYPE_CODED_SLICE_NON_IDR:
    case NAL_UNIT_TYPE_CODED_SLICE_AUX:
        structure(slice_layer_rbsp)(h, b);
        break;

#ifdef HAVE_SEI
    case NAL_UNIT_TYPE_SEI:
        structure(sei_rbsp)(h, b);
        break;
#endif

    case NAL_UNIT_TYPE_SPS:
        structure(seq_parameter_set_rbsp)(h, b);
        break;

    case NAL_UNIT_TYPE_PPS:
        structure(pic_parameter_set_rbsp)(h, b);
        break;

    case NAL_UNIT_TYPE_AUD:
        structure(access_unit_delimiter_rbsp)(h, b);
        break;

    case NAL_UNIT_TYPE_END_OF_SEQUENCE:
        structure(end_of_seq_rbsp)(h, b);
        break;

    case NAL_UNIT_TYPE_END_OF_STREAM:
        structure(end_of_stream_rbsp)(h, b);
        break;

    case NAL_UNIT_TYPE_FILLER:
    case NAL_UNIT_TYPE_SPS_EXT:
    case NAL_UNIT_TYPE_UNSPECIFIED:
    case NAL_UNIT_TYPE_CODED_SLICE_DATA_PARTITION_A:
    case NAL_UNIT_TYPE_CODED_SLICE_DATA_PARTITION_B:
    case NAL_UNIT_TYPE_CODED_SLICE_DATA_PARTITION_C:
    default:
        return -1;
    }

    if (bs_overrun(b)) {
        bs_free(b);
        free(rbsp_buf);
        return -1;
    }

    if( is_writing )
    {
        // now get the actual size used
        rbsp_size = bs_pos(b);

        int rc = rbsp_to_nal(rbsp_buf, &rbsp_size, buf, &nal_size);
        if (rc < 0) {
            bs_free(b);
            free(rbsp_buf);
            return -1;
        }
    }

    bs_free(b);
    free(rbsp_buf);

    return nal_size;
}