-
-
Save i-rinat/286f5d7322e80464d888 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdint.h> | |
#include <time.h> | |
#include <string.h> | |
#include <stdlib.h> | |
extern "C" { | |
#include <libswscale/swscale.h> | |
} | |
#include <libyuv.h> | |
#define WIDTH 1366 | |
#define STRIDE 1376 | |
#define HEIGHT 768 | |
#define FRAMES 8000 | |
void | |
Convert_BGRA_YUV420_SSSE3(unsigned int w, unsigned int h, const uint8_t* in_data, int in_stride, | |
uint8_t* const out_data[3], const int out_stride[3]); | |
uint8_t bgra_buf[STRIDE * HEIGHT * 4]; | |
uint8_t out_y[STRIDE * HEIGHT]; | |
uint8_t out_u[STRIDE * HEIGHT / 4]; | |
uint8_t out_v[STRIDE * HEIGHT / 4]; | |
void | |
prepare_bgra_buf(void) | |
{ | |
memset(bgra_buf, 0, sizeof(bgra_buf)); | |
for (int k = 0; k < HEIGHT; k ++) { | |
for (int j = 0; j < WIDTH; j ++) { | |
bgra_buf[4 * (k * STRIDE + j) + 0] = rand() & 0xff; | |
bgra_buf[4 * (k * STRIDE + j) + 1] = rand() & 0xff; | |
bgra_buf[4 * (k * STRIDE + j) + 2] = rand() & 0xff; | |
bgra_buf[4 * (k * STRIDE + j) + 3] = 0; | |
} | |
} | |
} | |
double | |
elapsed(struct timespec t_start, struct timespec t_end) | |
{ | |
return (t_end.tv_sec - t_start.tv_sec) + 1e-9 * (t_end.tv_nsec - t_start.tv_nsec); | |
}; | |
int | |
main(void) | |
{ | |
printf("benchmarking ssr yuv converter\n"); | |
srand(43); | |
prepare_bgra_buf(); | |
struct timespec t_start, t_end; | |
// ssr's Convert_BGRA_YUV420_SSSE3 | |
clock_gettime(CLOCK_MONOTONIC, &t_start); | |
for (int k = 0; k < FRAMES; k ++) { | |
uint8_t* const out_data[4] = {out_y, out_u, out_v, NULL}; | |
const int out_stride[4] = {STRIDE, STRIDE/2, STRIDE/2, 0}; | |
Convert_BGRA_YUV420_SSSE3(WIDTH, HEIGHT, bgra_buf, STRIDE, out_data, out_stride); | |
} | |
clock_gettime(CLOCK_MONOTONIC, &t_end); | |
printf("ssr %.1f fps\n", FRAMES / elapsed(t_start, t_end)); | |
// libswscale | |
struct SwsContext *sc = NULL; | |
clock_gettime(CLOCK_MONOTONIC, &t_start); | |
for (int k = 0; k < FRAMES; k ++) { | |
uint8_t* const out_data[4] = {out_y, out_u, out_v, NULL}; | |
const int out_stride[4] = {STRIDE, STRIDE/2, STRIDE/2, 0}; | |
sc = sws_getCachedContext(sc, | |
WIDTH, HEIGHT, AV_PIX_FMT_BGRA, | |
WIDTH, HEIGHT, AV_PIX_FMT_YUV420P, | |
SWS_POINT, | |
NULL, NULL, NULL); | |
uint8_t *const srcSlice[4] = {bgra_buf, NULL, NULL, NULL}; | |
const int srcStride[4] = {STRIDE, 0, 0, 0}; | |
sws_scale(sc, srcSlice, srcStride, 0, HEIGHT, out_data, out_stride); | |
} | |
clock_gettime(CLOCK_MONOTONIC, &t_end); | |
printf("swscale %.1f fps\n", FRAMES / elapsed(t_start, t_end)); | |
// libswscale reverse (YUV420P -> BGRA) | |
clock_gettime(CLOCK_MONOTONIC, &t_start); | |
for (int k = 0; k < FRAMES; k ++) { | |
uint8_t* const out_data[4] = {out_y, out_u, out_v, NULL}; | |
const int out_stride[4] = {STRIDE, STRIDE/2, STRIDE/2, 0}; | |
sc = sws_getCachedContext(sc, | |
WIDTH, HEIGHT, AV_PIX_FMT_YUV420P, | |
WIDTH, HEIGHT, AV_PIX_FMT_BGRA, | |
SWS_POINT, | |
NULL, NULL, NULL); | |
uint8_t *const srcSlice[4] = {bgra_buf, NULL, NULL, NULL}; | |
const int srcStride[4] = {STRIDE, 0, 0, 0}; | |
sws_scale(sc, out_data, out_stride, 0, HEIGHT, srcSlice, srcStride); | |
} | |
clock_gettime(CLOCK_MONOTONIC, &t_end); | |
printf("swscale rev %.1f fps\n", FRAMES / elapsed(t_start, t_end)); | |
// libyuv | |
clock_gettime(CLOCK_MONOTONIC, &t_start); | |
for (int k = 0; k < FRAMES; k ++) { | |
uint8_t* const out_data[4] = {out_y, out_u, out_v, NULL}; | |
const int out_stride[4] = {STRIDE, STRIDE/2, STRIDE/2, 0}; | |
uint8_t *const srcSlice[4] = {bgra_buf, NULL, NULL, NULL}; | |
const int srcStride[4] = {STRIDE, 0, 0, 0}; | |
libyuv::BGRAToI420(bgra_buf, STRIDE * 4, | |
out_y, STRIDE, | |
out_v, STRIDE/2, | |
out_u, STRIDE/2, | |
WIDTH, HEIGHT); | |
} | |
clock_gettime(CLOCK_MONOTONIC, &t_end); | |
printf("libyuv %.1f fps\n", FRAMES / elapsed(t_start, t_end)); | |
printf("done\n"); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment