mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
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>
This commit is contained in:
parent
58a0b7f114
commit
8e05f9217a
@ -855,9 +855,74 @@ int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4],
|
|||||||
if (need_reinit && (c->srcBpc == 8 || !isYUV(c->srcFormat)))
|
if (need_reinit && (c->srcBpc == 8 || !isYUV(c->srcFormat)))
|
||||||
ff_sws_init_range_convert(c);
|
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;
|
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->dstFormatBpp = av_get_bits_per_pixel(desc_dst);
|
||||||
c->srcFormatBpp = av_get_bits_per_pixel(desc_src);
|
c->srcFormatBpp = av_get_bits_per_pixel(desc_src);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user