diff libmpcodecs/vf_scale.c @ 30367:2db4c1158df9

Make the scale filter prefer yuv conversions that do not need chroma scaling. Also always try keeping input and output format the same first.
author reimar
date Sat, 23 Jan 2010 19:00:09 +0000
parents 81bebbcb2de4
children bbb6ebec87a0
line wrap: on
line diff
--- a/libmpcodecs/vf_scale.c	Sat Jan 23 18:37:47 2010 +0000
+++ b/libmpcodecs/vf_scale.c	Sat Jan 23 19:00:09 2010 +0000
@@ -94,14 +94,48 @@
     0
 };
 
-static unsigned int find_best_out(vf_instance_t *vf){
+/**
+ * A list of preferred conversions, in order of preference.
+ * This should be used for conversions that e.g. involve no scaling
+ * or to stop vf_scale from choosing a conversion that has no
+ * fast assembler implementation.
+ */
+static int preferred_conversions[][2] = {
+    {IMGFMT_YUY2, IMGFMT_UYVY},
+    {IMGFMT_YUY2, IMGFMT_422P},
+    {IMGFMT_UYVY, IMGFMT_YUY2},
+    {IMGFMT_UYVY, IMGFMT_422P},
+    {IMGFMT_422P, IMGFMT_YUY2},
+    {IMGFMT_422P, IMGFMT_UYVY},
+    {0, 0}
+};
+
+static unsigned int find_best_out(vf_instance_t *vf, int in_format){
     unsigned int best=0;
-    int i;
+    int i = -1;
+    int j = -1;
+    int format = 0;
 
     // find the best outfmt:
-    for(i=0; outfmt_list[i]; i++){
-        const int format= outfmt_list[i];
-        int ret = vf_next_query_format(vf, format);
+    while (1) {
+        int ret;
+        if (j < 0) {
+            format = in_format;
+            j = 0;
+        } else if (i < 0) {
+            while (preferred_conversions[j][0] &&
+                   preferred_conversions[j][0] != in_format)
+                j++;
+            format = preferred_conversions[j++][1];
+            // switch to standard list
+            if (!format)
+                i = 0;
+        }
+        if (i >= 0)
+            format = outfmt_list[i++];
+        if (!format)
+            break;
+        ret = vf_next_query_format(vf, format);
 
 	mp_msg(MSGT_VFILTER,MSGL_DBG2,"scale: query(%s) -> %d\n",vo_format_name(format),ret&3);
 	if(ret&VFCAP_CSP_SUPPORTED_BY_HW){
@@ -117,7 +151,7 @@
 static int config(struct vf_instance_s* vf,
         int width, int height, int d_width, int d_height,
 	unsigned int flags, unsigned int outfmt){
-    unsigned int best=find_best_out(vf);
+    unsigned int best=find_best_out(vf, outfmt);
     int vo_flags;
     int int_sws_flags=0;
     int round_w=0, round_h=0;
@@ -490,7 +524,7 @@
     case IMGFMT_RGB48LE:
     case IMGFMT_RGB48BE:
     {
-	unsigned int best=find_best_out(vf);
+	unsigned int best=find_best_out(vf, fmt);
 	int flags;
 	if(!best) return 0;	 // no matching out-fmt
 	flags=vf_next_query_format(vf,best);