[FFmpeg-devel] Why not integrate libyuv as a scale filter

Jeff 163jogh at 163.com
Sat Jul 28 14:34:45 EEST 2018


Hi Carl,


Sorry for late reply.


I make a simple test on my MacBook Pro (13-inch, 2016, 2 GHz Intel Core i5, 8 GB 1867 MHz LPDDR3). 
I read a 1088x1920 BGR24 frame from local disk, and then scale it to 480x854-YUV420P 500 
times respectively by libswscale & libyuv. The result shows that libswscale take about 4.19
seconds while libyuv just take about 0.93 seconds. Which means libyuv is about 4~5 times
faster than the libswscale on my test. Is that say something?


The following is my test code



staticint swsTest()

{

    int rgbW = 1088;

    int rgbH = 1920;

    int rgbStride[4] = {rgbW * 3, 0, 0, 0};

    uint8_t *rgbBuf = (uint8_t *) av_malloc(rgbW*rgbH*4);

    uint8_t  *rgb[4] = {rgbBuf, 0, 0, 0};

    enumAVPixelFormat rgbFormat = AV_PIX_FMT_BGR24;




    FILE* rgbfp = fopen("~/repo/fftest/video.rgb", "rb");

    if (!rgbfp) {

        printf("fopen error\n");

    }

    FILE* yuvfp = fopen("~/repo/fftest/video.420p.yuv", "wb");

    if (!yuvfp) {

        printf("fopen error\n");

    }




    int rbyte = (int)fread(rgbBuf, 1, rgbW * rgbH * 3, rgbfp);

    if (rbyte < rgbW*rgbH*3) {

        printf("fread error\n");

    }




    int yuvW = 1088;

    int yuvH = 1920;

    int yuvStride[4] = {yuvW, yuvW/2, yuvW/2, 0};

    uint8_t *yuvBuf = (uint8_t *) av_malloc(yuvW * yuvH * 4);

    uint8_t *yuv[4] = {

        yuvBuf,

        yuvBuf + yuvW * yuvH,

        yuvBuf + yuvW * yuvH * 5 / 4,

        0};

    enumAVPixelFormatyuvFormat = AV_PIX_FMT_YUV420P;







    int scaleW = 480;

    int scaleH = 854;

    int scaleStride[4] = {scaleW, scaleW/2, scaleW/2, 0};

    uint8_t *scaleBuf = (uint8_t *) av_malloc(scaleW * scaleH * 4);

    uint8_t *scale[4] = {

        scaleBuf,

        scaleBuf + scaleW * scaleH,

        scaleBuf + scaleW * scaleH * 5 / 4,

        0};

    enumAVPixelFormat scaleFormat = AV_PIX_FMT_YUV420P;




    SwsContext *scaleContext = sws_getContext(rgbW, rgbH, rgbFormat,

                                              scaleW, scaleH, scaleFormat,

                                              SWS_BILINEAR, NULL, NULL, NULL);

    if (!scaleContext) {

        fprintf(stderr, "Failed to get rgb24 ---> yuv420p\n");

    }




    int64_t sws_start = av_gettime();

    for (int i=0; i<500; i++) {

        sws_scale(scaleContext, rgb, rgbStride, 0, rgbH, scale, scaleStride);

    }

    int64_t sws_end = av_gettime();




    int64_t libyuv_start = av_gettime();

    for (int i=0; i<500; i++) {

        libyuv::RGB24ToI420(rgb[0],     rgbStride[0],

                            yuv[0],     yuvStride[0],

                            yuv[1],     yuvStride[1],

                            yuv[2],     yuvStride[2],

                            rgbW,       rgbH

                            );




        libyuv::I420Scale(yuv[0],   yuvStride[0],

                          yuv[1],   yuvStride[1],

                          yuv[2],   yuvStride[2],

                          yuvW,     yuvH,

                          scale[0], scaleStride[0],

                          scale[1], scaleStride[1],

                          scale[2], scaleStride[2],

                          scaleW,   scaleH,

                          libyuv::kFilterBilinear);

    }

    int64_t libyuv_end = av_gettime();




    printf("sws = %"PRId64", libyuv = %"PRId64"\n", sws_end - sws_start, libyuv_end - libyuv_start);

    int wbyte = (int)fwrite(scaleBuf, 1, scaleW * scaleH * 3 / 2, yuvfp);

    if (wbyte < scaleW * scaleH * 3 / 2) {

        printf("friter %d error\n", wbyte);

    }




    sws_freeContext(scaleContext);

    fclose(rgbfp);

    av_freep(&rgbBuf);

    av_freep(&yuvBuf);

    av_freep(&scaleBuf);




    return0;

}



