From: Jaroslav Kysela Date: Wed, 12 Sep 2018 07:59:01 +0000 (+0200) Subject: parsers: hevc - wait for metadata completion X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2616ec54cf6e6c5222b0335b85b2e704483944d5;p=thirdparty%2Ftvheadend.git parsers: hevc - wait for metadata completion --- diff --git a/src/parsers/parser_hevc.c b/src/parsers/parser_hevc.c index 90e251a81..26c00187e 100644 --- a/src/parsers/parser_hevc.c +++ b/src/parsers/parser_hevc.c @@ -1284,7 +1284,7 @@ static inline int check_height(uint32_t h) return h < 100 || h > 16384; } -void +int hevc_decode_vps(parser_es_t *st, bitstream_t *bs) { hevc_private_t *p; @@ -1295,7 +1295,7 @@ hevc_decode_vps(parser_es_t *st, bitstream_t *bs) 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)); @@ -1304,21 +1304,21 @@ hevc_decode_vps(parser_es_t *st, bitstream_t *bs) 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); @@ -1334,7 +1334,7 @@ hevc_decode_vps(parser_es_t *st, bitstream_t *bs) 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++) @@ -1346,6 +1346,7 @@ hevc_decode_vps(parser_es_t *st, bitstream_t *bs) vps->num_units_in_tick = read_bits(bs, 32); vps->time_scale = read_bits(bs, 32); } + return 0; } static int @@ -1417,7 +1418,7 @@ hevc_decode_vui(hevc_vui_t *vui, bitstream_t *bs) return 0; } -void +int hevc_decode_sps(parser_es_t *st, bitstream_t *bs) { hevc_private_t *p; @@ -1433,7 +1434,7 @@ hevc_decode_sps(parser_es_t *st, bitstream_t *bs) 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)); @@ -1442,21 +1443,21 @@ hevc_decode_sps(parser_es_t *st, bitstream_t *bs) 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); @@ -1466,7 +1467,7 @@ hevc_decode_sps(parser_es_t *st, bitstream_t *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 */ @@ -1478,11 +1479,11 @@ hevc_decode_sps(parser_es_t *st, bitstream_t *bs) 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++) { @@ -1493,16 +1494,16 @@ hevc_decode_sps(parser_es_t *st, bitstream_t *bs) 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 */ @@ -1538,7 +1539,7 @@ hevc_decode_sps(parser_es_t *st, bitstream_t *bs) 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 */ @@ -1548,7 +1549,7 @@ hevc_decode_sps(parser_es_t *st, bitstream_t *bs) 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 */ @@ -1563,7 +1564,7 @@ hevc_decode_sps(parser_es_t *st, bitstream_t *bs) 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); @@ -1575,11 +1576,11 @@ hevc_decode_sps(parser_es_t *st, bitstream_t *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; @@ -1587,16 +1588,17 @@ hevc_decode_sps(parser_es_t *st, bitstream_t *bs) 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; @@ -1604,7 +1606,7 @@ hevc_decode_pps(parser_es_t *st, bitstream_t *bs) 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)); @@ -1613,12 +1615,12 @@ hevc_decode_pps(parser_es_t *st, bitstream_t *bs) 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); @@ -1626,6 +1628,7 @@ hevc_decode_pps(parser_es_t *st, bitstream_t *bs) pps->num_extra_slice_header_bits = read_bits(bs, 3); pps->valid = 1; + return 0; } int diff --git a/src/parsers/parser_hevc.h b/src/parsers/parser_hevc.h index af56f8422..0c73e21bd 100644 --- a/src/parsers/parser_hevc.h +++ b/src/parsers/parser_hevc.h @@ -58,9 +58,9 @@ int isom_write_hvcc(sbuf_t *pb, const uint8_t *src, int size); 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); diff --git a/src/parsers/parsers.c b/src/parsers/parsers.c index 0fcc65734..670614bf2 100644 --- a/src/parsers/parsers.c +++ b/src/parsers/parsers.c @@ -1192,14 +1192,19 @@ drop_trailing_zeroes(const uint8_t *buf, size_t len) * */ 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; } @@ -1269,7 +1274,7 @@ parse_mpeg2video(parser_t *t, parser_es_t *st, size_t 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 */ } @@ -1282,12 +1287,12 @@ parse_mpeg2video(parser_t *t, parser_es_t *st, size_t len, 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; @@ -1344,7 +1349,7 @@ parse_mpeg2video(parser_t *t, parser_es_t *st, size_t len, 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: @@ -1512,9 +1517,9 @@ parse_h264(parser_t *t, parser_es_t *st, size_t len, 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; @@ -1524,8 +1529,7 @@ parse_h264(parser_t *t, parser_es_t *st, size_t len, 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; @@ -1687,9 +1691,9 @@ parse_hevc(parser_t *t, parser_es_t *st, size_t len, 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; @@ -1697,9 +1701,9 @@ parse_hevc(parser_t *t, parser_es_t *st, size_t len, 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; @@ -1707,9 +1711,9 @@ parse_hevc(parser_t *t, parser_es_t *st, size_t len, 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; @@ -1719,7 +1723,7 @@ parse_hevc(parser_t *t, parser_es_t *st, size_t len, 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;