mirror of
https://github.com/xenia-project/FFmpeg.git
synced 2025-02-02 02:04:19 +00:00
swscale: re-enable gamma
+added gamma conversion to refactored code
This commit is contained in:
parent
f67aff3ad7
commit
3059562aa1
@ -18,6 +18,7 @@ OBJS = alphablend.o \
|
|||||||
slice.o \
|
slice.o \
|
||||||
hscale.o \
|
hscale.o \
|
||||||
vscale.o \
|
vscale.o \
|
||||||
|
gamma.o \
|
||||||
|
|
||||||
OBJS-$(CONFIG_SHARED) += log2_tab.o
|
OBJS-$(CONFIG_SHARED) += log2_tab.o
|
||||||
|
|
||||||
|
72
libswscale/gamma.c
Normal file
72
libswscale/gamma.c
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Pedro Arthur <bygrandao@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of FFmpeg.
|
||||||
|
*
|
||||||
|
* FFmpeg is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FFmpeg is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with FFmpeg; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "swscale_internal.h"
|
||||||
|
|
||||||
|
typedef struct GammaContext
|
||||||
|
{
|
||||||
|
uint16_t *table;
|
||||||
|
} GammaContext;
|
||||||
|
|
||||||
|
// gamma_convert expects 16 bit rgb format
|
||||||
|
// it writes directly in src slice thus it must be modifiable (done through cascade context)
|
||||||
|
static int gamma_convert(SwsContext *c, SwsFilterDescriptor *desc, int sliceY, int sliceH)
|
||||||
|
{
|
||||||
|
GammaContext *instance = desc->instance;
|
||||||
|
uint16_t *table = instance->table;
|
||||||
|
int srcW = desc->src->width;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < sliceH; ++i) {
|
||||||
|
uint8_t ** src = desc->src->plane[0].line;
|
||||||
|
int src_pos = sliceY+i - desc->src->plane[0].sliceY;
|
||||||
|
|
||||||
|
uint16_t *src1 = (uint16_t*)*(src+src_pos);
|
||||||
|
int j;
|
||||||
|
for (j = 0; j < srcW; ++j) {
|
||||||
|
uint16_t r = AV_RL16(src1 + j*4 + 0);
|
||||||
|
uint16_t g = AV_RL16(src1 + j*4 + 1);
|
||||||
|
uint16_t b = AV_RL16(src1 + j*4 + 2);
|
||||||
|
|
||||||
|
AV_WL16(src1 + j*4 + 0, table[r]);
|
||||||
|
AV_WL16(src1 + j*4 + 1, table[g]);
|
||||||
|
AV_WL16(src1 + j*4 + 2, table[b]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return sliceH;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ff_init_gamma_convert(SwsFilterDescriptor *desc, SwsSlice * src, uint16_t *table)
|
||||||
|
{
|
||||||
|
GammaContext *li = av_malloc(sizeof(GammaContext));
|
||||||
|
if (!li)
|
||||||
|
return AVERROR(ENOMEM);
|
||||||
|
li->table = table;
|
||||||
|
|
||||||
|
desc->instance = li;
|
||||||
|
desc->src = src;
|
||||||
|
desc->dst = NULL;
|
||||||
|
desc->process = &gamma_convert;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -217,6 +217,7 @@ int ff_init_filters(SwsContext * c)
|
|||||||
int num_vdesc = isPlanarYUV(c->dstFormat) && !isGray(c->dstFormat) ? 2 : 1;
|
int num_vdesc = isPlanarYUV(c->dstFormat) && !isGray(c->dstFormat) ? 2 : 1;
|
||||||
int need_lum_conv = c->lumToYV12 || c->readLumPlanar || c->alpToYV12 || c->readAlpPlanar;
|
int need_lum_conv = c->lumToYV12 || c->readLumPlanar || c->alpToYV12 || c->readAlpPlanar;
|
||||||
int need_chr_conv = c->chrToYV12 || c->readChrPlanar;
|
int need_chr_conv = c->chrToYV12 || c->readChrPlanar;
|
||||||
|
int need_gamma = c->is_internal_gamma;
|
||||||
int srcIdx, dstIdx;
|
int srcIdx, dstIdx;
|
||||||
int dst_stride = FFALIGN(c->dstW * sizeof(int16_t) + 66, 16);
|
int dst_stride = FFALIGN(c->dstW * sizeof(int16_t) + 66, 16);
|
||||||
|
|
||||||
@ -230,9 +231,9 @@ int ff_init_filters(SwsContext * c)
|
|||||||
num_cdesc = need_chr_conv ? 2 : 1;
|
num_cdesc = need_chr_conv ? 2 : 1;
|
||||||
|
|
||||||
c->numSlice = FFMAX(num_ydesc, num_cdesc) + 2;
|
c->numSlice = FFMAX(num_ydesc, num_cdesc) + 2;
|
||||||
c->numDesc = num_ydesc + num_cdesc + num_vdesc;
|
c->numDesc = num_ydesc + num_cdesc + num_vdesc + (need_gamma ? 2 : 0);
|
||||||
c->descIndex[0] = num_ydesc;
|
c->descIndex[0] = num_ydesc + (need_gamma ? 1 : 0);
|
||||||
c->descIndex[1] = num_ydesc + num_cdesc;
|
c->descIndex[1] = num_ydesc + num_cdesc + (need_gamma ? 1 : 0);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -267,6 +268,12 @@ int ff_init_filters(SwsContext * c)
|
|||||||
srcIdx = 0;
|
srcIdx = 0;
|
||||||
dstIdx = 1;
|
dstIdx = 1;
|
||||||
|
|
||||||
|
if (need_gamma) {
|
||||||
|
res = ff_init_gamma_convert(c->desc + index, c->slice + srcIdx, c->inv_gamma);
|
||||||
|
if (res < 0) goto cleanup;
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
|
||||||
if (need_lum_conv) {
|
if (need_lum_conv) {
|
||||||
res = ff_init_desc_fmt_convert(&c->desc[index], &c->slice[srcIdx], &c->slice[dstIdx], pal);
|
res = ff_init_desc_fmt_convert(&c->desc[index], &c->slice[srcIdx], &c->slice[dstIdx], pal);
|
||||||
if (res < 0) goto cleanup;
|
if (res < 0) goto cleanup;
|
||||||
@ -309,6 +316,12 @@ int ff_init_filters(SwsContext * c)
|
|||||||
if (res < 0) goto cleanup;
|
if (res < 0) goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
++index;
|
||||||
|
if (need_gamma) {
|
||||||
|
res = ff_init_gamma_convert(c->desc + index, c->slice + dstIdx, c->gamma);
|
||||||
|
if (res < 0) goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
|
@ -379,7 +379,7 @@ static int swscale(SwsContext *c, const uint8_t *src[],
|
|||||||
int chrBufIndex = c->chrBufIndex;
|
int chrBufIndex = c->chrBufIndex;
|
||||||
int lastInLumBuf = c->lastInLumBuf;
|
int lastInLumBuf = c->lastInLumBuf;
|
||||||
int lastInChrBuf = c->lastInChrBuf;
|
int lastInChrBuf = c->lastInChrBuf;
|
||||||
// int perform_gamma = c->is_internal_gamma;
|
int perform_gamma = c->is_internal_gamma;
|
||||||
|
|
||||||
#ifdef NEW_FILTER
|
#ifdef NEW_FILTER
|
||||||
int lumStart = 0;
|
int lumStart = 0;
|
||||||
@ -392,9 +392,10 @@ static int swscale(SwsContext *c, const uint8_t *src[],
|
|||||||
SwsSlice *hout_slice = &c->slice[c->numSlice-2];
|
SwsSlice *hout_slice = &c->slice[c->numSlice-2];
|
||||||
SwsSlice *vout_slice = &c->slice[c->numSlice-1];
|
SwsSlice *vout_slice = &c->slice[c->numSlice-1];
|
||||||
SwsFilterDescriptor *desc = c->desc;
|
SwsFilterDescriptor *desc = c->desc;
|
||||||
#endif
|
|
||||||
int hasLumHoles = 1;
|
int hasLumHoles = 1;
|
||||||
int hasChrHoles = 1;
|
int hasChrHoles = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef NEW_FILTER
|
#ifndef NEW_FILTER
|
||||||
if (!usePal(c->srcFormat)) {
|
if (!usePal(c->srcFormat)) {
|
||||||
@ -612,8 +613,8 @@ static int swscale(SwsContext *c, const uint8_t *src[],
|
|||||||
av_assert0(lastInLumBuf + 1 - srcSliceY < srcSliceH);
|
av_assert0(lastInLumBuf + 1 - srcSliceY < srcSliceH);
|
||||||
av_assert0(lastInLumBuf + 1 - srcSliceY >= 0);
|
av_assert0(lastInLumBuf + 1 - srcSliceY >= 0);
|
||||||
|
|
||||||
//if (perform_gamma)
|
if (perform_gamma)
|
||||||
// gamma_convert((uint8_t **)src1, srcW, c->inv_gamma);
|
gamma_convert((uint8_t **)src1, srcW, c->inv_gamma);
|
||||||
|
|
||||||
hyscale(c, lumPixBuf[lumBufIndex], dstW, src1, srcW, lumXInc,
|
hyscale(c, lumPixBuf[lumBufIndex], dstW, src1, srcW, lumXInc,
|
||||||
hLumFilter, hLumFilterPos, hLumFilterSize,
|
hLumFilter, hLumFilterPos, hLumFilterSize,
|
||||||
@ -783,9 +784,9 @@ static int swscale(SwsContext *c, const uint8_t *src[],
|
|||||||
chrUSrcPtr, chrVSrcPtr, vChrFilterSize,
|
chrUSrcPtr, chrVSrcPtr, vChrFilterSize,
|
||||||
alpSrcPtr, dest, dstW, dstY);
|
alpSrcPtr, dest, dstW, dstY);
|
||||||
}
|
}
|
||||||
|
if (perform_gamma)
|
||||||
|
gamma_convert(dest, dstW, c->gamma);
|
||||||
#endif
|
#endif
|
||||||
//if (perform_gamma)
|
|
||||||
// gamma_convert(dest, dstW, c->gamma);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (isPlanar(dstFormat) && isALPHA(dstFormat) && !alpPixBuf) {
|
if (isPlanar(dstFormat) && isALPHA(dstFormat) && !alpPixBuf) {
|
||||||
|
@ -1028,6 +1028,9 @@ int ff_free_filters(SwsContext *c);
|
|||||||
*/
|
*/
|
||||||
int ff_rotate_slice(SwsSlice *s, int lum, int chr);
|
int ff_rotate_slice(SwsSlice *s, int lum, int chr);
|
||||||
|
|
||||||
|
/// initializes gamma conversion descriptor
|
||||||
|
int ff_init_gamma_convert(SwsFilterDescriptor *desc, SwsSlice * src, uint16_t *table);
|
||||||
|
|
||||||
/// initializes lum pixel format conversion descriptor
|
/// initializes lum pixel format conversion descriptor
|
||||||
int ff_init_desc_fmt_convert(SwsFilterDescriptor *desc, SwsSlice * src, SwsSlice *dst, uint32_t *pal);
|
int ff_init_desc_fmt_convert(SwsFilterDescriptor *desc, SwsSlice * src, SwsSlice *dst, uint32_t *pal);
|
||||||
|
|
||||||
|
@ -1419,6 +1419,15 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter,
|
|||||||
if (!c2->gamma || !c2->inv_gamma)
|
if (!c2->gamma || !c2->inv_gamma)
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
|
|
||||||
|
// is_internal_flag is set after creating the context
|
||||||
|
// to properly create the gamma convert FilterDescriptor
|
||||||
|
// we have to re-initialize it
|
||||||
|
ff_free_filters(c2);
|
||||||
|
if (ff_init_filters(c2) < 0) {
|
||||||
|
sws_freeContext(c2);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
c->cascaded_context[2] = NULL;
|
c->cascaded_context[2] = NULL;
|
||||||
if (dstFormat != tmpFmt) {
|
if (dstFormat != tmpFmt) {
|
||||||
ret = av_image_alloc(c->cascaded1_tmp, c->cascaded1_tmpStride,
|
ret = av_image_alloc(c->cascaded1_tmp, c->cascaded1_tmpStride,
|
||||||
|
@ -229,7 +229,7 @@ void ff_init_vscale_pfn(SwsContext *c,
|
|||||||
{
|
{
|
||||||
VScalerContext *lumCtx = NULL;
|
VScalerContext *lumCtx = NULL;
|
||||||
VScalerContext *chrCtx = NULL;
|
VScalerContext *chrCtx = NULL;
|
||||||
int idx = c->numDesc - 1;
|
int idx = c->numDesc - (c->is_internal_gamma ? 2 : 1);
|
||||||
|
|
||||||
if (isPlanarYUV(c->dstFormat) || (isGray(c->dstFormat) && !isALPHA(c->dstFormat))) {
|
if (isPlanarYUV(c->dstFormat) || (isGray(c->dstFormat) && !isALPHA(c->dstFormat))) {
|
||||||
if (!isGray(c->dstFormat)) {
|
if (!isGray(c->dstFormat)) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user