[x264-devel] Resize filter updates
Steven Walters
git at videolan.org
Mon Jan 16 02:11:54 CET 2012
x264 | branch: master | Steven Walters <kemuri9 at gmail.com> | Mon Dec 5 08:46:34 2011 -0500| [61a78a1b417595c4b5d7ef6831692904a243a9fc] | committer: Jason Garrett-Glaser
Resize filter updates
Use AVPixFmtDescriptors to pick the most compatible x264 csp for any pixel format.
Fix deprecated use of av_set_int.
Now requires libavutil >= 51.19.0
> http://git.videolan.org/gitweb.cgi/x264.git/?a=commit;h=61a78a1b417595c4b5d7ef6831692904a243a9fc
---
configure | 4 +-
filters/video/resize.c | 132 ++++++++++++++++++++++++------------------------
2 files changed, 68 insertions(+), 68 deletions(-)
diff --git a/configure b/configure
index 43f363a..5c58f5a 100755
--- a/configure
+++ b/configure
@@ -768,10 +768,10 @@ if [ "$swscale" = "auto" ] ; then
[ -z "$SWSCALE_LIBS" ] && SWSCALE_LIBS="-lswscale -lavutil"
if cc_check "libswscale/swscale.h" "$SWSCALE_CFLAGS $SWSCALE_LIBS" "sws_init_context(0,0,0);" ; then
- if cc_check "libavutil/pixdesc.h" "$SWSCALE_CFLAGS $SWSCALE_LIBS" "av_get_pix_fmt_name(0);" ; then
+ if cpp_check "libavutil/pixdesc.h" "$SWSCALE_CFLAGS $SWSCALE_LIBS" "defined(PIX_FMT_RGB)" ; then
swscale="yes"
else
- echo "Warning: av_get_pix_fmt_name is missing from libavutil, update for swscale support"
+ echo "Warning: PIX_FMT_RGB is missing from libavutil, update for swscale support"
fi
fi
fi
diff --git a/filters/video/resize.c b/filters/video/resize.c
index fac9f5e..c157ef7 100644
--- a/filters/video/resize.c
+++ b/filters/video/resize.c
@@ -45,6 +45,10 @@ static int full_check( video_info_t *info, x264_param_t *param )
#include <libavutil/opt.h>
#include <libavutil/pixdesc.h>
+#ifndef PIX_FMT_BGRA64
+#define PIX_FMT_BGRA64 PIX_FMT_NONE
+#endif
+
typedef struct
{
int width;
@@ -145,62 +149,63 @@ static int convert_csp_to_pix_fmt( int csp )
case X264_CSP_YV24: /* specially handled via swapping chroma */
case X264_CSP_I444: return csp&X264_CSP_HIGH_DEPTH ? PIX_FMT_YUV444P16 : PIX_FMT_YUV444P;
case X264_CSP_RGB: return csp&X264_CSP_HIGH_DEPTH ? PIX_FMT_RGB48 : PIX_FMT_RGB24;
- /* the next 3 csps have no equivalent 16bit depth in swscale */
+ case X264_CSP_BGR: return csp&X264_CSP_HIGH_DEPTH ? PIX_FMT_BGR48 : PIX_FMT_BGR24;
+ case X264_CSP_BGRA: return csp&X264_CSP_HIGH_DEPTH ? PIX_FMT_BGRA64 : PIX_FMT_BGRA;
+ /* the next csp has no equivalent 16bit depth in swscale */
case X264_CSP_NV12: return csp&X264_CSP_HIGH_DEPTH ? PIX_FMT_NONE : PIX_FMT_NV12;
- case X264_CSP_BGR: return csp&X264_CSP_HIGH_DEPTH ? PIX_FMT_NONE : PIX_FMT_BGR24;
- case X264_CSP_BGRA: return csp&X264_CSP_HIGH_DEPTH ? PIX_FMT_NONE : PIX_FMT_BGRA;
default: return PIX_FMT_NONE;
}
}
+static int pix_number_of_planes( const AVPixFmtDescriptor *pix_desc )
+{
+ int num_planes = 0;
+ for( int i = 0; i < pix_desc->nb_components; i++ )
+ {
+ int plane_plus1 = pix_desc->comp[i].plane + 1;
+ num_planes = X264_MAX( plane_plus1, num_planes );
+ }
+ return num_planes;
+}
+
static int pick_closest_supported_csp( int csp )
{
int pix_fmt = convert_csp_to_pix_fmt( csp );
- switch( pix_fmt )
+ // first determine the base csp
+ int ret = X264_CSP_NONE;
+ const AVPixFmtDescriptor *pix_desc = av_pix_fmt_descriptors+pix_fmt;
+ if( (unsigned)pix_fmt >= PIX_FMT_NB || !pix_desc->name )
+ return ret;
+
+ const char *pix_fmt_name = pix_desc->name;
+ int is_rgb = pix_desc->flags & (PIX_FMT_RGB | PIX_FMT_PAL);
+ int is_bgr = !!strstr( pix_fmt_name, "bgr" );
+ if( is_bgr || is_rgb )
+ {
+ if( pix_desc->nb_components == 4 ) // has alpha
+ ret = X264_CSP_BGRA;
+ else if( is_bgr )
+ ret = X264_CSP_BGR;
+ else
+ ret = X264_CSP_RGB;
+ }
+ else
{
- case PIX_FMT_YUV420P16LE:
- case PIX_FMT_YUV420P16BE:
- return X264_CSP_I420 | X264_CSP_HIGH_DEPTH;
- case PIX_FMT_YUV422P:
- case PIX_FMT_YUYV422:
- case PIX_FMT_UYVY422:
- case PIX_FMT_YUVJ422P:
- return X264_CSP_I422;
- case PIX_FMT_YUV422P16LE:
- case PIX_FMT_YUV422P16BE:
- return X264_CSP_I422 | X264_CSP_HIGH_DEPTH;
- case PIX_FMT_YUV444P:
- case PIX_FMT_YUVJ444P:
- return X264_CSP_I444;
- case PIX_FMT_YUV444P16LE:
- case PIX_FMT_YUV444P16BE:
- return X264_CSP_I444 | X264_CSP_HIGH_DEPTH;
- case PIX_FMT_RGB24:
- case PIX_FMT_RGB565BE:
- case PIX_FMT_RGB565LE:
- case PIX_FMT_RGB555BE:
- case PIX_FMT_RGB555LE:
- return X264_CSP_RGB;
- case PIX_FMT_RGB48BE:
- case PIX_FMT_RGB48LE:
- return X264_CSP_RGB | X264_CSP_HIGH_DEPTH;
- case PIX_FMT_BGR24:
- case PIX_FMT_BGR565BE:
- case PIX_FMT_BGR565LE:
- case PIX_FMT_BGR555BE:
- case PIX_FMT_BGR555LE:
- return X264_CSP_BGR;
- case PIX_FMT_ARGB:
- case PIX_FMT_RGBA:
- case PIX_FMT_ABGR:
- case PIX_FMT_BGRA:
- return X264_CSP_BGRA;
- case PIX_FMT_NV12:
- case PIX_FMT_NV21:
- return X264_CSP_NV12;
- default:
- return X264_CSP_I420;
+ // yuv-based
+ if( pix_desc->nb_components == 1 || pix_desc->nb_components == 2 ) // no chroma
+ ret = X264_CSP_I420;
+ else if( pix_desc->log2_chroma_w && pix_desc->log2_chroma_h ) // reduced chroma width & height
+ ret = (pix_desc->nb_components == pix_number_of_planes( pix_desc )) ? X264_CSP_I420 : X264_CSP_NV12;
+ else if( pix_desc->log2_chroma_w ) // reduced chroma width only
+ ret = (pix_desc->nb_components == pix_number_of_planes( pix_desc )) ? X264_CSP_I422 : X264_CSP_NV16;
+ else
+ ret = X264_CSP_I444;
}
+ // now determine high depth
+ for( int i = 0; i < pix_desc->nb_components; i++ )
+ if( pix_desc->comp[i].depth_minus1 >= 8 )
+ ret |= X264_CSP_HIGH_DEPTH;
+ return ret;
}
static int handle_opts( const char **optlist, char **opts, video_info_t *info, resizer_hnd_t *h )
@@ -348,24 +353,22 @@ static int handle_opts( const char **optlist, char **opts, video_info_t *info, r
static int x264_init_sws_context( resizer_hnd_t *h )
{
+ if( h->ctx )
+ sws_freeContext( h->ctx );
+ h->ctx = sws_alloc_context();
if( !h->ctx )
- {
- h->ctx = sws_alloc_context();
- if( !h->ctx )
- return -1;
+ return -1;
- /* set flags that will not change */
- av_set_int( h->ctx, "sws_flags", h->ctx_flags );
- av_set_int( h->ctx, "dstw", h->dst.width );
- av_set_int( h->ctx, "dsth", h->dst.height );
- av_set_int( h->ctx, "dst_format", h->dst.pix_fmt );
- av_set_int( h->ctx, "dst_range", h->dst.range );
- }
+ av_opt_set_int( h->ctx, "sws_flags", h->ctx_flags, 0 );
+ av_opt_set_int( h->ctx, "dstw", h->dst.width, 0 );
+ av_opt_set_int( h->ctx, "dsth", h->dst.height, 0 );
+ av_opt_set_int( h->ctx, "dst_format", h->dst.pix_fmt, 0 );
+ av_opt_set_int( h->ctx, "dst_range", h->dst.range, 0 );
- av_set_int( h->ctx, "srcw", h->scale.width );
- av_set_int( h->ctx, "srch", h->scale.height );
- av_set_int( h->ctx, "src_format", h->scale.pix_fmt );
- av_set_int( h->ctx, "src_range", h->scale.range );
+ av_opt_set_int( h->ctx, "srcw", h->scale.width, 0 );
+ av_opt_set_int( h->ctx, "srch", h->scale.height, 0 );
+ av_opt_set_int( h->ctx, "src_format", h->scale.pix_fmt, 0 );
+ av_opt_set_int( h->ctx, "src_range", h->scale.range, 0 );
/* FIXME: use the correct matrix coefficients (only YUV -> RGB conversions are supported) */
sws_setColorspaceDetails( h->ctx,
@@ -423,11 +426,8 @@ static int init( hnd_t *handle, cli_vid_filter_t *filter, video_info_t *info, x2
/* only in normalization scenarios is the input capable of changing properties */
h->variable_input = 1;
h->dst_csp = pick_closest_supported_csp( info->csp );
- /* now fix the catch-all i420 choice if it does not allow for the current input resolution dimensions. */
- if( h->dst_csp == X264_CSP_I420 && info->width&1 )
- h->dst_csp = X264_CSP_I444;
- if( h->dst_csp == X264_CSP_I420 && info->height&1 )
- h->dst_csp = X264_CSP_I422;
+ FAIL_IF_ERROR( h->dst_csp == X264_CSP_NONE,
+ "filter get invalid input pixel format %d (colorspace %d)\n", convert_csp_to_pix_fmt( info->csp ), info->csp )
}
else if( handle_opts( optlist, opts, info, h ) )
return -1;
More information about the x264-devel
mailing list