Commit e4253b1a authored by Philip Langdale's avatar Philip Langdale

CrystalHD: Add AVOption to configure hardware downscaling.

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.

This option takes the desired horizontal width in pixels, and
the hardware will do an aspect-scale. Upscaling is not supported
and the hardware will simply ignore any request to do so.
Signed-off-by: 's avatarPhilip Langdale <philipl@overt.org>
parent 67c1a59a
...@@ -87,6 +87,7 @@ ...@@ -87,6 +87,7 @@
#include "h264.h" #include "h264.h"
#include "libavutil/imgutils.h" #include "libavutil/imgutils.h"
#include "libavutil/intreadwrite.h" #include "libavutil/intreadwrite.h"
#include "libavutil/opt.h"
/** Timeout parameter passed to DtsProcOutput() in us */ /** Timeout parameter passed to DtsProcOutput() in us */
#define OUTPUT_PROC_TIMEOUT 50 #define OUTPUT_PROC_TIMEOUT 50
...@@ -118,6 +119,7 @@ typedef struct OpaqueList { ...@@ -118,6 +119,7 @@ typedef struct OpaqueList {
} OpaqueList; } OpaqueList;
typedef struct { typedef struct {
AVClass *av_class;
AVCodecContext *avctx; AVCodecContext *avctx;
AVFrame pic; AVFrame pic;
HANDLE dev; HANDLE dev;
...@@ -137,8 +139,20 @@ typedef struct { ...@@ -137,8 +139,20 @@ typedef struct {
OpaqueList *head; OpaqueList *head;
OpaqueList *tail; OpaqueList *tail;
/* Options */
uint32_t sWidth;
} CHDContext; } CHDContext;
static const AVOption options[] = {
{ "crystalhd_downscale_width",
"Turn on downscaling to the specified width",
offsetof(CHDContext, sWidth),
FF_OPT_TYPE_INT, 0, 0, UINT32_MAX,
AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM, },
{ NULL, },
};
/***************************************************************************** /*****************************************************************************
* Helper functions * Helper functions
...@@ -434,6 +448,11 @@ static av_cold int init(AVCodecContext *avctx) ...@@ -434,6 +448,11 @@ static av_cold int init(AVCodecContext *avctx)
} }
format.mSubtype = subtype; format.mSubtype = subtype;
if (priv->sWidth) {
format.bEnableScaling = 1;
format.ScalingParams.sWidth = priv->sWidth;
}
/* Get a decoder instance */ /* Get a decoder instance */
av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: starting up\n"); av_log(avctx, AV_LOG_VERBOSE, "CrystalHD: starting up\n");
// Initialize the Link and Decoder devices // Initialize the Link and Decoder devices
...@@ -948,6 +967,13 @@ static int decode(AVCodecContext *avctx, void *data, int *data_size, AVPacket *a ...@@ -948,6 +967,13 @@ static int decode(AVCodecContext *avctx, void *data, int *data_size, AVPacket *a
#if CONFIG_H264_CRYSTALHD_DECODER #if CONFIG_H264_CRYSTALHD_DECODER
static AVClass h264_class = {
"h264_crystalhd",
av_default_item_name,
options,
LIBAVUTIL_VERSION_INT,
};
AVCodec ff_h264_crystalhd_decoder = { AVCodec ff_h264_crystalhd_decoder = {
.name = "h264_crystalhd", .name = "h264_crystalhd",
.type = AVMEDIA_TYPE_VIDEO, .type = AVMEDIA_TYPE_VIDEO,
...@@ -960,10 +986,18 @@ AVCodec ff_h264_crystalhd_decoder = { ...@@ -960,10 +986,18 @@ AVCodec ff_h264_crystalhd_decoder = {
.flush = flush, .flush = flush,
.long_name = NULL_IF_CONFIG_SMALL("H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10 (CrystalHD acceleration)"), .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}, .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUYV422, PIX_FMT_NONE},
.priv_class = &h264_class,
}; };
#endif #endif
#if CONFIG_MPEG2_CRYSTALHD_DECODER #if CONFIG_MPEG2_CRYSTALHD_DECODER
static AVClass mpeg2_class = {
"mpeg2_crystalhd",
av_default_item_name,
options,
LIBAVUTIL_VERSION_INT,
};
AVCodec ff_mpeg2_crystalhd_decoder = { AVCodec ff_mpeg2_crystalhd_decoder = {
.name = "mpeg2_crystalhd", .name = "mpeg2_crystalhd",
.type = AVMEDIA_TYPE_VIDEO, .type = AVMEDIA_TYPE_VIDEO,
...@@ -976,10 +1010,18 @@ AVCodec ff_mpeg2_crystalhd_decoder = { ...@@ -976,10 +1010,18 @@ AVCodec ff_mpeg2_crystalhd_decoder = {
.flush = flush, .flush = flush,
.long_name = NULL_IF_CONFIG_SMALL("MPEG-2 Video (CrystalHD acceleration)"), .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 Video (CrystalHD acceleration)"),
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUYV422, PIX_FMT_NONE}, .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUYV422, PIX_FMT_NONE},
.priv_class = &mpeg2_class,
}; };
#endif #endif
#if CONFIG_MPEG4_CRYSTALHD_DECODER #if CONFIG_MPEG4_CRYSTALHD_DECODER
static AVClass mpeg4_class = {
"mpeg4_crystalhd",
av_default_item_name,
options,
LIBAVUTIL_VERSION_INT,
};
AVCodec ff_mpeg4_crystalhd_decoder = { AVCodec ff_mpeg4_crystalhd_decoder = {
.name = "mpeg4_crystalhd", .name = "mpeg4_crystalhd",
.type = AVMEDIA_TYPE_VIDEO, .type = AVMEDIA_TYPE_VIDEO,
...@@ -992,10 +1034,18 @@ AVCodec ff_mpeg4_crystalhd_decoder = { ...@@ -992,10 +1034,18 @@ AVCodec ff_mpeg4_crystalhd_decoder = {
.flush = flush, .flush = flush,
.long_name = NULL_IF_CONFIG_SMALL("MPEG-4 Part 2 (CrystalHD acceleration)"), .long_name = NULL_IF_CONFIG_SMALL("MPEG-4 Part 2 (CrystalHD acceleration)"),
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUYV422, PIX_FMT_NONE}, .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUYV422, PIX_FMT_NONE},
.priv_class = &mpeg4_class,
}; };
#endif #endif
#if CONFIG_MSMPEG4_CRYSTALHD_DECODER #if CONFIG_MSMPEG4_CRYSTALHD_DECODER
static AVClass msmpeg4_class = {
"msmpeg4_crystalhd",
av_default_item_name,
options,
LIBAVUTIL_VERSION_INT,
};
AVCodec ff_msmpeg4_crystalhd_decoder = { AVCodec ff_msmpeg4_crystalhd_decoder = {
.name = "msmpeg4_crystalhd", .name = "msmpeg4_crystalhd",
.type = AVMEDIA_TYPE_VIDEO, .type = AVMEDIA_TYPE_VIDEO,
...@@ -1008,10 +1058,18 @@ AVCodec ff_msmpeg4_crystalhd_decoder = { ...@@ -1008,10 +1058,18 @@ AVCodec ff_msmpeg4_crystalhd_decoder = {
.flush = flush, .flush = flush,
.long_name = NULL_IF_CONFIG_SMALL("MPEG-4 Part 2 Microsoft variant version 3 (CrystalHD acceleration)"), .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}, .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUYV422, PIX_FMT_NONE},
.priv_class = &msmpeg4_class,
}; };
#endif #endif
#if CONFIG_VC1_CRYSTALHD_DECODER #if CONFIG_VC1_CRYSTALHD_DECODER
static AVClass vc1_class = {
"vc1_crystalhd",
av_default_item_name,
options,
LIBAVUTIL_VERSION_INT,
};
AVCodec ff_vc1_crystalhd_decoder = { AVCodec ff_vc1_crystalhd_decoder = {
.name = "vc1_crystalhd", .name = "vc1_crystalhd",
.type = AVMEDIA_TYPE_VIDEO, .type = AVMEDIA_TYPE_VIDEO,
...@@ -1024,10 +1082,18 @@ AVCodec ff_vc1_crystalhd_decoder = { ...@@ -1024,10 +1082,18 @@ AVCodec ff_vc1_crystalhd_decoder = {
.flush = flush, .flush = flush,
.long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1 (CrystalHD acceleration)"), .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1 (CrystalHD acceleration)"),
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUYV422, PIX_FMT_NONE}, .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUYV422, PIX_FMT_NONE},
.priv_class = &vc1_class,
}; };
#endif #endif
#if CONFIG_WMV3_CRYSTALHD_DECODER #if CONFIG_WMV3_CRYSTALHD_DECODER
static AVClass wmv3_class = {
"wmv3_crystalhd",
av_default_item_name,
options,
LIBAVUTIL_VERSION_INT,
};
AVCodec ff_wmv3_crystalhd_decoder = { AVCodec ff_wmv3_crystalhd_decoder = {
.name = "wmv3_crystalhd", .name = "wmv3_crystalhd",
.type = AVMEDIA_TYPE_VIDEO, .type = AVMEDIA_TYPE_VIDEO,
...@@ -1040,5 +1106,6 @@ AVCodec ff_wmv3_crystalhd_decoder = { ...@@ -1040,5 +1106,6 @@ AVCodec ff_wmv3_crystalhd_decoder = {
.flush = flush, .flush = flush,
.long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 (CrystalHD acceleration)"), .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9 (CrystalHD acceleration)"),
.pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUYV422, PIX_FMT_NONE}, .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUYV422, PIX_FMT_NONE},
.priv_class = &wmv3_class,
}; };
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment