return h < 100 || h > 16384;
}
-void
+int
hevc_decode_vps(parser_es_t *st, bitstream_t *bs)
{
hevc_private_t *p;
uint32_t u, v;
if (read_bits1(bs)) /* zero bit */
- return ;
+ return -1;
if((p = st->es_priv) == NULL)
p = st->es_priv = calloc(1, sizeof(hevc_private_t));
vps_id = read_bits(bs, 4);
if (vps_id >= MAX_VPS_COUNT)
- return;
+ return -1;
vps = &p->vps[vps_id];
if (read_bits(bs, 2) != 3) /* vps_reserved_three_2bits */
- return;
+ return -1;
skip_bits(bs, 6); /* vps_max_sublayers */
max_sub_layers = read_bits(bs, 3) + 1;
skip_bits1(bs); /* vps_temporal_id_nesting */
if (read_bits(bs, 16) != 0xffff) /* reserved */
- return;
+ return -1;
if (max_sub_layers > MAX_SUB_LAYERS)
- return;
+ return -1;
hvcc_parse_ptl(bs, NULL, max_sub_layers);
num_layer_sets = read_golomb_ue(bs) + 1;
if (num_layer_sets < 1 || num_layer_sets > 1024 ||
(num_layer_sets - 1LL) * (max_layer_id + 1LL) > remaining_bits(bs))
- return;
+ return -1;
for (u = 1; u < num_layer_sets; u++)
for (v = 0; v < max_layer_id; v++)
vps->num_units_in_tick = read_bits(bs, 32);
vps->time_scale = read_bits(bs, 32);
}
+ return 0;
}
static int
return 0;
}
-void
+int
hevc_decode_sps(parser_es_t *st, bitstream_t *bs)
{
hevc_private_t *p;
uint32_t log2_ctb_size, nb_st_rps;
if (read_bits1(bs)) /* zero bit */
- return;
+ return -1;
if((p = st->es_priv) == NULL)
p = st->es_priv = calloc(1, sizeof(hevc_private_t));
vps_id = read_bits(bs, 4);
if (vps_id >= MAX_VPS_COUNT)
- return;
+ return -1;
vps = &p->vps[vps_id];
if (!vps->valid)
- return;
+ return -1;
max_sub_layers = read_bits(bs, 3) + 1;
if (max_sub_layers > MAX_SUB_LAYERS)
- return;
+ return -1;
skip_bits1(bs); /* temporal_id_nesting */
hvcc_parse_ptl(bs, NULL, max_sub_layers);
sps_id = read_golomb_ue(bs);
if (sps_id >= MAX_SPS_COUNT)
- return;
+ return -1;
sps = &p->sps[sps_id];
chroma_format_idc = read_golomb_ue(bs);
width = read_golomb_ue(bs);
height = read_golomb_ue(bs);
if (check_width(width) || check_height(height))
- return;
+ return -1;
if (read_bits1(bs)) { /* pic_conformance */
read_golomb_ue(bs); /* left_offset */
bit_depth = read_golomb_ue(bs);
bit_depth_chroma = read_golomb_ue(bs);
if (chroma_format_idc && bit_depth_chroma != bit_depth)
- return;
+ return -1;
log2_max_poc_lsb = read_golomb_ue(bs) + 4;
if (log2_max_poc_lsb > 16)
- return;
+ return -1;
u = read_bits1(bs); /* sublayer_ordering_info */
for (u = u ? 0 : max_sub_layers - 1; u < max_sub_layers; u++) {
log2_min_cb_size = read_golomb_ue(bs) + 3;
if (log2_min_cb_size < 3 || log2_min_cb_size > 30)
- return;
+ return -1;
log2_diff_max_min_coding_block_size = read_golomb_ue(bs);
if (log2_diff_max_min_coding_block_size > 30)
- return;
+ return -1;
log2_min_tb_size = read_golomb_ue(bs) + 2;
if (log2_min_tb_size >= log2_min_cb_size || log2_min_tb_size < 2)
- return;
+ return -1;
log2_diff_max_min_transform_block_size = read_golomb_ue(bs);
if (log2_diff_max_min_transform_block_size > 30)
- return;
+ return -1;
read_golomb_ue(bs); /* max_transform_hierarchy_depth_inter */
read_golomb_ue(bs); /* max_transform_hierarchy_depth_intra */
nb_st_rps = read_golomb_ue(bs);
if (nb_st_rps > MAX_SHORT_TERM_RPS_COUNT)
- return;
+ return -1;
for (u = 0; u < nb_st_rps; u++) {
if (u > 0 && read_bits1(bs)) { /* rps_predict */
u = read_golomb_ue(bs); /* rps->num_negative_pics */
v = read_golomb_ue(bs); /* nb_positive_pics */
if (u > MAX_REFS || v > MAX_REFS)
- return;
+ return -1;
for (i = 0; i < u; i++) {
read_golomb_ue(bs); /* delta_poc */
skip_bits1(bs); /* used */
if (read_bits1(bs)) { /* long_term_ref_pics_present */
u = read_golomb_ue(bs); /* num_long_term_ref_pics_sps */
if (u > 31)
- return;
+ return -1;
for (i = 0; i < u; i++) {
skip_bits(bs, log2_max_poc_lsb);
skip_bits1(bs);
if (read_bits1(bs)) /* vui_present */
if (hevc_decode_vui(&sps->vui, bs))
- return;
+ return -1;
if (!vps->num_units_in_tick && !vps->time_scale &&
!sps->vui.num_units_in_tick && !sps->vui.time_scale)
- return;
+ return -1;
sps->width = width;
sps->height = height;
log2_ctb_size = log2_min_cb_size +
log2_diff_max_min_coding_block_size;
if (log2_ctb_size > 18)
- return;
+ return -1;
sps->ctb_width = (width + (1 << log2_ctb_size) - 1) >> log2_ctb_size;
sps->ctb_height = (height + (1 << log2_ctb_size) - 1) >> log2_ctb_size;
sps->vps_id = vps_id;
sps->valid = 1;
+ return -1;
}
-void
+int
hevc_decode_pps(parser_es_t *st, bitstream_t *bs)
{
hevc_private_t *p;
uint32_t pps_id, sps_id;
if (read_bits1(bs)) /* zero bit */
- return ;
+ return -1;
if((p = st->es_priv) == NULL)
p = st->es_priv = calloc(1, sizeof(hevc_private_t));
pps_id = read_golomb_ue(bs);
if (pps_id >= MAX_PPS_COUNT)
- return;
+ return -1;
pps = &p->pps[pps_id];
sps_id = read_golomb_ue(bs);
if (sps_id >= MAX_SPS_COUNT || !p->sps[sps_id].valid)
- return;
+ return -1;
pps->sps_id = sps_id;
pps->dependent_slice_segments = read_bits1(bs);
pps->num_extra_slice_header_bits = read_bits(bs, 3);
pps->valid = 1;
+ return 0;
}
int
th_pkt_t * hevc_convert_pkt(th_pkt_t *src);
-void hevc_decode_vps(parser_es_t *st, bitstream_t *bs);
-void hevc_decode_sps(parser_es_t *st, bitstream_t *bs);
-void hevc_decode_pps(parser_es_t *st, bitstream_t *bs);
+int hevc_decode_vps(parser_es_t *st, bitstream_t *bs);
+int hevc_decode_sps(parser_es_t *st, bitstream_t *bs);
+int hevc_decode_pps(parser_es_t *st, bitstream_t *bs);
int hevc_decode_slice_header(parser_es_t *st, bitstream_t *bs, int *pkttype);
*
*/
static void
-parser_global_data_move(parser_es_t *st, const uint8_t *data, size_t len)
+parser_global_data_move(parser_es_t *st, const uint8_t *data, size_t len, int reset)
{
- int len2 = drop_trailing_zeroes(data, len);
-
- st->es_global_data = realloc(st->es_global_data,
- st->es_global_data_len + len2);
- memcpy(st->es_global_data + st->es_global_data_len, data, len2);
- st->es_global_data_len += len2;
+ if (reset) {
+ free(st->es_global_data);
+ st->es_global_data = NULL;
+ st->es_global_data_len = 0;
+ } else {
+ int len2 = drop_trailing_zeroes(data, len);
+ st->es_global_data = realloc(st->es_global_data,
+ st->es_global_data_len + len2);
+ memcpy(st->es_global_data + st->es_global_data_len, data, len2);
+ st->es_global_data_len += len2;
+ }
st->es_buf.sb_ptr -= len;
}
if(!st->es_buf.sb_err) {
if(parse_mpeg2video_seq_start(t, st, &bs) != PARSER_APPEND)
return PARSER_RESET;
- parser_global_data_move(st, buf, len);
+ parser_global_data_move(st, buf, len, 0);
if (!st->es_priv)
st->es_priv = malloc(1); /* starting mark */
}
case 0x1:
// Sequence Extension
if(!st->es_buf.sb_err)
- parser_global_data_move(st, buf, len);
+ parser_global_data_move(st, buf, len, 0);
return PARSER_DROP;
case 0x2:
// Sequence Display Extension
if(!st->es_buf.sb_err)
- parser_global_data_move(st, buf, len);
+ parser_global_data_move(st, buf, len, 0);
return PARSER_DROP;
}
break;
case 0xb8:
// GOP header
if(!st->es_buf.sb_err)
- parser_global_data_move(st, buf, len);
+ parser_global_data_move(st, buf, len, 0);
return PARSER_DROP;
case 0xb2:
case H264_NAL_SPS:
if(!st->es_buf.sb_err) {
void *f = h264_nal_deescape(&bs, buf + 4, len - 4);
- h264_decode_seq_parameter_set(st, &bs);
+ int r = h264_decode_seq_parameter_set(st, &bs);
free(f);
- parser_global_data_move(st, buf, len);
+ parser_global_data_move(st, buf, len, r);
}
ret = PARSER_DROP;
break;
void *f = h264_nal_deescape(&bs, buf + 4, len - 4);
int r = h264_decode_pic_parameter_set(st, &bs);
free(f);
- if (r == 0)
- parser_global_data_move(st, buf, len);
+ parser_global_data_move(st, buf, len, r);
}
ret = PARSER_DROP;
break;
case HEVC_NAL_VPS:
if(!st->es_buf.sb_err) {
void *f = h264_nal_deescape(&bs, buf + 3, len - 3);
- hevc_decode_vps(st, &bs);
+ int r = hevc_decode_vps(st, &bs);
free(f);
- parser_global_data_move(st, buf, len);
+ parser_global_data_move(st, buf, len, r);
}
ret = PARSER_DROP;
break;
case HEVC_NAL_SPS:
if(!st->es_buf.sb_err) {
void *f = h264_nal_deescape(&bs, buf + 3, len - 3);
- hevc_decode_sps(st, &bs);
+ int r = hevc_decode_sps(st, &bs);
free(f);
- parser_global_data_move(st, buf, len);
+ parser_global_data_move(st, buf, len, r);
}
ret = PARSER_DROP;
break;
case HEVC_NAL_PPS:
if(!st->es_buf.sb_err) {
void *f = h264_nal_deescape(&bs, buf + 3, len - 3);
- hevc_decode_pps(st, &bs);
+ int r = hevc_decode_pps(st, &bs);
free(f);
- parser_global_data_move(st, buf, len);
+ parser_global_data_move(st, buf, len, r);
}
ret = PARSER_DROP;
break;
case HEVC_NAL_SEI_SUFFIX:
if(!st->es_buf.sb_err) {
/* FIXME: only declarative messages */
- parser_global_data_move(st, buf, len);
+ parser_global_data_move(st, buf, len, 0);
}
ret = PARSER_DROP;
break;