mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-01-13 10:55:34 +00:00
tests: make pack/unpack test
Make a more complete pack/unpack test, check if the image after pack/unpack has the same color and precision, and has correctly duplicated subsampled pixels.
This commit is contained in:
parent
4ab5a29e46
commit
64c1303dd0
1 changed files with 202 additions and 1 deletions
|
@ -1697,6 +1697,207 @@ GST_START_TEST (test_overlay_composition_global_alpha)
|
|||
|
||||
GST_END_TEST;
|
||||
|
||||
static guint8 *
|
||||
make_pixels (gint depth, gint width, gint height)
|
||||
{
|
||||
guint32 color = 0xff000000;
|
||||
gint i, j;
|
||||
|
||||
if (depth == 8) {
|
||||
guint8 *pixels = g_malloc (width * height * 4);
|
||||
for (i = 0; i < height; i++) {
|
||||
for (j = 0; j < width; j++) {
|
||||
pixels[(i * width + j) * 4 + 0] = ((color >> 24) & 0xff);
|
||||
pixels[(i * width + j) * 4 + 1] = ((color >> 16) & 0xff);
|
||||
pixels[(i * width + j) * 4 + 2] = ((color >> 8) & 0xff);
|
||||
pixels[(i * width + j) * 4 + 3] = (color & 0xff);
|
||||
color++;
|
||||
}
|
||||
}
|
||||
return pixels;
|
||||
} else {
|
||||
#define TO16(a) (((a)<<8)|(a))
|
||||
guint16 *pixels = g_malloc (width * height * 8);
|
||||
for (i = 0; i < height; i++) {
|
||||
for (j = 0; j < width; j++) {
|
||||
pixels[(i * width + j) * 4 + 0] = TO16 ((color >> 24) & 0xff);
|
||||
pixels[(i * width + j) * 4 + 1] = TO16 ((color >> 16) & 0xff);
|
||||
pixels[(i * width + j) * 4 + 2] = TO16 ((color >> 8) & 0xff);
|
||||
pixels[(i * width + j) * 4 + 3] = TO16 (color & 0xff);
|
||||
color++;
|
||||
}
|
||||
}
|
||||
#undef TO16
|
||||
return (guint8 *) pixels;
|
||||
}
|
||||
}
|
||||
|
||||
#define HS(x,o) ((x)&hs[o])
|
||||
#define WS(x,o) ((x)&ws[o])
|
||||
#define IN(i,j,o) (in[(HS(i, o)*width + WS(j,o))*4+(o)] & mask[o])
|
||||
#define OUT(i,j,o) (out[((i)*width + (j))*4+o] & mask[o])
|
||||
static gint
|
||||
compare_frame (const GstVideoFormatInfo * finfo, gint depth, guint8 * outpixels,
|
||||
guint8 * pixels, gint width, gint height)
|
||||
{
|
||||
gint diff, i, j, k;
|
||||
guint ws[4], hs[4], mask[4];
|
||||
|
||||
for (k = 0; k < 4; k++) {
|
||||
hs[k] = G_MAXUINT << finfo->h_sub[(3 + k) % 4];
|
||||
ws[k] = G_MAXUINT << finfo->w_sub[(3 + k) % 4];
|
||||
mask[k] = G_MAXUINT << (depth - finfo->depth[(3 + k) % 4]);
|
||||
}
|
||||
diff = 0;
|
||||
if (depth == 8) {
|
||||
guint8 *in = pixels;
|
||||
guint8 *out = outpixels;
|
||||
|
||||
for (i = 0; i < height; i++) {
|
||||
for (j = 0; j < width; j++) {
|
||||
for (k = 0; k < 4; k++) {
|
||||
diff += IN (i, j, k) != OUT (i, j, k);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
guint16 *in = (guint16 *) pixels;
|
||||
guint16 *out = (guint16 *) outpixels;
|
||||
|
||||
for (i = 0; i < height; i++) {
|
||||
for (j = 0; j < width; j++) {
|
||||
for (k = 0; k < 4; k++) {
|
||||
diff += IN (i, j, k) != OUT (i, j, k);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
|
||||
#undef WS
|
||||
#undef HS
|
||||
#undef IN
|
||||
#undef OUT
|
||||
|
||||
#define UNPACK_FRAME(frame,dest,line,x,width) \
|
||||
(frame)->info.finfo->unpack_func ((frame)->info.finfo, \
|
||||
(GST_VIDEO_FRAME_IS_INTERLACED (frame) ? \
|
||||
GST_VIDEO_PACK_FLAG_INTERLACED : \
|
||||
GST_VIDEO_PACK_FLAG_NONE), \
|
||||
dest, (frame)->data, (frame)->info.stride, x, \
|
||||
line, width)
|
||||
#define PACK_FRAME(frame,src,line,width) \
|
||||
(frame)->info.finfo->pack_func ((frame)->info.finfo, \
|
||||
(GST_VIDEO_FRAME_IS_INTERLACED (frame) ? \
|
||||
GST_VIDEO_PACK_FLAG_INTERLACED : \
|
||||
GST_VIDEO_PACK_FLAG_NONE), \
|
||||
src, 0, (frame)->data, (frame)->info.stride, \
|
||||
(frame)->info.chroma_site, line, width);
|
||||
|
||||
GST_START_TEST (test_video_pack_unpack2)
|
||||
{
|
||||
GstVideoFormat format;
|
||||
GTimer *timer;
|
||||
gint num_formats;
|
||||
|
||||
#define WIDTH 1920
|
||||
#define HEIGHT 1080
|
||||
/* set to something larger to do benchmarks */
|
||||
#define TIME 0.0
|
||||
|
||||
timer = g_timer_new ();
|
||||
|
||||
num_formats = get_num_formats ();
|
||||
|
||||
GST_DEBUG ("pack/sec\t unpack/sec \tpack GB/sec\tunpack GB/sec\tformat");
|
||||
|
||||
for (format = GST_VIDEO_FORMAT_I420; format < num_formats; format++) {
|
||||
GstVideoInfo info;
|
||||
const GstVideoFormatInfo *finfo, *fuinfo;
|
||||
GstBuffer *buffer;
|
||||
GstVideoFrame frame;
|
||||
gint k, stride, count, diff, depth;
|
||||
guint8 *pixels, *outpixels;
|
||||
gdouble elapsed;
|
||||
gdouble unpack_sec, pack_sec;
|
||||
|
||||
finfo = gst_video_format_get_info (format);
|
||||
fail_unless (finfo != NULL);
|
||||
|
||||
if (GST_VIDEO_FORMAT_INFO_HAS_PALETTE (finfo))
|
||||
continue;
|
||||
|
||||
fuinfo = gst_video_format_get_info (finfo->unpack_format);
|
||||
fail_unless (fuinfo != NULL);
|
||||
|
||||
depth = GST_VIDEO_FORMAT_INFO_BITS (fuinfo);
|
||||
fail_unless (depth == 8 || depth == 16);
|
||||
|
||||
pixels = make_pixels (depth, WIDTH, HEIGHT);
|
||||
stride = WIDTH * (depth >> 1);
|
||||
|
||||
gst_video_info_set_format (&info, format, WIDTH, HEIGHT);
|
||||
buffer = gst_buffer_new_and_alloc (info.size);
|
||||
gst_video_frame_map (&frame, &info, buffer, GST_MAP_READWRITE);
|
||||
|
||||
/* pack the frame into the target format */
|
||||
/* warmup */
|
||||
PACK_FRAME (&frame, pixels, 0, WIDTH);
|
||||
|
||||
count = 0;
|
||||
g_timer_start (timer);
|
||||
while (TRUE) {
|
||||
for (k = 0; k < HEIGHT; k += finfo->pack_lines) {
|
||||
PACK_FRAME (&frame, pixels + k * stride, k, WIDTH);
|
||||
}
|
||||
count++;
|
||||
elapsed = g_timer_elapsed (timer, NULL);
|
||||
if (elapsed >= TIME)
|
||||
break;
|
||||
}
|
||||
unpack_sec = count / elapsed;
|
||||
|
||||
outpixels = g_malloc0 (HEIGHT * stride);
|
||||
|
||||
/* unpack the frame */
|
||||
/* warmup */
|
||||
UNPACK_FRAME (&frame, outpixels, 0, 0, WIDTH);
|
||||
|
||||
count = 0;
|
||||
g_timer_start (timer);
|
||||
while (TRUE) {
|
||||
for (k = 0; k < HEIGHT; k += finfo->pack_lines) {
|
||||
UNPACK_FRAME (&frame, outpixels + k * stride, k, 0, WIDTH);
|
||||
}
|
||||
count++;
|
||||
elapsed = g_timer_elapsed (timer, NULL);
|
||||
if (elapsed >= TIME)
|
||||
break;
|
||||
}
|
||||
pack_sec = count / elapsed;
|
||||
|
||||
/* compare the frame */
|
||||
diff = compare_frame (finfo, depth, outpixels, pixels, WIDTH, HEIGHT);
|
||||
|
||||
GST_DEBUG ("%f \t %f \t %f \t %f \t %s", pack_sec, unpack_sec,
|
||||
info.size * pack_sec, info.size * unpack_sec, finfo->name);
|
||||
|
||||
if (diff != 0) {
|
||||
gst_util_dump_mem (outpixels, 128);
|
||||
gst_util_dump_mem (pixels, 128);
|
||||
fail_if (diff != 0);
|
||||
}
|
||||
gst_video_frame_unmap (&frame);
|
||||
gst_buffer_unref (buffer);
|
||||
g_free (pixels);
|
||||
g_free (outpixels);
|
||||
}
|
||||
g_timer_destroy (timer);
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
||||
GST_START_TEST (test_video_scaler)
|
||||
{
|
||||
GstVideoScaler *scale;
|
||||
|
@ -1708,7 +1909,6 @@ GST_START_TEST (test_video_scaler)
|
|||
scale = gst_video_scaler_new (GST_VIDEO_RESAMPLER_METHOD_LINEAR,
|
||||
GST_VIDEO_SCALER_FLAG_NONE, 2, 15, 5, NULL);
|
||||
gst_video_scaler_free (scale);
|
||||
|
||||
}
|
||||
|
||||
GST_END_TEST;
|
||||
|
@ -1734,6 +1934,7 @@ video_suite (void)
|
|||
tcase_add_test (tc_chain, test_overlay_composition);
|
||||
tcase_add_test (tc_chain, test_overlay_composition_premultiplied_alpha);
|
||||
tcase_add_test (tc_chain, test_overlay_composition_global_alpha);
|
||||
tcase_add_test (tc_chain, test_video_pack_unpack2);
|
||||
tcase_add_test (tc_chain, test_video_scaler);
|
||||
|
||||
return s;
|
||||
|
|
Loading…
Reference in a new issue