Examples of sws_scale () usage in FFMPEG
Video Encoding
10:02:27
Read 1185
Comment 0
Font size: Large
Medium
Small
Subscription
/*
* Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at
>
*
* This file is part of FFMPEG.
*
* FFmpeg is free software; you can redistribute it and/or
* Modify it under the terms of the GNU lesser general public
* License as published by the Free Software Foundation; either
* Version 2.1 of the license, or (at your option) any later version.
*
* FFmpeg is distributed in the hope that it will be useful,
* But without any warranty; without even the implied warranty
* Merchantability or fitness for a special purpose. See the GNU
* Lesser General Public License for more details.
*
* You shoshould have written ed a copy of the GNU lesser general public
* License along with FFMPEG; if not, write to the Free Software
* Foundation, inc., 51 Franklin Street, fifth floor, Boston, MA 02110-1301 USA
*/
# Include <stdio. h>
# Include <stdlib. h>
# Include <string. h>
# Include <inttypes. h>
# Include <stdarg. h>
# UNDEF have_av_config_h
# Include "libavutil/avutil. H"
# Include "swscale. H"
# Include "swscale_internal.h"
Static uint64_t getssd (uint8_t * src1, uint8_t * src2, int stride1, int stride2, int W, int h ){
Int X, Y;
Uint64_t SSD = 0;
// Printf ("% d/N", W, H );
For (y = 0; y For (x = 0; x <W; X ++ ){
Int d = src1 [x + y * stride1]-src2 [x + y * stride2];
SSD + = D * D;
// Printf ("% d", ABS (src1 [x + y * stride1]-src2 [x + y * stride2])/26 );
}
// Printf ("/N ");
}
Return SSD;
}
// Test by ref-> Src-> DST-> out & compare out against ref
// Ref & out are yv12
Static int dotest (uint8_t * ref [3], int refstride [3], int W, int H, int srcformat, int dstformat,
Int srcw, int srch, int dstw, int dsomething, int flags ){
Uint8_t * SRC [3];
Uint8_t * DST [3];
Uint8_t * out [3];
Int srcstride [3], dststride [3];
Int I;
Uint64_t ssdy, ssdu, ssdv;
Struct swscontext * srccontext, * dstcontext, * outcontext;
Int res;
Res = 0;
For (I = 0; I <3; I ++ ){
// Avoid stride % BPP! = 0
If (srcformat = pix_fmt_rgb24 | srcformat = pix_fmt_bgr24)
Srcstride [I] = srcw * 3;
Else
Srcstride [I] = srcw * 4;
If (dstformat = pix_fmt_rgb24 | dstformat = pix_fmt_bgr24)
Dststride [I] = dstw * 3;
Else
Dststride [I] = dstw * 4;
SRC [I] = (uint8_t *) malloc (srcstride [I] * srch );
DST [I] = (uint8_t *) malloc (dststride [I] * DTH );
Out [I] = (uint8_t *) malloc (refstride [I] * H );
If (! SRC [I] |! DST [I] |! Out [I]) {
Perror ("malloc ");
Res =-1;
Goto end;
}
}
Dstcontext = outcontext = NULL;
Srccontext = sws_getcontext (W, H, pix_fmt_yuv420p, srcw, srch, srcformat, flags, null, null );
If (! Srccontext ){
Fprintf (stderr, "failed to get % s ---> % s/n ",
Sws_format_name (pix_fmt_yuv420p ),
Sws_format_name (srcformat ));
Res =-1;
Goto end;
}
Dstcontext = sws_getcontext (srcw, srch, srcformat, dstw, DTH, dstformat, flags, null, null );
If (! Dstcontext ){
Fprintf (stderr, "failed to get % s ---> % s/n ",
Sws_format_name (srcformat ),
Sws_format_name (dstformat ));
Res =-1;
Goto end;
}
Outcontext = sws_getcontext (dstw, DTH, dstformat, W, H, pix_fmt_yuv420p, flags, null, null );
If (! Outcontext ){
Fprintf (stderr, "failed to get % s ---> % s/n ",
Sws_format_name (dstformat ),
Sws_format_name (pix_fmt_yuv420p ));
Res =-1;
Goto end;
}
// Printf ("test % x-> % x/N", (INT) Ref [0], (INT) Ref [1], (INT) Ref [2],
// (INT) SRC [0], (INT) SRC [1], (INT) SRC [2]);
Sws_scale (srccontext, ref, refstride, 0, H, SRC, srcstride );
Sws_scale (dstcontext, SRC, srcstride, 0, srch, DST, dststride );
Sws_scale (outcontext, DST, dststride, 0, dsomething, out, refstride );
Ssdy = getssd (Ref [0], out [0], refstride [0], refstride [0], W, H );
Ssdu = getssd (Ref [1], out [1], refstride [1], refstride [1], (W + 1)> 1, (H + 1)> 1 );
Ssdv = getssd (Ref [2], out [2], refstride [2], refstride [2], (W + 1)> 1, (H + 1)> 1 );
If (srcformat = pix_fmt_gray8 | dstformat = pix_fmt_gray8) ssdu = ssdv = 0; // fixme check that output is really gray
Ssdy/= W * h;
Ssdu/= W * H/4;
Ssdv/= W * H/4;
Printf ("% S % DX % d-> % S % 4dx % 4D flags = % 2D SSD = % 5lld, % 5lld, % 5lld/N ",
Sws_format_name (srcformat), srcw, srch,
Sws_format_name (dstformat), dstw, dsomething,
Flags, ssdy, ssdu, ssdv );
Fflush (stdout );
End:
Sws_freecontext (srccontext );
Sws_freecontext (dstcontext );
Sws_freecontext (outcontext );
For (I = 0; I <3; I ++ ){
Free (SRC [I]);
Free (DST [I]);
Free (out [I]);
}
Return res;
}
Static void selftest (uint8_t * SRC [3], int stride [3], int W, int h ){
Enum pixelformat srcformat, dstformat;
Int srcw, srch, dstw, dsomething;
Int flags;
For (srcformat = 0; srcformat <pix_fmt_nb; srcformat ++ ){
For (dstformat = 0; dstformat <pix_fmt_nb; dstformat ++ ){
Printf ("% s-> % s/n ",
Sws_format_name (srcformat ),
Sws_format_name (dstformat ));
Fflush (stdout );
Srcw = W;
Srch = h;
For (dstw = W-W/3; dstw <= 4 * w/3; dstw + = W/3 ){
For (dsomething = H-H/3; dsomething <= 4 * H/3; dsomething + = H/3 ){
For (flags = 1; flags <33; flags * = 2 ){
Int res;
Res = dotest (SRC, stride, W, H, srcformat, dstformat,
Srcw, srch, dstw, DTH, flags );
If (RES <0 ){
Dstw = 4 * w/3;
Dsomething = 4 * H/3;
Flags = 33;
}
}
}
}
}
}
}
# Define W 96
# Define H 96
Int main (INT argc, char ** argv ){
Uint8_t * rgb_data = malloc (w * H * 4 );
Uint8_t * rgb_src [3] = {rgb_data, null, null };
Int rgb_stride [3] = {4 * w, 0, 0 };
Uint8_t * Data = malloc (3 * w * H );
Uint8_t * SRC [3] = {data, data + W * H, Data + W * H * 2 };
Int stride [3] = {W, W, w };
Int X, Y;
Struct swscontext * SWS;
SWS = sws_getcontext (W/12, H/12, pix_fmt_rgb32, W, H, pix_fmt_yuv420p, 2, null );
For (y = 0; y For (x = 0; x <w * 4; X ++ ){
Rgb_data [x + y * 4 * w] = random ();
}
}
Sws_scale (SWS, rgb_src, rgb_stride, 0, H, SRC, stride );
Selftest (SRC, stride, W, H );
Return 123;
}