diff options
author | Maarten Lankhorst <maarten.lankhorst@canonical.com> | 2013-01-07 13:11:26 +0100 |
---|---|---|
committer | Maarten Lankhorst <maarten.lankhorst@canonical.com> | 2013-01-07 13:12:18 +0100 |
commit | d8212519a7440fa137f0a39f9e63b4899318ed67 (patch) | |
tree | 55cc0a9b3517ba7e19c767f4f879a8d42334da92 /vdpow | |
parent | b043c6aaf32c07a92fa43f4816e844239f5615e5 (diff) |
vdpow: add h263 struct fuzzing
Diffstat (limited to 'vdpow')
-rw-r--r-- | vdpow/vdpow.c | 158 |
1 files changed, 156 insertions, 2 deletions
diff --git a/vdpow/vdpow.c b/vdpow/vdpow.c index df0fc7ab..637371a0 100644 --- a/vdpow/vdpow.c +++ b/vdpow/vdpow.c @@ -601,6 +601,154 @@ static void fuzz_mpeg(VdpVideoMixer mix, VdpVideoSurface *surf, VdpOutputSurface vdp_decoder_destroy(dec); } +static void action_h263(VdpDecoder dec, VdpVideoSurface surf, VdpPictureInfoMPEG4Part2 *info, struct snap *ref, +struct fuzz *f, uint32_t oldval, uint32_t newval) +{ + struct snap *cur = f ? calloc(1, sizeof(*cur)) : ref; + VdpStatus ret; + int debug = 1; + char bitstream[0] = {}; + int save = 0, failed_tries = 0; + VdpBitstreamBuffer buffer; + + buffer.struct_version = VDP_BITSTREAM_BUFFER_VERSION; + buffer.bitstream = bitstream; + buffer.bitstream_bytes = sizeof(bitstream); + + if (f) + fprintf(stderr, "Starting %s %u -> %u\n", f->name, oldval, newval); + + if (!debug) { + uint32_t pitches[3] = { input_width, input_width }; + + void *data[3]; + + data[0] = calloc(input_height, input_width); + data[1] = calloc(input_height/2, input_width); + data[2] = NULL; + + do { + if (save) + ok(vdp_video_surface_get_bits_y_cb_cr(surf, VDP_YCBCR_FORMAT_NV12, data, pitches)); + ok(vdp_decoder_render(dec, surf, (void*)info, 1, &buffer)); + } while ((save = save_data(VS_H263, cur)) == -EAGAIN || (save == -EIO && ++failed_tries < 3)); + + ok(vdp_video_surface_get_bits_y_cb_cr(surf, VDP_YCBCR_FORMAT_NV12, data, pitches)); + free(data[0]); + free(data[1]); + + if (save < 0) { + if (!f || oldval == newval) { + // Reference streams shouldn't be failing + assert(!!!"WTF?"); + return; + } + fprintf(stderr, "Failed on %s %u->%u, stream was likely invalid\n", f->name, oldval, newval); +// free((void*)buffer.bitstream); + free(cur); + return; + } + } else + ok(vdp_decoder_render(dec, surf, (void*)info, 1, &buffer)); + +// free((void*)buffer.bitstream); + if (f) { + compare_data(ref, cur, f, oldval, newval); + free(cur); + } +} + +static void fuzz_h263(VdpVideoMixer mix, VdpVideoSurface *surf, VdpOutputSurface *osurf) +{ + VdpPictureInfoMPEG4Part2 info, template[1] = { { } }; + uint32_t i, j; + VdpDecoder dec; + VdpStatus ret; + struct snap *ref = calloc(ARRAY_SIZE(template), sizeof(*ref)); + + for (i = 0; i < ARRAY_SIZE(template); ++i) { + template[i] = (VdpPictureInfoMPEG4Part2){ + .forward_reference = VDP_INVALID_HANDLE, + .backward_reference = VDP_INVALID_HANDLE, + .trd = { 0, 0 }, + .trb = { 0, 0 }, + .vop_time_increment_resolution = 1, + .vop_coding_type = 2, + .vop_fcode_backward = 1, + .vop_fcode_forward = 1, + .resync_marker_disable = 0, + .interlaced = 0, + .quant_type = 0, + .quarter_sample = 0, + .short_video_header = 0, + .rounding_control = 0, + .alternate_vertical_scan_flag = 0, + .top_field_first = 0, + }; + for (j = 0; j < 64; ++j) { + template[i].intra_quantizer_matrix[j] = j; + template[i].non_intra_quantizer_matrix[j] = j; + } + } + + struct fuzz fuzzy[] = { +#define entry(type, rest...) { \ + __builtin_offsetof(VdpPictureInfoMPEG4Part2, type), \ + sizeof(((VdpPictureInfoMPEG4Part2*)NULL)->type), \ + #type, rest \ +} +#define entry_bool(type) entry(type, 0, { 0, 1 }) + + entry(trd[0], 2, { 0, -1 }), + entry(trd[1], 2, { 0, -1 }), + entry(trb[0], 2, { 0, -1 }), + entry(trb[1], 2, { 0, -1 }), + entry(vop_time_increment_resolution, 2, { 1, 0xffff }), + entry(vop_coding_type, 3, { 0, 1, 2 }), + entry(vop_fcode_backward, 2, { 1, 7 }), + entry(vop_fcode_forward, 2, { 1, 7 }), + entry_bool(resync_marker_disable), + entry_bool(interlaced), + entry_bool(quant_type), + entry_bool(quarter_sample), + entry_bool(short_video_header), + entry_bool(rounding_control), + entry_bool(alternate_vertical_scan_flag), + entry_bool(top_field_first), + }; +#undef entry +#undef entry_bool + + ok(vdp_decoder_create(dev, VDP_DECODER_PROFILE_MPEG4_PART2_ASP, input_width, input_height, 2, &dec)); + + clear_data(); + // Render first, then retrieve bits to force serialization + for (i = 0; i < ARRAY_SIZE(template); ++i) + action_h263(dec, surf[0], &template[i], &ref[i], NULL, 0, 0); + + fprintf(stderr, "Reference rendering done\n"); + + for (i = 0; i < ARRAY_SIZE(fuzzy); ++i) { + int oldval = 0, tidx = fuzzy[i].template_idx; + memcpy(&info, &template[tidx], sizeof(template[0])); + memcpy(&oldval, (char*)&template[tidx] + fuzzy[i].offset, fuzzy[i].size_bytes); + if (fuzzy[i].single_values) { + for (j = 0; j < fuzzy[i].single_values; ++j) { + memcpy((char*)&info + fuzzy[i].offset, &fuzzy[i].values[j], fuzzy[i].size_bytes); + action_h263(dec, surf[0], &info, &ref[tidx], &fuzzy[i], oldval, fuzzy[i].values[j]); + } + } else { + for (j = fuzzy[i].values[0]; j <= fuzzy[i].values[1]; ++j) { + memcpy((char*)&info + fuzzy[i].offset, &j, fuzzy[i].size_bytes); + action_h263(dec, surf[0], &info, &ref[tidx], &fuzzy[i], oldval, j); + } + } + } + fprintf(stderr, "Done, destroying renderer\n"); + free(ref); + vdp_decoder_destroy(dec); +} + static void action_h264(VdpDecoder dec, VdpVideoSurface surf, VdpPictureInfoH264 *info, struct snap *ref, struct fuzz *f, uint32_t oldval, uint32_t newval) { @@ -658,7 +806,6 @@ struct fuzz *f, uint32_t oldval, uint32_t newval) } } - static void fuzz_h264(VdpVideoMixer mix, VdpVideoSurface *surf, VdpOutputSurface *osurf) { VdpPictureInfoH264 info, template[1] = { { } }; @@ -739,6 +886,11 @@ static void fuzz_h264(VdpVideoMixer mix, VdpVideoSurface *surf, VdpOutputSurface entry(pic_init_qp_minus26, 2, { 0, -1 }), entry(pic_order_cnt_type, 0, { 0, 2 }), entry(log2_max_pic_order_cnt_lsb_minus4, 2, { 0, 12 }), + + entry(num_ref_idx_l0_active_minus1, 2, { 0, 1 }), + entry(num_ref_idx_l1_active_minus1, 2, { 0, 1 }), + entry(log2_max_frame_num_minus4, 2, { 0, 1 }), + entry_bool(delta_pic_order_always_zero_flag), entry_bool(direct_8x8_inference_flag), entry_bool(entropy_coding_mode_flag), @@ -746,6 +898,8 @@ static void fuzz_h264(VdpVideoMixer mix, VdpVideoSurface *surf, VdpOutputSurface entry_bool(deblocking_filter_control_present_flag), entry_bool(redundant_pic_cnt_present_flag), }; +#undef entry +#undef entry_bool ok(vdp_decoder_create(dev, VDP_DECODER_PROFILE_H264_HIGH, input_width, input_height, 16, &dec)); @@ -777,7 +931,6 @@ static void fuzz_h264(VdpVideoMixer mix, VdpVideoSurface *surf, VdpOutputSurface vdp_decoder_destroy(dec); } - int main(int argc, char *argv[]) { Display *display; Window root, window; @@ -829,6 +982,7 @@ int main(int argc, char *argv[]) { ARRAY_SIZE(mixer_parameters), mixer_parameters, mixer_values, &mixer)); fuzz_mpeg(mixer, surf, osurf); + fuzz_h263(mixer, surf, osurf); fuzz_h264(mixer, surf, osurf); vdp_video_mixer_destroy(mixer); |