|
|
|
@ -27,11 +27,12 @@ |
|
|
|
|
|
|
|
|
|
#include <stdio.h> |
|
|
|
|
|
|
|
|
|
#include "libavutil/intreadwrite.h" |
|
|
|
|
#include "libavutil/pixdesc.h" |
|
|
|
|
#include "libavutil/imgutils.h" |
|
|
|
|
#include "libavutil/internal.h" |
|
|
|
|
#include "libavutil/intreadwrite.h" |
|
|
|
|
#include "libavutil/opt.h" |
|
|
|
|
#include "libavutil/pixdesc.h" |
|
|
|
|
|
|
|
|
|
#include "avfilter.h" |
|
|
|
|
#include "formats.h" |
|
|
|
|
#include "internal.h" |
|
|
|
@ -111,12 +112,14 @@ static int config_props_output(AVFilterLink *outlink) |
|
|
|
|
outlink->w = inlink->h; |
|
|
|
|
outlink->h = inlink->w; |
|
|
|
|
|
|
|
|
|
if (inlink->sample_aspect_ratio.num){ |
|
|
|
|
outlink->sample_aspect_ratio = av_div_q((AVRational){1,1}, inlink->sample_aspect_ratio); |
|
|
|
|
} else |
|
|
|
|
if (inlink->sample_aspect_ratio.num) |
|
|
|
|
outlink->sample_aspect_ratio = av_div_q((AVRational) { 1, 1 }, |
|
|
|
|
inlink->sample_aspect_ratio); |
|
|
|
|
else |
|
|
|
|
outlink->sample_aspect_ratio = inlink->sample_aspect_ratio; |
|
|
|
|
|
|
|
|
|
av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d dir:%d -> w:%d h:%d rotation:%s vflip:%d\n", |
|
|
|
|
av_log(ctx, AV_LOG_VERBOSE, |
|
|
|
|
"w:%d h:%d dir:%d -> w:%d h:%d rotation:%s vflip:%d\n", |
|
|
|
|
inlink->w, inlink->h, trans->dir, outlink->w, outlink->h, |
|
|
|
|
trans->dir == 1 || trans->dir == 3 ? "clockwise" : "counterclockwise", |
|
|
|
|
trans->dir == 0 || trans->dir == 3); |
|
|
|
@ -146,30 +149,30 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, |
|
|
|
|
int plane; |
|
|
|
|
|
|
|
|
|
for (plane = 0; out->data[plane]; plane++) { |
|
|
|
|
int hsub = plane == 1 || plane == 2 ? trans->hsub : 0; |
|
|
|
|
int vsub = plane == 1 || plane == 2 ? trans->vsub : 0; |
|
|
|
|
int hsub = plane == 1 || plane == 2 ? trans->hsub : 0; |
|
|
|
|
int vsub = plane == 1 || plane == 2 ? trans->vsub : 0; |
|
|
|
|
int pixstep = trans->pixsteps[plane]; |
|
|
|
|
int inh = in->height >> vsub; |
|
|
|
|
int outw = FF_CEIL_RSHIFT(out->width, hsub); |
|
|
|
|
int outh = FF_CEIL_RSHIFT(out->height, vsub); |
|
|
|
|
int start = (outh * jobnr ) / nb_jobs; |
|
|
|
|
int end = (outh * (jobnr+1)) / nb_jobs; |
|
|
|
|
int inh = in->height >> vsub; |
|
|
|
|
int outw = FF_CEIL_RSHIFT(out->width, hsub); |
|
|
|
|
int outh = FF_CEIL_RSHIFT(out->height, vsub); |
|
|
|
|
int start = (outh * jobnr ) / nb_jobs; |
|
|
|
|
int end = (outh * (jobnr+1)) / nb_jobs; |
|
|
|
|
uint8_t *dst, *src; |
|
|
|
|
int dstlinesize, srclinesize; |
|
|
|
|
int x, y; |
|
|
|
|
|
|
|
|
|
dstlinesize = out->linesize[plane]; |
|
|
|
|
dst = out->data[plane] + start * dstlinesize; |
|
|
|
|
src = in->data[plane]; |
|
|
|
|
dst = out->data[plane] + start * dstlinesize; |
|
|
|
|
src = in->data[plane]; |
|
|
|
|
srclinesize = in->linesize[plane]; |
|
|
|
|
|
|
|
|
|
if (trans->dir&1) { |
|
|
|
|
src += in->linesize[plane] * (inh-1); |
|
|
|
|
if (trans->dir & 1) { |
|
|
|
|
src += in->linesize[plane] * (inh - 1); |
|
|
|
|
srclinesize *= -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (trans->dir&2) { |
|
|
|
|
dst = out->data[plane] + dstlinesize * (outh-start-1); |
|
|
|
|
if (trans->dir & 2) { |
|
|
|
|
dst = out->data[plane] + dstlinesize * (outh - start - 1); |
|
|
|
|
dstlinesize *= -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -177,32 +180,34 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, |
|
|
|
|
case 1: |
|
|
|
|
for (y = start; y < end; y++, dst += dstlinesize) |
|
|
|
|
for (x = 0; x < outw; x++) |
|
|
|
|
dst[x] = src[x*srclinesize + y]; |
|
|
|
|
dst[x] = src[x * srclinesize + y]; |
|
|
|
|
break; |
|
|
|
|
case 2: |
|
|
|
|
for (y = start; y < end; y++, dst += dstlinesize) { |
|
|
|
|
for (x = 0; x < outw; x++) |
|
|
|
|
*((uint16_t *)(dst + 2*x)) = *((uint16_t *)(src + x*srclinesize + y*2)); |
|
|
|
|
*((uint16_t *)(dst + 2 * x)) = |
|
|
|
|
*((uint16_t *)(src + x * srclinesize + y * 2)); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 3: |
|
|
|
|
for (y = start; y < end; y++, dst += dstlinesize) { |
|
|
|
|
for (x = 0; x < outw; x++) { |
|
|
|
|
int32_t v = AV_RB24(src + x*srclinesize + y*3); |
|
|
|
|
AV_WB24(dst + 3*x, v); |
|
|
|
|
int32_t v = AV_RB24(src + x * srclinesize + y * 3); |
|
|
|
|
AV_WB24(dst + 3 * x, v); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 4: |
|
|
|
|
for (y = start; y < end; y++, dst += dstlinesize) { |
|
|
|
|
for (x = 0; x < outw; x++) |
|
|
|
|
*((uint32_t *)(dst + 4*x)) = *((uint32_t *)(src + x*srclinesize + y*4)); |
|
|
|
|
*((uint32_t *)(dst + 4 * x)) = |
|
|
|
|
*((uint32_t *)(src + x * srclinesize + y * 4)); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
case 6: |
|
|
|
|
for (y = start; y < end; y++, dst += dstlinesize) { |
|
|
|
|
for (x = 0; x < outw; x++) { |
|
|
|
|
int64_t v = AV_RB48(src + x*srclinesize + y*6); |
|
|
|
|
int64_t v = AV_RB48(src + x * srclinesize + y*6); |
|
|
|
|
AV_WB48(dst + 6*x, v); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
@ -210,7 +215,7 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, |
|
|
|
|
case 8: |
|
|
|
|
for (y = start; y < end; y++, dst += dstlinesize) { |
|
|
|
|
for (x = 0; x < outw; x++) |
|
|
|
|
*((uint64_t *)(dst + 8*x)) = *((uint64_t *)(src + x*srclinesize + y*8)); |
|
|
|
|
*((uint64_t *)(dst + 8*x)) = *((uint64_t *)(src + x * srclinesize + y*8)); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
@ -273,10 +278,10 @@ AVFILTER_DEFINE_CLASS(transpose); |
|
|
|
|
|
|
|
|
|
static const AVFilterPad avfilter_vf_transpose_inputs[] = { |
|
|
|
|
{ |
|
|
|
|
.name = "default", |
|
|
|
|
.type = AVMEDIA_TYPE_VIDEO, |
|
|
|
|
.name = "default", |
|
|
|
|
.type = AVMEDIA_TYPE_VIDEO, |
|
|
|
|
.get_video_buffer = get_video_buffer, |
|
|
|
|
.filter_frame = filter_frame, |
|
|
|
|
.filter_frame = filter_frame, |
|
|
|
|
}, |
|
|
|
|
{ NULL } |
|
|
|
|
}; |
|
|
|
|