[FFmpeg-devel] [PATCH] CrystalHD: Use lowres option to expose hardware scaling.

Philip Langdale philipl at overt.org
Sun Apr 17 00:43:03 CEST 2011


The CrystalHD hardware can do scaling, which is particularly
desirable when dealing with some high resolution clips that take
so long to decode and copy out that they end up playing back
slower than realtime. By using scaling, we can make the output
frames smaller and reduce the copy out time.

The official lowres semantics are that the resolution should be
divided by 2^n but this would prevent scaling to resolutions
higher than 960x540 for 1920x1080 content. So, I am abusing the
semantics by assigning specific resolutions to each value.

Signed-off-by: Philip Langdale <philipl at overt.org>
---
 libavcodec/crystalhd.c |   36 ++++++++++++++++++++++++++++++++++++
 1 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/libavcodec/crystalhd.c b/libavcodec/crystalhd.c
index 9bbb6e8..dc2cc09 100644
--- a/libavcodec/crystalhd.c
+++ b/libavcodec/crystalhd.c
@@ -96,6 +96,8 @@
 #define BASE_WAIT 10000
 /** Increment in us to adjust wait in decode() */
 #define WAIT_UNIT 1000
+/** Maximum accepted lowres value */
+#define MAX_LOWRES 4
 
 
 /*****************************************************************************
@@ -434,6 +436,34 @@ static av_cold int init(AVCodecContext *avctx)
     }
     format.mSubtype = subtype;
 
+    /*
+     * We slightly abuse the semantics of lowres - which say that you
+     * should divide the resolution by 2^n. This would mean we couldn't
+     * offer reasonable resolutions between 1920 and 960 - particularly
+     * 1280 (for 720p).
+     */
+    if (avctx->lowres) {
+        format.bEnableScaling = 1;
+        switch (avctx->lowres) {
+        case 1:
+	    format.ScalingParams.sWidth = 1600;
+            break;
+        case 2:
+	    format.ScalingParams.sWidth = 1280;
+            break;
+        case 3:
+	    format.ScalingParams.sWidth = 960;
+            break;
+        case 4:
+	    format.ScalingParams.sWidth = 640;
+            break;
+        default:
+	    av_log(avctx, AV_LOG_ERROR, "CrystalHD: Invalid lowres: %d\n",
+	           avctx->lowres);
+	    return AVERROR(EINVAL);
+	}
+    }
+
     /* Get a decoder instance */
     av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: starting up\n");
     // Initialize the Link and Decoder devices
@@ -960,6 +990,7 @@ AVCodec ff_h264_crystalhd_decoder = {
     .flush          = flush,
     .long_name      = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (CrystalHD acceleration)"),
     .pix_fmts       = (const enum PixelFormat[]){PIX_FMT_YUYV422, PIX_FMT_NONE},
+    .max_lowres     = MAX_LOWRES,
 };
 #endif
 
@@ -976,6 +1007,7 @@ AVCodec ff_mpeg2_crystalhd_decoder = {
     .flush          = flush,
     .long_name      = NULL_IF_CONFIG_SMALL("MPEG-2 Video (CrystalHD acceleration)"),
     .pix_fmts       = (const enum PixelFormat[]){PIX_FMT_YUYV422, PIX_FMT_NONE},
+    .max_lowres     = MAX_LOWRES,
 };
 #endif
 
@@ -992,6 +1024,7 @@ AVCodec ff_mpeg4_crystalhd_decoder = {
     .flush          = flush,
     .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 Part 2 (CrystalHD acceleration)"),
     .pix_fmts       = (const enum PixelFormat[]){PIX_FMT_YUYV422, PIX_FMT_NONE},
+    .max_lowres     = MAX_LOWRES,
 };
 #endif
 
@@ -1008,6 +1041,7 @@ AVCodec ff_msmpeg4_crystalhd_decoder = {
     .flush          = flush,
     .long_name      = NULL_IF_CONFIG_SMALL("MPEG-4 Part 2 Microsoft variant version 3 (CrystalHD acceleration)"),
     .pix_fmts       = (const enum PixelFormat[]){PIX_FMT_YUYV422, PIX_FMT_NONE},
+    .max_lowres     = MAX_LOWRES,
 };
 #endif
 
@@ -1024,6 +1058,7 @@ AVCodec ff_vc1_crystalhd_decoder = {
     .flush          = flush,
     .long_name      = NULL_IF_CONFIG_SMALL("SMPTE VC-1 (CrystalHD acceleration)"),
     .pix_fmts       = (const enum PixelFormat[]){PIX_FMT_YUYV422, PIX_FMT_NONE},
+    .max_lowres     = MAX_LOWRES,
 };
 #endif
 
@@ -1040,5 +1075,6 @@ AVCodec ff_wmv3_crystalhd_decoder = {
     .flush          = flush,
     .long_name      = NULL_IF_CONFIG_SMALL("Windows Media Video 9 (CrystalHD acceleration)"),
     .pix_fmts       = (const enum PixelFormat[]){PIX_FMT_YUYV422, PIX_FMT_NONE},
+    .max_lowres     = MAX_LOWRES,
 };
 #endif
-- 
1.7.4.1



More information about the ffmpeg-devel mailing list