Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Niedermayer <michael@niedermayer.cc>2015-08-31 00:58:37 +0300
committerMichael Niedermayer <michael@niedermayer.cc>2015-08-31 03:00:19 +0300
commit8e05f9217ae567a26ea71dd29acd79b1631ae593 (patch)
tree0c5156cc424b2fcd6dc704e34dcaaaa765e0f5cd /libswscale
parent58a0b7f1143511b712741af91d5f4bcbbe9d1488 (diff)
swscale/utils: Split scaling if possible and yuv->yuv with different matrixes is requested
This uses a RGB intermediate, a more optimal solution would be to perform the rematrixing directly in subsampled YUV, this is quite a bit more complicated though Fixes Ticket4805 Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libswscale')
-rw-r--r--libswscale/utils.c67
1 files changed, 66 insertions, 1 deletions
diff --git a/libswscale/utils.c b/libswscale/utils.c
index 181a48ad21..53f68db1b3 100644
--- a/libswscale/utils.c
+++ b/libswscale/utils.c
@@ -855,8 +855,73 @@ int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4],
if (need_reinit && (c->srcBpc == 8 || !isYUV(c->srcFormat)))
ff_sws_init_range_convert(c);
- if ((isYUV(c->dstFormat) || isGray(c->dstFormat)) && (isYUV(c->srcFormat) || isGray(c->srcFormat)))
+ if ((isYUV(c->dstFormat) || isGray(c->dstFormat)) && (isYUV(c->srcFormat) || isGray(c->srcFormat))) {
+ if (!c->cascaded_context[0] &&
+ memcmp(c->dstColorspaceTable, c->srcColorspaceTable, sizeof(int) * 4) &&
+ c->srcW && c->srcH && c->dstW && c->dstH) {
+ enum AVPixelFormat tmp_format;
+ int tmp_width, tmp_height;
+ int srcW = c->srcW;
+ int srcH = c->srcH;
+ int dstW = c->dstW;
+ int dstH = c->dstH;
+ int ret;
+ av_log(c, AV_LOG_VERBOSE, "YUV color matrix differs for YUV->YUV, using intermediate RGB to convert\n");
+
+ if (isNBPS(c->dstFormat) || is16BPS(c->dstFormat)) {
+ if (isALPHA(c->srcFormat) && isALPHA(c->dstFormat)) {
+ tmp_format = AV_PIX_FMT_BGRA64;
+ } else {
+ tmp_format = AV_PIX_FMT_BGR48;
+ }
+ } else {
+ if (isALPHA(c->srcFormat) && isALPHA(c->dstFormat)) {
+ tmp_format = AV_PIX_FMT_BGRA;
+ } else {
+ tmp_format = AV_PIX_FMT_BGR24;
+ }
+ }
+
+ if (srcW*srcH > dstW*dstH) {
+ tmp_width = dstW;
+ tmp_height = dstH;
+ } else {
+ tmp_width = srcW;
+ tmp_height = srcH;
+ }
+
+ ret = av_image_alloc(c->cascaded_tmp, c->cascaded_tmpStride,
+ tmp_width, tmp_height, tmp_format, 64);
+ if (ret < 0)
+ return ret;
+
+ c->cascaded_context[0] = sws_alloc_set_opts(srcW, srcH, c->srcFormat,
+ tmp_width, tmp_height, tmp_format,
+ c->flags, c->param);
+ if (!c->cascaded_context[0])
+ return -1;
+
+ c->cascaded_context[0]->alphablend = c->alphablend;
+ ret = sws_init_context(c->cascaded_context[0], NULL , NULL);
+ if (ret < 0)
+ return ret;
+ //we set both src and dst depending on that the RGB side will be ignored
+ sws_setColorspaceDetails(c->cascaded_context[0], inv_table,
+ srcRange, table, dstRange,
+ brightness, contrast, saturation);
+
+ c->cascaded_context[1] = sws_getContext(tmp_width, tmp_height, tmp_format,
+ dstW, dstH, c->dstFormat,
+ c->flags, NULL, NULL, c->param);
+ if (!c->cascaded_context[1])
+ return -1;
+ sws_setColorspaceDetails(c->cascaded_context[1], inv_table,
+ srcRange, table, dstRange,
+ 0, 1 << 16, 1 << 16);
+ return 0;
+ }
return -1;
+ }
c->dstFormatBpp = av_get_bits_per_pixel(desc_dst);
c->srcFormatBpp = av_get_bits_per_pixel(desc_src);