The following is my FFMPEG configurations



ffmpeg version 3.1.7 (w-c103674) Copyright (c) 2000-2017 the FFmpeg developers

  built with Apple LLVM version 9.1.0 (clang-902.0.39.2)

  configuration: --prefix=/Users/jianfeng15/weibo/trans/weibo-ffmpeg/target --pkg-config-flags=--static --disable-everything --disable-audiotoolbox --disable-videotoolbox --disable-videotoolbox_hwaccel --disable-securetransport --disable-vda --enable-gpl --enable-nonfree --disable-bzlib --enable-static --enable-libfdk-aac --disable-stripping --enable-ffmpeg --disable-ffplay --disable-ffserver --disable-ffprobe --disable-symver --disable-devices --disable-programs --enable-ffmpeg --disable-doc --disable-htmlpages --disable-manpages --disable-podpages --disable-txtpages --disable-avdevice --disable-postproc --enable-swscale --enable-network --enable-avfilter --enable-avformat --enable-avcodec --enable-avutil --enable-swresample --enable-avresample --enable-asm --enable-pic --enable-yasm --enable-pthreads --enable-neon --disable-debug --enable-optimizations --enable-runtime-cpudetect --disable-encoders --enable-libx264 --enable-libopenh264 --enable-encoder=libx264 --enable-encoder=libopenh264 --enable-encoder=aac --enable-encoder=libfdk_aac --enable-encoder=libspeex --enable-encoder=mjpeg --enable-encoder=mp3 --disable-decoders --enable-decoder=aac --enable-decoder=ac3 --enable-decoder=flv --enable-decoder=h264 --enable-decoder=mp3 --enable-decoder=libfdk_aac --enable-decoder=hevc --enable-decoder=mjpeg --enable-decoder='pcm*' --disable-muxers --enable-muxer=mpegts --enable-muxer=mp4 --enable-muxer=flv --enable-muxer=mp3 --disable-demuxers --enable-demuxer=aac --enable-demuxer=concat --enable-demuxer=ac3 --enable-demuxer=flv --enable-demuxer=hls --enable-demuxer=live_flv --enable-demuxer=mp4 --enable-demuxer=mov --enable-demuxer=mp3 --enable-demuxer=mpegts --enable-demuxer=mjpeg --enable-demuxer='pcm*' --disable-parsers --enable-parser=aac --enable-parser=ac3 --enable-parser=h264 --enable-parser=hevc --disable-protocols --enable-protocol=file --enable-protocol=http --enable-protocol=tls_openssl --enable-protocol=https --enable-protocol=rtmp --enable-protocol=rtmpt --enable-protocol=concat --disable-filters --enable-filter=buffer --enable-filter=buffersink --enable-filter=abuffer --enable-filter=abuffersink --enable-filter=scale --enable-filter=crop --enable-filter=copy --enable-filter=transpose --enable-filter=movie --enable-filter=format --enable-filter='anull*' --enable-filter=aresample --enable-filter=trim --enable-filter=atrim --enable-filter=concat --enable-filter=null --enable-filter='frame*' --enable-filter=fps --enable-filter=overlay --enable-filter=aformat --enable-filter=hflip --enable-filter=vflip --enable-filter=afade --enable-filter=amix --enable-filter=volume --enable-filter=reverse --enable-filter=amovie --enable-filter=atempo --disable-hwaccels --disable-bsfs --enable-bsf=aac_adtstoasc --enable-bsf=h264_mp4toannexb

  libavutil      55. 28.100 / 55. 28.100

  libavcodec     57. 48.101 / 57. 48.101

  libavformat    57. 41.100 / 57. 41.100

  libavfilter     6. 47.100 /  6. 47.100

  libavresample   3.  0.  0 /  3.  0.  0

  libswscale      4.  1.100 /  4.  1.100

  libswresample   2.  1.100 /  2.  1.100



Thanks,
Jogh

At 2018-07-25 02:54:27, "Carl Eugen Hoyos" <ceffmpeg at gmail.com> wrote:
>2018-07-23 16:39 GMT+02:00, Jeff <163jogh at 163.com>:
>
>> It seems like libyuv has better performace on scaling
>> than libswscale.
>
>Which platform did you test?
>
>Iirc, libswscale supports slices but the scale filter does not,
>so there is a possibility to improve the performance (from a
>user's perspective).
>
>Carl Eugen
>_______________________________________________
>ffmpeg-devel mailing list
>ffmpeg-devel at ffmpeg.org
>http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


More information about the ffmpeg-devel mailing list