uint8_t get_width_height(byte *nal_sps, uint32_t *size_nal_sps, i2ctx_video **ctxVideo) { uint32_t width, height; sps_t* sps = (sps_t*)malloc(sizeof(sps_t)); uint8_t* rbsp_buf = (uint8_t*)malloc(*size_nal_sps); if (nal_to_rbsp(nal_sps, (int*)size_nal_sps, rbsp_buf, (int*)size_nal_sps) < 0){ free(rbsp_buf); free(sps); return I2ERROR_SPS_PPS; } bs_t* b = bs_new(rbsp_buf, *size_nal_sps); if(read_seq_parameter_set_rbsp(sps,b) < 0){ bs_free(b); free(rbsp_buf); free(sps); return I2ERROR_SPS_PPS; } width = (sps->pic_width_in_mbs_minus1 + 1) * 16; height = (2 - sps->frame_mbs_only_flag) * (sps->pic_height_in_map_units_minus1 + 1) * 16; if (sps->frame_cropping_flag){ width -= (sps->frame_crop_left_offset*2 + sps->frame_crop_right_offset*2); height -= (sps->frame_crop_top_offset*2 + sps->frame_crop_bottom_offset*2); } (*ctxVideo)->width = width; (*ctxVideo)->height = height; bs_free(b); free(rbsp_buf); free(sps); return 0; }
static uint8_t * CreateDecodedNAL( int *pi_ret, const uint8_t *src, int i_src ) { uint8_t *dst = malloc( i_src ); if( !dst ) return NULL; *pi_ret = nal_to_rbsp( src, dst, i_src ); return dst; }
//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; }