Browse Source

Merge remote-tracking branch 'qatar/master'

* qatar/master:
  swscale: remove misplaced comment.
  ffmpeg: fix streaming to ffserver.
  swscale: split out RGB48 output functions from yuv2packed[12X]_c().
  build: move vpath directives to main Makefile
  swscale: fix JPEG-range YUV scaling artifacts.
  build: move ALLFFLIBS to a more logical place
  ARM: factor some repetitive code into macros
  Fix SVQ3 after adding 4:4:4 H.264 support
  H.264: fix CODEC_FLAG_GRAY
  4:4:4 H.264 decoding support
  ac3enc: fix allocation of floating point samples.

Conflicts:
	ffmpeg.c
	libavcodec/dsputil_template.c
	libavcodec/h264.c
	libavcodec/mpegvideo.c
	libavcodec/snow.c
	libswscale/swscale.c
	libswscale/swscale_internal.h

Merged-by: Michael Niedermayer <michaelni@gmx.at>
tags/n0.8
Michael Niedermayer 14 years ago
parent
commit
c137fdd778
27 changed files with 2048 additions and 998 deletions
  1. +7
    -0
      Makefile
  2. +0
    -7
      common.mak
  3. +7
    -9
      libavcodec/ac3enc.c
  4. +5
    -0
      libavcodec/ac3enc.h
  5. +20
    -0
      libavcodec/ac3enc_template.c
  6. +2
    -1
      libavcodec/arm/h264dsp_init_arm.c
  7. +23
    -38
      libavcodec/arm/mpegvideo_armv5te_s.S
  8. +46
    -136
      libavcodec/arm/simple_idct_armv5te.S
  9. +1
    -1
      libavcodec/dsputil.h
  10. +3
    -3
      libavcodec/dsputil_template.c
  11. +519
    -288
      libavcodec/h264.c
  12. +100
    -81
      libavcodec/h264.h
  13. +714
    -101
      libavcodec/h264_cabac.c
  14. +117
    -81
      libavcodec/h264_cavlc.c
  15. +82
    -50
      libavcodec/h264_loopfilter.c
  16. +11
    -3
      libavcodec/h264_ps.c
  17. +4
    -4
      libavcodec/h264dsp.h
  18. +25
    -19
      libavcodec/h264idct_template.c
  19. +19
    -9
      libavcodec/mpegvideo.c
  20. +12
    -10
      libavcodec/ppc/h264_altivec.c
  21. +9
    -3
      libavcodec/snow.c
  22. +16
    -12
      libavcodec/svq3.c
  23. +2
    -2
      libavcodec/x86/dsputil_mmx.c
  24. +9
    -6
      libavcodec/x86/h264_i386.h
  25. +27
    -17
      libavcodec/x86/h264_idct.asm
  26. +20
    -15
      libavcodec/x86/h264_idct_10bit.asm
  27. +248
    -102
      libswscale/swscale.c

+ 7
- 0
Makefile View File

@@ -2,6 +2,11 @@ include config.mak


SRC_DIR = $(SRC_PATH_BARE) SRC_DIR = $(SRC_PATH_BARE)


vpath %.c $(SRC_DIR)
vpath %.h $(SRC_DIR)
vpath %.S $(SRC_DIR)
vpath %.asm $(SRC_DIR)
vpath %.v $(SRC_DIR)
vpath %.texi $(SRC_PATH_BARE) vpath %.texi $(SRC_PATH_BARE)


PROGS-$(CONFIG_FFMPEG) += ffmpeg PROGS-$(CONFIG_FFMPEG) += ffmpeg
@@ -24,6 +29,8 @@ ALLPROGS = $(BASENAMES:%=%$(EXESUF))
ALLPROGS_G = $(BASENAMES:%=%_g$(EXESUF)) ALLPROGS_G = $(BASENAMES:%=%_g$(EXESUF))
ALLMANPAGES = $(BASENAMES:%=%.1) ALLMANPAGES = $(BASENAMES:%=%.1)


ALLFFLIBS = avcodec avdevice avfilter avformat avutil postproc swscale

FFLIBS-$(CONFIG_AVDEVICE) += avdevice FFLIBS-$(CONFIG_AVDEVICE) += avdevice
FFLIBS-$(CONFIG_AVFILTER) += avfilter FFLIBS-$(CONFIG_AVFILTER) += avfilter
FFLIBS-$(CONFIG_AVFORMAT) += avformat FFLIBS-$(CONFIG_AVFORMAT) += avformat


+ 0
- 7
common.mak View File

@@ -6,11 +6,6 @@
all: all-yes all: all-yes


ifndef SUBDIR ifndef SUBDIR
vpath %.c $(SRC_DIR)
vpath %.h $(SRC_DIR)
vpath %.S $(SRC_DIR)
vpath %.asm $(SRC_DIR)
vpath %.v $(SRC_DIR)


ifndef V ifndef V
Q = @ Q = @
@@ -25,8 +20,6 @@ $(foreach VAR,$(SILENT),$(eval override $(VAR) = @$($(VAR))))
$(eval INSTALL = @$(call ECHO,INSTALL,$$(^:$(SRC_DIR)/%=%)); $(INSTALL)) $(eval INSTALL = @$(call ECHO,INSTALL,$$(^:$(SRC_DIR)/%=%)); $(INSTALL))
endif endif


ALLFFLIBS = avcodec avdevice avfilter avformat avutil postproc swscale

IFLAGS := -I. -I$(SRC_PATH) IFLAGS := -I. -I$(SRC_PATH)
CPPFLAGS := $(IFLAGS) $(CPPFLAGS) CPPFLAGS := $(IFLAGS) $(CPPFLAGS)
CFLAGS += $(ECFLAGS) CFLAGS += $(ECFLAGS)


+ 7
- 9
libavcodec/ac3enc.c View File

@@ -2215,15 +2215,9 @@ static av_cold int allocate_buffers(AVCodecContext *avctx)
AC3EncodeContext *s = avctx->priv_data; AC3EncodeContext *s = avctx->priv_data;
int channels = s->channels + 1; /* includes coupling channel */ int channels = s->channels + 1; /* includes coupling channel */


FF_ALLOC_OR_GOTO(avctx, s->windowed_samples, AC3_WINDOW_SIZE *
sizeof(*s->windowed_samples), alloc_fail);
FF_ALLOC_OR_GOTO(avctx, s->planar_samples, s->channels * sizeof(*s->planar_samples),
alloc_fail);
for (ch = 0; ch < s->channels; ch++) {
FF_ALLOCZ_OR_GOTO(avctx, s->planar_samples[ch],
(AC3_FRAME_SIZE+AC3_BLOCK_SIZE) * sizeof(**s->planar_samples),
alloc_fail);
}
if (s->allocate_sample_buffers(s))
goto alloc_fail;

FF_ALLOC_OR_GOTO(avctx, s->bap_buffer, AC3_MAX_BLOCKS * channels * FF_ALLOC_OR_GOTO(avctx, s->bap_buffer, AC3_MAX_BLOCKS * channels *
AC3_MAX_COEFS * sizeof(*s->bap_buffer), alloc_fail); AC3_MAX_COEFS * sizeof(*s->bap_buffer), alloc_fail);
FF_ALLOC_OR_GOTO(avctx, s->bap1_buffer, AC3_MAX_BLOCKS * channels * FF_ALLOC_OR_GOTO(avctx, s->bap1_buffer, AC3_MAX_BLOCKS * channels *
@@ -2323,6 +2317,8 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx)
AC3EncodeContext *s = avctx->priv_data; AC3EncodeContext *s = avctx->priv_data;
int ret, frame_size_58; int ret, frame_size_58;


s->avctx = avctx;

s->eac3 = avctx->codec_id == CODEC_ID_EAC3; s->eac3 = avctx->codec_id == CODEC_ID_EAC3;


avctx->frame_size = AC3_FRAME_SIZE; avctx->frame_size = AC3_FRAME_SIZE;
@@ -2355,6 +2351,7 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx)
s->apply_window = ff_ac3_fixed_apply_window; s->apply_window = ff_ac3_fixed_apply_window;
s->normalize_samples = ff_ac3_fixed_normalize_samples; s->normalize_samples = ff_ac3_fixed_normalize_samples;
s->scale_coefficients = ff_ac3_fixed_scale_coefficients; s->scale_coefficients = ff_ac3_fixed_scale_coefficients;
s->allocate_sample_buffers = ff_ac3_fixed_allocate_sample_buffers;
s->deinterleave_input_samples = ff_ac3_fixed_deinterleave_input_samples; s->deinterleave_input_samples = ff_ac3_fixed_deinterleave_input_samples;
s->apply_mdct = ff_ac3_fixed_apply_mdct; s->apply_mdct = ff_ac3_fixed_apply_mdct;
s->apply_channel_coupling = ff_ac3_fixed_apply_channel_coupling; s->apply_channel_coupling = ff_ac3_fixed_apply_channel_coupling;
@@ -2364,6 +2361,7 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx)
s->mdct_init = ff_ac3_float_mdct_init; s->mdct_init = ff_ac3_float_mdct_init;
s->apply_window = ff_ac3_float_apply_window; s->apply_window = ff_ac3_float_apply_window;
s->scale_coefficients = ff_ac3_float_scale_coefficients; s->scale_coefficients = ff_ac3_float_scale_coefficients;
s->allocate_sample_buffers = ff_ac3_float_allocate_sample_buffers;
s->deinterleave_input_samples = ff_ac3_float_deinterleave_input_samples; s->deinterleave_input_samples = ff_ac3_float_deinterleave_input_samples;
s->apply_mdct = ff_ac3_float_apply_mdct; s->apply_mdct = ff_ac3_float_apply_mdct;
s->apply_channel_coupling = ff_ac3_float_apply_channel_coupling; s->apply_channel_coupling = ff_ac3_float_apply_channel_coupling;


+ 5
- 0
libavcodec/ac3enc.h View File

@@ -135,6 +135,7 @@ typedef struct AC3Block {
typedef struct AC3EncodeContext { typedef struct AC3EncodeContext {
AVClass *av_class; ///< AVClass used for AVOption AVClass *av_class; ///< AVClass used for AVOption
AC3EncOptions options; ///< encoding options AC3EncOptions options; ///< encoding options
AVCodecContext *avctx; ///< parent AVCodecContext
PutBitContext pb; ///< bitstream writer context PutBitContext pb; ///< bitstream writer context
DSPContext dsp; DSPContext dsp;
AC3DSPContext ac3dsp; ///< AC-3 optimized functions AC3DSPContext ac3dsp; ///< AC-3 optimized functions
@@ -230,6 +231,7 @@ typedef struct AC3EncodeContext {
void (*scale_coefficients)(struct AC3EncodeContext *s); void (*scale_coefficients)(struct AC3EncodeContext *s);


/* fixed vs. float templated function pointers */ /* fixed vs. float templated function pointers */
int (*allocate_sample_buffers)(struct AC3EncodeContext *s);
void (*deinterleave_input_samples)(struct AC3EncodeContext *s, void (*deinterleave_input_samples)(struct AC3EncodeContext *s,
const SampleType *samples); const SampleType *samples);
void (*apply_mdct)(struct AC3EncodeContext *s); void (*apply_mdct)(struct AC3EncodeContext *s);
@@ -276,6 +278,9 @@ void ff_ac3_float_scale_coefficients(AC3EncodeContext *s);


/* prototypes for functions in ac3enc_template.c */ /* prototypes for functions in ac3enc_template.c */


int ff_ac3_fixed_allocate_sample_buffers(AC3EncodeContext *s);
int ff_ac3_float_allocate_sample_buffers(AC3EncodeContext *s);

void ff_ac3_fixed_deinterleave_input_samples(AC3EncodeContext *s, void ff_ac3_fixed_deinterleave_input_samples(AC3EncodeContext *s,
const SampleType *samples); const SampleType *samples);
void ff_ac3_float_deinterleave_input_samples(AC3EncodeContext *s, void ff_ac3_float_deinterleave_input_samples(AC3EncodeContext *s,


+ 20
- 0
libavcodec/ac3enc_template.c View File

@@ -31,6 +31,26 @@
#include "ac3enc.h" #include "ac3enc.h"




int AC3_NAME(allocate_sample_buffers)(AC3EncodeContext *s)
{
int ch;

FF_ALLOC_OR_GOTO(s->avctx, s->windowed_samples, AC3_WINDOW_SIZE *
sizeof(*s->windowed_samples), alloc_fail);
FF_ALLOC_OR_GOTO(s->avctx, s->planar_samples, s->channels * sizeof(*s->planar_samples),
alloc_fail);
for (ch = 0; ch < s->channels; ch++) {
FF_ALLOCZ_OR_GOTO(s->avctx, s->planar_samples[ch],
(AC3_FRAME_SIZE+AC3_BLOCK_SIZE) * sizeof(**s->planar_samples),
alloc_fail);
}

return 0;
alloc_fail:
return AVERROR(ENOMEM);
}


/** /**
* Deinterleave input samples. * Deinterleave input samples.
* Channels are reordered from Libav's default order to AC-3 order. * Channels are reordered from Libav's default order to AC-3 order.


+ 2
- 1
libavcodec/arm/h264dsp_init_arm.c View File

@@ -122,7 +122,8 @@ static void ff_h264dsp_init_neon(H264DSPContext *c, const int bit_depth)
c->h264_idct_dc_add = ff_h264_idct_dc_add_neon; c->h264_idct_dc_add = ff_h264_idct_dc_add_neon;
c->h264_idct_add16 = ff_h264_idct_add16_neon; c->h264_idct_add16 = ff_h264_idct_add16_neon;
c->h264_idct_add16intra = ff_h264_idct_add16intra_neon; c->h264_idct_add16intra = ff_h264_idct_add16intra_neon;
c->h264_idct_add8 = ff_h264_idct_add8_neon;
//FIXME: reenable when asm is updated.
//c->h264_idct_add8 = ff_h264_idct_add8_neon;
c->h264_idct8_add = ff_h264_idct8_add_neon; c->h264_idct8_add = ff_h264_idct8_add_neon;
c->h264_idct8_dc_add = ff_h264_idct8_dc_add_neon; c->h264_idct8_dc_add = ff_h264_idct8_dc_add_neon;
c->h264_idct8_add4 = ff_h264_idct8_add4_neon; c->h264_idct8_add4 = ff_h264_idct8_add4_neon;


+ 23
- 38
libavcodec/arm/mpegvideo_armv5te_s.S View File

@@ -35,6 +35,21 @@
* *
* Inner loop should take 6 cycles per element on arm926ej-s (Nokia 770) * Inner loop should take 6 cycles per element on arm926ej-s (Nokia 770)
*/ */

.macro dequant_t dst, src, mul, add, tmp
rsbs \tmp, ip, \src, asr #16
addgt \tmp, \add, #0
rsblt \tmp, \add, #0
smlatbne \dst, \src, \mul, \tmp
.endm

.macro dequant_b dst, src, mul, add, tmp
rsbs \tmp, ip, \src, lsl #16
addgt \tmp, \add, #0
rsblt \tmp, \add, #0
smlabbne \dst, \src, \mul, \tmp
.endm

function ff_dct_unquantize_h263_armv5te, export=1 function ff_dct_unquantize_h263_armv5te, export=1
push {r4-r9,lr} push {r4-r9,lr}
mov ip, #0 mov ip, #0
@@ -44,50 +59,20 @@ function ff_dct_unquantize_h263_armv5te, export=1
1: 1:
ldrd r6, [r0, #8] ldrd r6, [r0, #8]


rsbs r9, ip, r4, asr #16
addgt r9, r2, #0
rsblt r9, r2, #0
smlatbne r9, r4, r1, r9

rsbs lr, ip, r5, asr #16
addgt lr, r2, #0
rsblt lr, r2, #0
smlatbne lr, r5, r1, lr

rsbs r8, ip, r4, asl #16
addgt r8, r2, #0
rsblt r8, r2, #0
smlabbne r4, r4, r1, r8

rsbs r8, ip, r5, asl #16
addgt r8, r2, #0
rsblt r8, r2, #0
smlabbne r5, r5, r1, r8
dequant_t r9, r4, r1, r2, r9
dequant_t lr, r5, r1, r2, lr
dequant_b r4, r4, r1, r2, r8
dequant_b r5, r5, r1, r2, r8


strh r4, [r0], #2 strh r4, [r0], #2
strh r9, [r0], #2 strh r9, [r0], #2
strh r5, [r0], #2 strh r5, [r0], #2
strh lr, [r0], #2 strh lr, [r0], #2


rsbs r9, ip, r6, asr #16
addgt r9, r2, #0
rsblt r9, r2, #0
smlatbne r9, r6, r1, r9

rsbs lr, ip, r7, asr #16
addgt lr, r2, #0
rsblt lr, r2, #0
smlatbne lr, r7, r1, lr

rsbs r8, ip, r6, asl #16
addgt r8, r2, #0
rsblt r8, r2, #0
smlabbne r6, r6, r1, r8

rsbs r8, ip, r7, asl #16
addgt r8, r2, #0
rsblt r8, r2, #0
smlabbne r7, r7, r1, r8
dequant_t r9, r6, r1, r2, r9
dequant_t lr, r7, r1, r2, lr
dequant_b r6, r6, r1, r2, r8
dequant_b r7, r7, r1, r2, r8


strh r6, [r0], #2 strh r6, [r0], #2
strh r9, [r0], #2 strh r9, [r0], #2


+ 46
- 136
libavcodec/arm/simple_idct_armv5te.S View File

@@ -333,6 +333,20 @@ function idct_col_armv5te
ldr pc, [sp], #4 ldr pc, [sp], #4
endfunc endfunc


.macro clip dst, src:vararg
movs \dst, \src
movmi \dst, #0
cmp \dst, #255
movgt \dst, #255
.endm

.macro aclip dst, src:vararg
adds \dst, \src
movmi \dst, #0
cmp \dst, #255
movgt \dst, #255
.endm

function idct_col_put_armv5te function idct_col_put_armv5te
str lr, [sp, #-4]! str lr, [sp, #-4]!


@@ -341,27 +355,15 @@ function idct_col_put_armv5te
ldmfd sp!, {a3, a4} ldmfd sp!, {a3, a4}
ldr lr, [sp, #32] ldr lr, [sp, #32]
add a2, a3, v1 add a2, a3, v1
movs a2, a2, asr #20
movmi a2, #0
cmp a2, #255
movgt a2, #255
clip a2, a2, asr #20
add ip, a4, v2 add ip, a4, v2
movs ip, ip, asr #20
movmi ip, #0
cmp ip, #255
movgt ip, #255
clip ip, ip, asr #20
orr a2, a2, ip, lsl #8 orr a2, a2, ip, lsl #8
sub a3, a3, v1 sub a3, a3, v1
movs a3, a3, asr #20
movmi a3, #0
cmp a3, #255
movgt a3, #255
clip a3, a3, asr #20
sub a4, a4, v2 sub a4, a4, v2
movs a4, a4, asr #20
movmi a4, #0
cmp a4, #255
clip a4, a4, asr #20
ldr v1, [sp, #28] ldr v1, [sp, #28]
movgt a4, #255
strh a2, [v1] strh a2, [v1]
add a2, v1, #2 add a2, v1, #2
str a2, [sp, #28] str a2, [sp, #28]
@@ -371,79 +373,43 @@ function idct_col_put_armv5te
strh a2, [v2, v1]! strh a2, [v2, v1]!


sub a2, a3, v3 sub a2, a3, v3
movs a2, a2, asr #20
movmi a2, #0
cmp a2, #255
movgt a2, #255
clip a2, a2, asr #20
sub ip, a4, v4 sub ip, a4, v4
movs ip, ip, asr #20
movmi ip, #0
cmp ip, #255
movgt ip, #255
clip ip, ip, asr #20
orr a2, a2, ip, lsl #8 orr a2, a2, ip, lsl #8
strh a2, [v1, lr]! strh a2, [v1, lr]!
add a3, a3, v3 add a3, a3, v3
movs a2, a3, asr #20
movmi a2, #0
cmp a2, #255
movgt a2, #255
clip a2, a3, asr #20
add a4, a4, v4 add a4, a4, v4
movs a4, a4, asr #20
movmi a4, #0
cmp a4, #255
movgt a4, #255
clip a4, a4, asr #20
orr a2, a2, a4, lsl #8 orr a2, a2, a4, lsl #8
ldmfd sp!, {a3, a4} ldmfd sp!, {a3, a4}
strh a2, [v2, -lr]! strh a2, [v2, -lr]!


add a2, a3, v5 add a2, a3, v5
movs a2, a2, asr #20
movmi a2, #0
cmp a2, #255
movgt a2, #255
clip a2, a2, asr #20
add ip, a4, v6 add ip, a4, v6
movs ip, ip, asr #20
movmi ip, #0
cmp ip, #255
movgt ip, #255
clip ip, ip, asr #20
orr a2, a2, ip, lsl #8 orr a2, a2, ip, lsl #8
strh a2, [v1, lr]! strh a2, [v1, lr]!
sub a3, a3, v5 sub a3, a3, v5
movs a2, a3, asr #20
movmi a2, #0
cmp a2, #255
movgt a2, #255
clip a2, a3, asr #20
sub a4, a4, v6 sub a4, a4, v6
movs a4, a4, asr #20
movmi a4, #0
cmp a4, #255
movgt a4, #255
clip a4, a4, asr #20
orr a2, a2, a4, lsl #8 orr a2, a2, a4, lsl #8
ldmfd sp!, {a3, a4} ldmfd sp!, {a3, a4}
strh a2, [v2, -lr]! strh a2, [v2, -lr]!


add a2, a3, v7 add a2, a3, v7
movs a2, a2, asr #20
movmi a2, #0
cmp a2, #255
movgt a2, #255
clip a2, a2, asr #20
add ip, a4, fp add ip, a4, fp
movs ip, ip, asr #20
movmi ip, #0
cmp ip, #255
movgt ip, #255
clip ip, ip, asr #20
orr a2, a2, ip, lsl #8 orr a2, a2, ip, lsl #8
strh a2, [v1, lr] strh a2, [v1, lr]
sub a3, a3, v7 sub a3, a3, v7
movs a2, a3, asr #20
movmi a2, #0
cmp a2, #255
movgt a2, #255
clip a2, a3, asr #20
sub a4, a4, fp sub a4, a4, fp
movs a4, a4, asr #20
movmi a4, #0
cmp a4, #255
movgt a4, #255
clip a4, a4, asr #20
orr a2, a2, a4, lsl #8 orr a2, a2, a4, lsl #8
strh a2, [v2, -lr] strh a2, [v2, -lr]


@@ -460,36 +426,22 @@ function idct_col_add_armv5te
ldmfd sp!, {a3, a4} ldmfd sp!, {a3, a4}
ldrh ip, [lr] ldrh ip, [lr]
add a2, a3, v1 add a2, a3, v1
mov a2, a2, asr #20
sub a3, a3, v1 sub a3, a3, v1
and v1, ip, #255 and v1, ip, #255
adds a2, a2, v1
movmi a2, #0
cmp a2, #255
movgt a2, #255
aclip a2, v1, a2, asr #20
add v1, a4, v2 add v1, a4, v2
mov v1, v1, asr #20 mov v1, v1, asr #20
adds v1, v1, ip, lsr #8
movmi v1, #0
cmp v1, #255
movgt v1, #255
aclip v1, v1, ip, lsr #8
orr a2, a2, v1, lsl #8 orr a2, a2, v1, lsl #8
ldr v1, [sp, #32] ldr v1, [sp, #32]
sub a4, a4, v2 sub a4, a4, v2
rsb v2, v1, v1, lsl #3 rsb v2, v1, v1, lsl #3
ldrh ip, [v2, lr]! ldrh ip, [v2, lr]!
strh a2, [lr] strh a2, [lr]
mov a3, a3, asr #20
and a2, ip, #255 and a2, ip, #255
adds a3, a3, a2
movmi a3, #0
cmp a3, #255
movgt a3, #255
aclip a3, a2, a3, asr #20
mov a4, a4, asr #20 mov a4, a4, asr #20
adds a4, a4, ip, lsr #8
movmi a4, #0
cmp a4, #255
movgt a4, #255
aclip a4, a4, ip, lsr #8
add a2, lr, #2 add a2, lr, #2
str a2, [sp, #28] str a2, [sp, #28]
orr a2, a3, a4, lsl #8 orr a2, a3, a4, lsl #8
@@ -498,102 +450,60 @@ function idct_col_add_armv5te
ldmfd sp!, {a3, a4} ldmfd sp!, {a3, a4}
ldrh ip, [lr, v1]! ldrh ip, [lr, v1]!
sub a2, a3, v3 sub a2, a3, v3
mov a2, a2, asr #20
add a3, a3, v3 add a3, a3, v3
and v3, ip, #255 and v3, ip, #255
adds a2, a2, v3
movmi a2, #0
cmp a2, #255
movgt a2, #255
aclip a2, v3, a2, asr #20
sub v3, a4, v4 sub v3, a4, v4
mov v3, v3, asr #20 mov v3, v3, asr #20
adds v3, v3, ip, lsr #8
movmi v3, #0
cmp v3, #255
movgt v3, #255
aclip v3, v3, ip, lsr #8
orr a2, a2, v3, lsl #8 orr a2, a2, v3, lsl #8
add a4, a4, v4 add a4, a4, v4
ldrh ip, [v2, -v1]! ldrh ip, [v2, -v1]!
strh a2, [lr] strh a2, [lr]
mov a3, a3, asr #20
and a2, ip, #255 and a2, ip, #255
adds a3, a3, a2
movmi a3, #0
cmp a3, #255
movgt a3, #255
aclip a3, a2, a3, asr #20
mov a4, a4, asr #20 mov a4, a4, asr #20
adds a4, a4, ip, lsr #8
movmi a4, #0
cmp a4, #255
movgt a4, #255
aclip a4, a4, ip, lsr #8
orr a2, a3, a4, lsl #8 orr a2, a3, a4, lsl #8
strh a2, [v2] strh a2, [v2]


ldmfd sp!, {a3, a4} ldmfd sp!, {a3, a4}
ldrh ip, [lr, v1]! ldrh ip, [lr, v1]!
add a2, a3, v5 add a2, a3, v5
mov a2, a2, asr #20
sub a3, a3, v5 sub a3, a3, v5
and v3, ip, #255 and v3, ip, #255
adds a2, a2, v3
movmi a2, #0
cmp a2, #255
movgt a2, #255
aclip a2, v3, a2, asr #20
add v3, a4, v6 add v3, a4, v6
mov v3, v3, asr #20 mov v3, v3, asr #20
adds v3, v3, ip, lsr #8
movmi v3, #0
cmp v3, #255
movgt v3, #255
aclip v3, v3, ip, lsr #8
orr a2, a2, v3, lsl #8 orr a2, a2, v3, lsl #8
sub a4, a4, v6 sub a4, a4, v6
ldrh ip, [v2, -v1]! ldrh ip, [v2, -v1]!
strh a2, [lr] strh a2, [lr]
mov a3, a3, asr #20
and a2, ip, #255 and a2, ip, #255
adds a3, a3, a2
movmi a3, #0
cmp a3, #255
movgt a3, #255
aclip a3, a2, a3, asr #20
mov a4, a4, asr #20 mov a4, a4, asr #20
adds a4, a4, ip, lsr #8
movmi a4, #0
cmp a4, #255
movgt a4, #255
aclip a4, a4, ip, lsr #8
orr a2, a3, a4, lsl #8 orr a2, a3, a4, lsl #8
strh a2, [v2] strh a2, [v2]


ldmfd sp!, {a3, a4} ldmfd sp!, {a3, a4}
ldrh ip, [lr, v1]! ldrh ip, [lr, v1]!
add a2, a3, v7 add a2, a3, v7
mov a2, a2, asr #20
sub a3, a3, v7 sub a3, a3, v7
and v3, ip, #255 and v3, ip, #255
adds a2, a2, v3
movmi a2, #0
cmp a2, #255
movgt a2, #255
aclip a2, v3, a2, asr #20
add v3, a4, fp add v3, a4, fp
mov v3, v3, asr #20 mov v3, v3, asr #20
adds v3, v3, ip, lsr #8
movmi v3, #0
cmp v3, #255
movgt v3, #255
aclip v3, v3, ip, lsr #8
orr a2, a2, v3, lsl #8 orr a2, a2, v3, lsl #8
sub a4, a4, fp sub a4, a4, fp
ldrh ip, [v2, -v1]! ldrh ip, [v2, -v1]!
strh a2, [lr] strh a2, [lr]
mov a3, a3, asr #20
and a2, ip, #255 and a2, ip, #255
adds a3, a3, a2
movmi a3, #0
cmp a3, #255
movgt a3, #255
aclip a3, a2, a3, asr #20
mov a4, a4, asr #20 mov a4, a4, asr #20
adds a4, a4, ip, lsr #8
movmi a4, #0
cmp a4, #255
movgt a4, #255
aclip a4, a4, ip, lsr #8
orr a2, a3, a4, lsl #8 orr a2, a3, a4, lsl #8
strh a2, [v2] strh a2, [v2]




+ 1
- 1
libavcodec/dsputil.h View File

@@ -505,7 +505,7 @@ typedef struct DSPContext {
#define BASIS_SHIFT 16 #define BASIS_SHIFT 16
#define RECON_SHIFT 6 #define RECON_SHIFT 6


void (*draw_edges)(uint8_t *buf, int wrap, int width, int height, int w, int sides);
void (*draw_edges)(uint8_t *buf, int wrap, int width, int height, int w, int h, int sides);
#define EDGE_WIDTH 16 #define EDGE_WIDTH 16
#define EDGE_TOP 1 #define EDGE_TOP 1
#define EDGE_BOTTOM 2 #define EDGE_BOTTOM 2


+ 3
- 3
libavcodec/dsputil_template.c View File

@@ -79,7 +79,7 @@ static inline void FUNC(copy_block16)(uint8_t *dst, const uint8_t *src, int dstS


/* draw the edges of width 'w' of an image of size width, height */ /* draw the edges of width 'w' of an image of size width, height */
//FIXME check that this is ok for mpeg4 interlaced //FIXME check that this is ok for mpeg4 interlaced
static void FUNCC(draw_edges)(uint8_t *p_buf, int p_wrap, int width, int height, int w, int sides)
static void FUNCC(draw_edges)(uint8_t *p_buf, int p_wrap, int width, int height, int w, int h, int sides)
{ {
pixel *buf = (pixel*)p_buf; pixel *buf = (pixel*)p_buf;
int wrap = p_wrap / sizeof(pixel); int wrap = p_wrap / sizeof(pixel);
@@ -106,10 +106,10 @@ static void FUNCC(draw_edges)(uint8_t *p_buf, int p_wrap, int width, int height,
buf -= w; buf -= w;
last_line = buf + (height - 1) * wrap; last_line = buf + (height - 1) * wrap;
if (sides & EDGE_TOP) if (sides & EDGE_TOP)
for(i = 0; i < w; i++)
for(i = 0; i < h; i++)
memcpy(buf - (i + 1) * wrap, buf, (width + w + w) * sizeof(pixel)); // top memcpy(buf - (i + 1) * wrap, buf, (width + w + w) * sizeof(pixel)); // top
if (sides & EDGE_BOTTOM) if (sides & EDGE_BOTTOM)
for (i = 0; i < w; i++)
for (i = 0; i < h; i++)
memcpy(last_line + (i + 1) * wrap, last_line, (width + w + w) * sizeof(pixel)); // bottom memcpy(last_line + (i + 1) * wrap, last_line, (width + w + w) * sizeof(pixel)); // bottom
} }




+ 519
- 288
libavcodec/h264.c
File diff suppressed because it is too large
View File


+ 100
- 81
libavcodec/h264.h View File

@@ -39,9 +39,6 @@
#define interlaced_dct interlaced_dct_is_a_bad_name #define interlaced_dct interlaced_dct_is_a_bad_name
#define mb_intra mb_intra_is_not_initialized_see_mb_type #define mb_intra mb_intra_is_not_initialized_see_mb_type


#define LUMA_DC_BLOCK_INDEX 24
#define CHROMA_DC_BLOCK_INDEX 25

#define CHROMA_DC_COEFF_TOKEN_VLC_BITS 8 #define CHROMA_DC_COEFF_TOKEN_VLC_BITS 8
#define COEFF_TOKEN_VLC_BITS 8 #define COEFF_TOKEN_VLC_BITS 8
#define TOTAL_ZEROS_VLC_BITS 9 #define TOTAL_ZEROS_VLC_BITS 9
@@ -60,8 +57,6 @@
* of progressive decoding by about 2%. */ * of progressive decoding by about 2%. */
#define ALLOW_INTERLACE #define ALLOW_INTERLACE


#define ALLOW_NOCHROMA

#define FMO 0 #define FMO 0


/** /**
@@ -85,16 +80,12 @@
#endif #endif
#define FIELD_OR_MBAFF_PICTURE (FRAME_MBAFF || FIELD_PICTURE) #define FIELD_OR_MBAFF_PICTURE (FRAME_MBAFF || FIELD_PICTURE)


#ifdef ALLOW_NOCHROMA
#define CHROMA h->sps.chroma_format_idc
#else
#define CHROMA 1
#endif

#ifndef CABAC #ifndef CABAC
#define CABAC h->pps.cabac #define CABAC h->pps.cabac
#endif #endif


#define CHROMA444 (h->sps.chroma_format_idc == 3)

#define EXTENDED_SAR 255 #define EXTENDED_SAR 255


#define MB_TYPE_REF0 MB_TYPE_ACPRED //dirty but it fits in 16 bit #define MB_TYPE_REF0 MB_TYPE_ACPRED //dirty but it fits in 16 bit
@@ -198,7 +189,7 @@ typedef struct SPS{
int num_reorder_frames; int num_reorder_frames;
int scaling_matrix_present; int scaling_matrix_present;
uint8_t scaling_matrix4[6][16]; uint8_t scaling_matrix4[6][16];
uint8_t scaling_matrix8[2][64];
uint8_t scaling_matrix8[6][64];
int nal_hrd_parameters_present_flag; int nal_hrd_parameters_present_flag;
int vcl_hrd_parameters_present_flag; int vcl_hrd_parameters_present_flag;
int pic_struct_present_flag; int pic_struct_present_flag;
@@ -233,7 +224,7 @@ typedef struct PPS{
int redundant_pic_cnt_present; ///< redundant_pic_cnt_present_flag int redundant_pic_cnt_present; ///< redundant_pic_cnt_present_flag
int transform_8x8_mode; ///< transform_8x8_mode_flag int transform_8x8_mode; ///< transform_8x8_mode_flag
uint8_t scaling_matrix4[6][16]; uint8_t scaling_matrix4[6][16];
uint8_t scaling_matrix8[2][64];
uint8_t scaling_matrix8[6][64];
uint8_t chroma_qp_table[2][64]; ///< pre-scaled (with chroma_qp_index_offset) version of qp_table uint8_t chroma_qp_table[2][64]; ///< pre-scaled (with chroma_qp_index_offset) version of qp_table
int chroma_qp_diff; int chroma_qp_diff;
}PPS; }PPS;
@@ -298,21 +289,15 @@ typedef struct H264Context{
unsigned int top_samples_available; unsigned int top_samples_available;
unsigned int topright_samples_available; unsigned int topright_samples_available;
unsigned int left_samples_available; unsigned int left_samples_available;
uint8_t (*top_borders[2])[(16+2*8)*2];
uint8_t (*top_borders[2])[(16*3)*2];


/** /**
* non zero coeff count cache. * non zero coeff count cache.
* is 64 if not available. * is 64 if not available.
*/ */
DECLARE_ALIGNED(8, uint8_t, non_zero_count_cache)[6*8];
DECLARE_ALIGNED(8, uint8_t, non_zero_count_cache)[15*8];


/*
.UU.YYYY
.UU.YYYY
.vv.YYYY
.VV.YYYY
*/
uint8_t (*non_zero_count)[32];
uint8_t (*non_zero_count)[48];


/** /**
* Motion vector cache. * Motion vector cache.
@@ -336,7 +321,7 @@ typedef struct H264Context{
* block_offset[ 0..23] for frame macroblocks * block_offset[ 0..23] for frame macroblocks
* block_offset[24..47] for field macroblocks * block_offset[24..47] for field macroblocks
*/ */
int block_offset[2*(16+8)];
int block_offset[2*(16*3)];


uint32_t *mb2b_xy; //FIXME are these 4 a good idea? uint32_t *mb2b_xy; //FIXME are these 4 a good idea?
uint32_t *mb2br_xy; uint32_t *mb2br_xy;
@@ -356,9 +341,9 @@ typedef struct H264Context{
PPS pps; //FIXME move to Picture perhaps? (->no) do we need that? PPS pps; //FIXME move to Picture perhaps? (->no) do we need that?


uint32_t dequant4_buffer[6][QP_MAX_NUM+1][16]; //FIXME should these be moved down? uint32_t dequant4_buffer[6][QP_MAX_NUM+1][16]; //FIXME should these be moved down?
uint32_t dequant8_buffer[2][QP_MAX_NUM+1][64];
uint32_t dequant8_buffer[6][QP_MAX_NUM+1][64];
uint32_t (*dequant4_coeff[6])[16]; uint32_t (*dequant4_coeff[6])[16];
uint32_t (*dequant8_coeff[2])[64];
uint32_t (*dequant8_coeff[6])[64];


int slice_num; int slice_num;
uint16_t *slice_table; ///< slice_table_base + 2*mb_stride + 1 uint16_t *slice_table; ///< slice_table_base + 2*mb_stride + 1
@@ -408,15 +393,15 @@ typedef struct H264Context{
GetBitContext *intra_gb_ptr; GetBitContext *intra_gb_ptr;
GetBitContext *inter_gb_ptr; GetBitContext *inter_gb_ptr;


DECLARE_ALIGNED(16, DCTELEM, mb)[16*24*2]; ///< as a dct coeffecient is int32_t in high depth, we need to reserve twice the space.
DECLARE_ALIGNED(16, DCTELEM, mb_luma_dc)[16*2];
DECLARE_ALIGNED(16, DCTELEM, mb)[16*48*2]; ///< as a dct coeffecient is int32_t in high depth, we need to reserve twice the space.
DECLARE_ALIGNED(16, DCTELEM, mb_luma_dc)[3][16*2];
DCTELEM mb_padding[256*2]; ///< as mb is addressed by scantable[i] and scantable is uint8_t we can either check that i is not too large or ensure that there is some unused stuff after mb DCTELEM mb_padding[256*2]; ///< as mb is addressed by scantable[i] and scantable is uint8_t we can either check that i is not too large or ensure that there is some unused stuff after mb


/** /**
* Cabac * Cabac
*/ */
CABACContext cabac; CABACContext cabac;
uint8_t cabac_state[460];
uint8_t cabac_state[1024];


/* 0x100 -> non null luma_dc, 0x80/0x40 -> non null chroma_dc (cb/cr), 0x?0 -> chroma_cbp(0,1,2), 0x0? luma_cbp */ /* 0x100 -> non null luma_dc, 0x80/0x40 -> non null chroma_dc (cb/cr), 0x?0 -> chroma_cbp(0,1,2), 0x0? luma_cbp */
uint16_t *cbp_table; uint16_t *cbp_table;
@@ -721,27 +706,43 @@ o-o o-o
*/ */


/* Scan8 organization: /* Scan8 organization:
* 0 1 2 3 4 5 6 7
* 0 u u y y y y y
* 1 u U U y Y Y Y Y
* 2 u U U y Y Y Y Y
* 3 v v y Y Y Y Y
* 4 v V V y Y Y Y Y
* 5 v V V DYDUDV
* 0 1 2 3 4 5 6 7
* 0 DY y y y y y
* 1 y Y Y Y Y
* 2 y Y Y Y Y
* 3 y Y Y Y Y
* 4 y Y Y Y Y
* 5 DU u u u u u
* 6 u U U U U
* 7 u U U U U
* 8 u U U U U
* 9 u U U U U
* 10 DV v v v v v
* 11 v V V V V
* 12 v V V V V
* 13 v V V V V
* 14 v V V V V
* DY/DU/DV are for luma/chroma DC. * DY/DU/DV are for luma/chroma DC.
*/ */


#define LUMA_DC_BLOCK_INDEX 48
#define CHROMA_DC_BLOCK_INDEX 49

//This table must be here because scan8[constant] must be known at compiletime //This table must be here because scan8[constant] must be known at compiletime
static const uint8_t scan8[16 + 2*4 + 3]={
4+1*8, 5+1*8, 4+2*8, 5+2*8,
6+1*8, 7+1*8, 6+2*8, 7+2*8,
4+3*8, 5+3*8, 4+4*8, 5+4*8,
6+3*8, 7+3*8, 6+4*8, 7+4*8,
1+1*8, 2+1*8,
1+2*8, 2+2*8,
1+4*8, 2+4*8,
1+5*8, 2+5*8,
4+5*8, 5+5*8, 6+5*8
static const uint8_t scan8[16*3 + 3]={
4+ 1*8, 5+ 1*8, 4+ 2*8, 5+ 2*8,
6+ 1*8, 7+ 1*8, 6+ 2*8, 7+ 2*8,
4+ 3*8, 5+ 3*8, 4+ 4*8, 5+ 4*8,
6+ 3*8, 7+ 3*8, 6+ 4*8, 7+ 4*8,
4+ 6*8, 5+ 6*8, 4+ 7*8, 5+ 7*8,
6+ 6*8, 7+ 6*8, 6+ 7*8, 7+ 7*8,
4+ 8*8, 5+ 8*8, 4+ 9*8, 5+ 9*8,
6+ 8*8, 7+ 8*8, 6+ 9*8, 7+ 9*8,
4+11*8, 5+11*8, 4+12*8, 5+12*8,
6+11*8, 7+11*8, 6+12*8, 7+12*8,
4+13*8, 5+13*8, 4+14*8, 5+14*8,
6+13*8, 7+13*8, 6+14*8, 7+14*8,
0+ 0*8, 0+ 5*8, 0+10*8
}; };


static av_always_inline uint32_t pack16to32(int a, int b){ static av_always_inline uint32_t pack16to32(int a, int b){
@@ -773,11 +774,11 @@ static void fill_decode_neighbors(H264Context *h, int mb_type){
MpegEncContext * const s = &h->s; MpegEncContext * const s = &h->s;
const int mb_xy= h->mb_xy; const int mb_xy= h->mb_xy;
int topleft_xy, top_xy, topright_xy, left_xy[2]; int topleft_xy, top_xy, topright_xy, left_xy[2];
static const uint8_t left_block_options[4][16]={
{0,1,2,3,7,10,8,11,7+0*8, 7+1*8, 7+2*8, 7+3*8, 2+0*8, 2+3*8, 2+1*8, 2+2*8},
{2,2,3,3,8,11,8,11,7+2*8, 7+2*8, 7+3*8, 7+3*8, 2+1*8, 2+2*8, 2+1*8, 2+2*8},
{0,0,1,1,7,10,7,10,7+0*8, 7+0*8, 7+1*8, 7+1*8, 2+0*8, 2+3*8, 2+0*8, 2+3*8},
{0,2,0,2,7,10,7,10,7+0*8, 7+2*8, 7+0*8, 7+2*8, 2+0*8, 2+3*8, 2+0*8, 2+3*8}
static const uint8_t left_block_options[4][32]={
{0,1,2,3,7,10,8,11,3+0*4, 3+1*4, 3+2*4, 3+3*4, 1+4*4, 1+8*4, 1+5*4, 1+9*4},
{2,2,3,3,8,11,8,11,3+2*4, 3+2*4, 3+3*4, 3+3*4, 1+5*4, 1+9*4, 1+5*4, 1+9*4},
{0,0,1,1,7,10,7,10,3+0*4, 3+0*4, 3+1*4, 3+1*4, 1+4*4, 1+8*4, 1+4*4, 1+8*4},
{0,2,0,2,7,10,7,10,3+0*4, 3+2*4, 3+0*4, 3+2*4, 1+4*4, 1+8*4, 1+4*4, 1+8*4}
}; };


h->topleft_partition= -1; h->topleft_partition= -1;
@@ -947,32 +948,41 @@ static void fill_decode_caches(H264Context *h, int mb_type){
*/ */
//FIXME constraint_intra_pred & partitioning & nnz (let us hope this is just a typo in the spec) //FIXME constraint_intra_pred & partitioning & nnz (let us hope this is just a typo in the spec)
if(top_type){ if(top_type){
AV_COPY32(&h->non_zero_count_cache[4+8*0], &h->non_zero_count[top_xy][4+3*8]);
h->non_zero_count_cache[1+8*0]= h->non_zero_count[top_xy][1+1*8];
h->non_zero_count_cache[2+8*0]= h->non_zero_count[top_xy][2+1*8];
h->non_zero_count_cache[1+8*3]= h->non_zero_count[top_xy][1+2*8];
h->non_zero_count_cache[2+8*3]= h->non_zero_count[top_xy][2+2*8];
}else {
h->non_zero_count_cache[1+8*0]=
h->non_zero_count_cache[2+8*0]=
h->non_zero_count_cache[1+8*3]=
h->non_zero_count_cache[2+8*3]=
AV_WN32A(&h->non_zero_count_cache[4+8*0], CABAC && !IS_INTRA(mb_type) ? 0 : 0x40404040);
AV_COPY32(&h->non_zero_count_cache[4+8* 0], &h->non_zero_count[top_xy][4*3]);
if(CHROMA444){
AV_COPY32(&h->non_zero_count_cache[4+8* 5], &h->non_zero_count[top_xy][4* 7]);
AV_COPY32(&h->non_zero_count_cache[4+8*10], &h->non_zero_count[top_xy][4*11]);
}else{
AV_COPY32(&h->non_zero_count_cache[4+8* 5], &h->non_zero_count[top_xy][4* 5]);
AV_COPY32(&h->non_zero_count_cache[4+8*10], &h->non_zero_count[top_xy][4* 9]);
}
}else{
uint32_t top_empty = CABAC && !IS_INTRA(mb_type) ? 0 : 0x40404040;
AV_WN32A(&h->non_zero_count_cache[4+8* 0], top_empty);
AV_WN32A(&h->non_zero_count_cache[4+8* 5], top_empty);
AV_WN32A(&h->non_zero_count_cache[4+8*10], top_empty);
} }


for (i=0; i<2; i++) { for (i=0; i<2; i++) {
if(left_type[i]){ if(left_type[i]){
h->non_zero_count_cache[3+8*1 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[8+0+2*i]];
h->non_zero_count_cache[3+8*2 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[8+1+2*i]];
h->non_zero_count_cache[0+8*1 + 8*i]= h->non_zero_count[left_xy[i]][left_block[8+4+2*i]];
h->non_zero_count_cache[0+8*4 + 8*i]= h->non_zero_count[left_xy[i]][left_block[8+5+2*i]];
h->non_zero_count_cache[3+8* 1 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[8+0+2*i]];
h->non_zero_count_cache[3+8* 2 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[8+1+2*i]];
if(CHROMA444){
h->non_zero_count_cache[3+8* 6 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[8+0+2*i]+4*4];
h->non_zero_count_cache[3+8* 7 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[8+1+2*i]+4*4];
h->non_zero_count_cache[3+8*11 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[8+0+2*i]+8*4];
h->non_zero_count_cache[3+8*12 + 2*8*i]= h->non_zero_count[left_xy[i]][left_block[8+1+2*i]+8*4];
}else{
h->non_zero_count_cache[3+8* 6 + 8*i]= h->non_zero_count[left_xy[i]][left_block[8+4+2*i]];
h->non_zero_count_cache[3+8*11 + 8*i]= h->non_zero_count[left_xy[i]][left_block[8+5+2*i]];
}
}else{ }else{
h->non_zero_count_cache[3+8*1 + 2*8*i]=
h->non_zero_count_cache[3+8*2 + 2*8*i]=
h->non_zero_count_cache[0+8*1 + 8*i]=
h->non_zero_count_cache[0+8*4 + 8*i]= CABAC && !IS_INTRA(mb_type) ? 0 : 64;
h->non_zero_count_cache[3+8* 1 + 2*8*i]=
h->non_zero_count_cache[3+8* 2 + 2*8*i]=
h->non_zero_count_cache[3+8* 6 + 2*8*i]=
h->non_zero_count_cache[3+8* 7 + 2*8*i]=
h->non_zero_count_cache[3+8*11 + 2*8*i]=
h->non_zero_count_cache[3+8*12 + 2*8*i]= CABAC && !IS_INTRA(mb_type) ? 0 : 64;
} }
} }


@@ -981,15 +991,15 @@ static void fill_decode_caches(H264Context *h, int mb_type){
if(top_type) { if(top_type) {
h->top_cbp = h->cbp_table[top_xy]; h->top_cbp = h->cbp_table[top_xy];
} else { } else {
h->top_cbp = IS_INTRA(mb_type) ? 0x1CF : 0x00F;
h->top_cbp = IS_INTRA(mb_type) ? 0x7CF : 0x00F;
} }
// left_cbp // left_cbp
if (left_type[0]) { if (left_type[0]) {
h->left_cbp = (h->cbp_table[left_xy[0]] & 0x1f0)
h->left_cbp = (h->cbp_table[left_xy[0]] & 0x7F0)
| ((h->cbp_table[left_xy[0]]>>(left_block[0]&(~1)))&2) | ((h->cbp_table[left_xy[0]]>>(left_block[0]&(~1)))&2)
| (((h->cbp_table[left_xy[1]]>>(left_block[2]&(~1)))&2) << 2); | (((h->cbp_table[left_xy[1]]>>(left_block[2]&(~1)))&2) << 2);
} else { } else {
h->left_cbp = IS_INTRA(mb_type) ? 0x1CF : 0x00F;
h->left_cbp = IS_INTRA(mb_type) ? 0x7CF : 0x00F;
} }
} }
} }
@@ -1190,11 +1200,21 @@ static inline int pred_intra_mode(H264Context *h, int n){
static inline void write_back_non_zero_count(H264Context *h){ static inline void write_back_non_zero_count(H264Context *h){
const int mb_xy= h->mb_xy; const int mb_xy= h->mb_xy;


AV_COPY64(&h->non_zero_count[mb_xy][ 0], &h->non_zero_count_cache[0+8*1]);
AV_COPY64(&h->non_zero_count[mb_xy][ 8], &h->non_zero_count_cache[0+8*2]);
AV_COPY32(&h->non_zero_count[mb_xy][16], &h->non_zero_count_cache[0+8*5]);
AV_COPY32(&h->non_zero_count[mb_xy][20], &h->non_zero_count_cache[4+8*3]);
AV_COPY64(&h->non_zero_count[mb_xy][24], &h->non_zero_count_cache[0+8*4]);
AV_COPY32(&h->non_zero_count[mb_xy][ 0], &h->non_zero_count_cache[4+8* 1]);
AV_COPY32(&h->non_zero_count[mb_xy][ 4], &h->non_zero_count_cache[4+8* 2]);
AV_COPY32(&h->non_zero_count[mb_xy][ 8], &h->non_zero_count_cache[4+8* 3]);
AV_COPY32(&h->non_zero_count[mb_xy][12], &h->non_zero_count_cache[4+8* 4]);
AV_COPY32(&h->non_zero_count[mb_xy][16], &h->non_zero_count_cache[4+8* 6]);
AV_COPY32(&h->non_zero_count[mb_xy][20], &h->non_zero_count_cache[4+8* 7]);
AV_COPY32(&h->non_zero_count[mb_xy][32], &h->non_zero_count_cache[4+8*11]);
AV_COPY32(&h->non_zero_count[mb_xy][36], &h->non_zero_count_cache[4+8*12]);

if(CHROMA444){
AV_COPY32(&h->non_zero_count[mb_xy][24], &h->non_zero_count_cache[4+8* 8]);
AV_COPY32(&h->non_zero_count[mb_xy][28], &h->non_zero_count_cache[4+8* 9]);
AV_COPY32(&h->non_zero_count[mb_xy][40], &h->non_zero_count_cache[4+8*13]);
AV_COPY32(&h->non_zero_count[mb_xy][44], &h->non_zero_count_cache[4+8*14]);
}
} }


static inline void write_back_motion(H264Context *h, int mb_type){ static inline void write_back_motion(H264Context *h, int mb_type){
@@ -1267,8 +1287,7 @@ static void av_unused decode_mb_skip(H264Context *h){
const int mb_xy= h->mb_xy; const int mb_xy= h->mb_xy;
int mb_type=0; int mb_type=0;


memset(h->non_zero_count[mb_xy], 0, 32);
memset(h->non_zero_count_cache + 8, 0, 8*5); //FIXME ugly, remove pfui
memset(h->non_zero_count[mb_xy], 0, 48);


if(MB_FIELD) if(MB_FIELD)
mb_type|= MB_TYPE_INTERLACED; mb_type|= MB_TYPE_INTERLACED;


+ 714
- 101
libavcodec/h264_cabac.c
File diff suppressed because it is too large
View File


+ 117
- 81
libavcodec/h264_cavlc.c View File

@@ -371,12 +371,12 @@ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, in


//FIXME put trailing_onex into the context //FIXME put trailing_onex into the context


if(n >= CHROMA_DC_BLOCK_INDEX){
if(max_coeff <= 8){
coeff_token= get_vlc2(gb, chroma_dc_coeff_token_vlc.table, CHROMA_DC_COEFF_TOKEN_VLC_BITS, 1); coeff_token= get_vlc2(gb, chroma_dc_coeff_token_vlc.table, CHROMA_DC_COEFF_TOKEN_VLC_BITS, 1);
total_coeff= coeff_token>>2; total_coeff= coeff_token>>2;
}else{ }else{
if(n == LUMA_DC_BLOCK_INDEX){
total_coeff= pred_non_zero_count(h, 0);
if(n >= LUMA_DC_BLOCK_INDEX){
total_coeff= pred_non_zero_count(h, (n - LUMA_DC_BLOCK_INDEX)*16);
coeff_token= get_vlc2(gb, coeff_token_vlc[ coeff_token_table_index[total_coeff] ].table, COEFF_TOKEN_VLC_BITS, 2); coeff_token= get_vlc2(gb, coeff_token_vlc[ coeff_token_table_index[total_coeff] ].table, COEFF_TOKEN_VLC_BITS, 2);
total_coeff= coeff_token>>2; total_coeff= coeff_token>>2;
}else{ }else{
@@ -482,7 +482,8 @@ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, in
if(total_coeff == max_coeff) if(total_coeff == max_coeff)
zeros_left=0; zeros_left=0;
else{ else{
if(n >= CHROMA_DC_BLOCK_INDEX)
/* FIXME: we don't actually support 4:2:2 yet. */
if(max_coeff <= 8)
zeros_left= get_vlc2(gb, (chroma_dc_total_zeros_vlc-1)[ total_coeff ].table, CHROMA_DC_TOTAL_ZEROS_VLC_BITS, 1); zeros_left= get_vlc2(gb, (chroma_dc_total_zeros_vlc-1)[ total_coeff ].table, CHROMA_DC_TOTAL_ZEROS_VLC_BITS, 1);
else else
zeros_left= get_vlc2(gb, (total_zeros_vlc-1)[ total_coeff ].table, TOTAL_ZEROS_VLC_BITS, 1); zeros_left= get_vlc2(gb, (total_zeros_vlc-1)[ total_coeff ].table, TOTAL_ZEROS_VLC_BITS, 1);
@@ -536,12 +537,80 @@ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, in
return 0; return 0;
} }


static av_always_inline int decode_luma_residual(H264Context *h, GetBitContext *gb, const uint8_t *scan, const uint8_t *scan8x8, int pixel_shift, int mb_type, int cbp, int p){
int i4x4, i8x8;
MpegEncContext * const s = &h->s;
int qscale = p == 0 ? s->qscale : h->chroma_qp[p-1];
if(IS_INTRA16x16(mb_type)){
AV_ZERO128(h->mb_luma_dc[p]+0);
AV_ZERO128(h->mb_luma_dc[p]+8);
AV_ZERO128(h->mb_luma_dc[p]+16);
AV_ZERO128(h->mb_luma_dc[p]+24);
if( decode_residual(h, h->intra_gb_ptr, h->mb_luma_dc[p], LUMA_DC_BLOCK_INDEX+p, scan, NULL, 16) < 0){
return -1; //FIXME continue if partitioned and other return -1 too
}

assert((cbp&15) == 0 || (cbp&15) == 15);

if(cbp&15){
for(i8x8=0; i8x8<4; i8x8++){
for(i4x4=0; i4x4<4; i4x4++){
const int index= i4x4 + 4*i8x8 + p*16;
if( decode_residual(h, h->intra_gb_ptr, h->mb + (16*index << pixel_shift),
index, scan + 1, h->dequant4_coeff[p][qscale], 15) < 0 ){
return -1;
}
}
}
return 0xf;
}else{
fill_rectangle(&h->non_zero_count_cache[scan8[p*16]], 4, 4, 8, 0, 1);
return 0;
}
}else{
int cqm = (IS_INTRA( mb_type ) ? 0:3)+p;
/* For CAVLC 4:4:4, we need to keep track of the luma 8x8 CBP for deblocking nnz purposes. */
int new_cbp = 0;
for(i8x8=0; i8x8<4; i8x8++){
if(cbp & (1<<i8x8)){
if(IS_8x8DCT(mb_type)){
DCTELEM *buf = &h->mb[64*i8x8+256*p << pixel_shift];
uint8_t *nnz;
for(i4x4=0; i4x4<4; i4x4++){
const int index= i4x4 + 4*i8x8 + p*16;
if( decode_residual(h, gb, buf, index, scan8x8+16*i4x4,
h->dequant8_coeff[cqm][qscale], 16) < 0 )
return -1;
}
nnz= &h->non_zero_count_cache[ scan8[4*i8x8+p*16] ];
nnz[0] += nnz[1] + nnz[8] + nnz[9];
new_cbp |= !!nnz[0] << i8x8;
}else{
for(i4x4=0; i4x4<4; i4x4++){
const int index= i4x4 + 4*i8x8 + p*16;
if( decode_residual(h, gb, h->mb + (16*index << pixel_shift), index,
scan, h->dequant4_coeff[cqm][qscale], 16) < 0 ){
return -1;
}
new_cbp |= h->non_zero_count_cache[ scan8[index] ] << i8x8;
}
}
}else{
uint8_t * const nnz= &h->non_zero_count_cache[ scan8[4*i8x8+p*16] ];
nnz[0] = nnz[1] = nnz[8] = nnz[9] = 0;
}
}
return new_cbp;
}
}

int ff_h264_decode_mb_cavlc(H264Context *h){ int ff_h264_decode_mb_cavlc(H264Context *h){
MpegEncContext * const s = &h->s; MpegEncContext * const s = &h->s;
int mb_xy; int mb_xy;
int partition_count; int partition_count;
unsigned int mb_type, cbp; unsigned int mb_type, cbp;
int dct8x8_allowed= h->pps.transform_8x8_mode; int dct8x8_allowed= h->pps.transform_8x8_mode;
int decode_chroma = h->sps.chroma_format_idc == 1 || h->sps.chroma_format_idc == 2;
const int pixel_shift = h->pixel_shift; const int pixel_shift = h->pixel_shift;


mb_xy = h->mb_xy = s->mb_x + s->mb_y*s->mb_stride; mb_xy = h->mb_xy = s->mb_x + s->mb_y*s->mb_stride;
@@ -608,19 +677,21 @@ decode_intra_mb:


if(IS_INTRA_PCM(mb_type)){ if(IS_INTRA_PCM(mb_type)){
unsigned int x; unsigned int x;
static const uint16_t mb_sizes[4] = {256,384,512,768};
const int mb_size = mb_sizes[h->sps.chroma_format_idc]*h->sps.bit_depth_luma >> 3;


// We assume these blocks are very rare so we do not optimize it. // We assume these blocks are very rare so we do not optimize it.
align_get_bits(&s->gb); align_get_bits(&s->gb);


// The pixels are stored in the same order as levels in h->mb array. // The pixels are stored in the same order as levels in h->mb array.
for(x=0; x < (CHROMA ? 384 : 256)*h->sps.bit_depth_luma/8; x++){
for(x=0; x < mb_size; x++){
((uint8_t*)h->mb)[x]= get_bits(&s->gb, 8); ((uint8_t*)h->mb)[x]= get_bits(&s->gb, 8);
} }


// In deblocking, the quantizer is 0 // In deblocking, the quantizer is 0
s->current_picture.qscale_table[mb_xy]= 0; s->current_picture.qscale_table[mb_xy]= 0;
// All coeffs are present // All coeffs are present
memset(h->non_zero_count[mb_xy], 16, 32);
memset(h->non_zero_count[mb_xy], 16, 48);


s->current_picture.mb_type[mb_xy]= mb_type; s->current_picture.mb_type[mb_xy]= mb_type;
return 0; return 0;
@@ -668,7 +739,7 @@ decode_intra_mb:
if(h->intra16x16_pred_mode < 0) if(h->intra16x16_pred_mode < 0)
return -1; return -1;
} }
if(CHROMA){
if(decode_chroma){
pred_mode= ff_h264_check_intra_pred_mode(h, get_ue_golomb_31(&s->gb)); pred_mode= ff_h264_check_intra_pred_mode(h, get_ue_golomb_31(&s->gb));
if(pred_mode < 0) if(pred_mode < 0)
return -1; return -1;
@@ -896,15 +967,19 @@ decode_intra_mb:


if(!IS_INTRA16x16(mb_type)){ if(!IS_INTRA16x16(mb_type)){
cbp= get_ue_golomb(&s->gb); cbp= get_ue_golomb(&s->gb);
if(cbp > 47){
av_log(h->s.avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, s->mb_x, s->mb_y);
return -1;
}


if(CHROMA){
if(decode_chroma){
if(cbp > 47){
av_log(h->s.avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, s->mb_x, s->mb_y);
return -1;
}
if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp[cbp]; if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp[cbp];
else cbp= golomb_to_inter_cbp [cbp]; else cbp= golomb_to_inter_cbp [cbp];
}else{ }else{
if(cbp > 15){
av_log(h->s.avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, s->mb_x, s->mb_y);
return -1;
}
if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp_gray[cbp]; if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp_gray[cbp];
else cbp= golomb_to_inter_cbp_gray[cbp]; else cbp= golomb_to_inter_cbp_gray[cbp];
} }
@@ -918,8 +993,9 @@ decode_intra_mb:
s->current_picture.mb_type[mb_xy]= mb_type; s->current_picture.mb_type[mb_xy]= mb_type;


if(cbp || IS_INTRA16x16(mb_type)){ if(cbp || IS_INTRA16x16(mb_type)){
int i8x8, i4x4, chroma_idx;
int i4x4, chroma_idx;
int dquant; int dquant;
int ret;
GetBitContext *gb= IS_INTRA(mb_type) ? h->intra_gb_ptr : h->inter_gb_ptr; GetBitContext *gb= IS_INTRA(mb_type) ? h->intra_gb_ptr : h->inter_gb_ptr;
const uint8_t *scan, *scan8x8; const uint8_t *scan, *scan8x8;
const int max_qp = 51 + 6*(h->sps.bit_depth_luma-8); const int max_qp = 51 + 6*(h->sps.bit_depth_luma-8);
@@ -947,85 +1023,45 @@ decode_intra_mb:


h->chroma_qp[0]= get_chroma_qp(h, 0, s->qscale); h->chroma_qp[0]= get_chroma_qp(h, 0, s->qscale);
h->chroma_qp[1]= get_chroma_qp(h, 1, s->qscale); h->chroma_qp[1]= get_chroma_qp(h, 1, s->qscale);
if(IS_INTRA16x16(mb_type)){
AV_ZERO128(h->mb_luma_dc+0);
AV_ZERO128(h->mb_luma_dc+8);
AV_ZERO128(h->mb_luma_dc+16);
AV_ZERO128(h->mb_luma_dc+24);
if( decode_residual(h, h->intra_gb_ptr, h->mb_luma_dc, LUMA_DC_BLOCK_INDEX, scan, h->dequant4_coeff[0][s->qscale], 16) < 0){
return -1; //FIXME continue if partitioned and other return -1 too
}


assert((cbp&15) == 0 || (cbp&15) == 15);
if( (ret = decode_luma_residual(h, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 0)) < 0 ){
return -1;
}
h->cbp_table[mb_xy] |= ret << 12;
if(CHROMA444){
if( decode_luma_residual(h, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 1) < 0 ){
return -1;
}
if( decode_luma_residual(h, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 2) < 0 ){
return -1;
}
} else {
if(cbp&0x30){
for(chroma_idx=0; chroma_idx<2; chroma_idx++)
if( decode_residual(h, gb, h->mb + ((256 + 16*16*chroma_idx) << pixel_shift), CHROMA_DC_BLOCK_INDEX+chroma_idx, chroma_dc_scan, NULL, 4) < 0){
return -1;
}
}


if(cbp&15){
for(i8x8=0; i8x8<4; i8x8++){
if(cbp&0x20){
for(chroma_idx=0; chroma_idx<2; chroma_idx++){
const uint32_t *qmul = h->dequant4_coeff[chroma_idx+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[chroma_idx]];
for(i4x4=0; i4x4<4; i4x4++){ for(i4x4=0; i4x4<4; i4x4++){
const int index= i4x4 + 4*i8x8;
if( decode_residual(h, h->intra_gb_ptr, h->mb + (16*index << pixel_shift), index, scan + 1, h->dequant4_coeff[0][s->qscale], 15) < 0 ){
const int index= 16 + 16*chroma_idx + i4x4;
if( decode_residual(h, gb, h->mb + (16*index << pixel_shift), index, scan + 1, qmul, 15) < 0){
return -1; return -1;
} }
} }
} }
}else{ }else{
fill_rectangle(&h->non_zero_count_cache[scan8[0]], 4, 4, 8, 0, 1);
fill_rectangle(&h->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);
fill_rectangle(&h->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);
} }
}else{
for(i8x8=0; i8x8<4; i8x8++){
if(cbp & (1<<i8x8)){
if(IS_8x8DCT(mb_type)){
DCTELEM *buf = &h->mb[64*i8x8 << pixel_shift];
uint8_t *nnz;
for(i4x4=0; i4x4<4; i4x4++){
if( decode_residual(h, gb, buf, i4x4+4*i8x8, scan8x8+16*i4x4,
h->dequant8_coeff[IS_INTRA( mb_type ) ? 0:1][s->qscale], 16) <0 )
return -1;
}
nnz= &h->non_zero_count_cache[ scan8[4*i8x8] ];
nnz[0] += nnz[1] + nnz[8] + nnz[9];
}else{
for(i4x4=0; i4x4<4; i4x4++){
const int index= i4x4 + 4*i8x8;

if( decode_residual(h, gb, h->mb + (16*index << pixel_shift), index, scan, h->dequant4_coeff[IS_INTRA( mb_type ) ? 0:3][s->qscale], 16) <0 ){
return -1;
}
}
}
}else{
uint8_t * const nnz= &h->non_zero_count_cache[ scan8[4*i8x8] ];
nnz[0] = nnz[1] = nnz[8] = nnz[9] = 0;
}
}
}

if(cbp&0x30){
for(chroma_idx=0; chroma_idx<2; chroma_idx++)
if( decode_residual(h, gb, h->mb + ((256 + 16*4*chroma_idx) << pixel_shift), CHROMA_DC_BLOCK_INDEX+chroma_idx, chroma_dc_scan, NULL, 4) < 0){
return -1;
}
}

if(cbp&0x20){
for(chroma_idx=0; chroma_idx<2; chroma_idx++){
const uint32_t *qmul = h->dequant4_coeff[chroma_idx+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp[chroma_idx]];
for(i4x4=0; i4x4<4; i4x4++){
const int index= 16 + 4*chroma_idx + i4x4;
if( decode_residual(h, gb, h->mb + (16*index << pixel_shift), index, scan + 1, qmul, 15) < 0){
return -1;
}
}
}
}else{
uint8_t * const nnz= &h->non_zero_count_cache[0];
nnz[ scan8[16]+0 ] = nnz[ scan8[16]+1 ] =nnz[ scan8[16]+8 ] =nnz[ scan8[16]+9 ] =
nnz[ scan8[20]+0 ] = nnz[ scan8[20]+1 ] =nnz[ scan8[20]+8 ] =nnz[ scan8[20]+9 ] = 0;
} }
}else{ }else{
uint8_t * const nnz= &h->non_zero_count_cache[0];
fill_rectangle(&nnz[scan8[0]], 4, 4, 8, 0, 1);
nnz[ scan8[16]+0 ] = nnz[ scan8[16]+1 ] =nnz[ scan8[16]+8 ] =nnz[ scan8[16]+9 ] =
nnz[ scan8[20]+0 ] = nnz[ scan8[20]+1 ] =nnz[ scan8[20]+8 ] =nnz[ scan8[20]+9 ] = 0;
fill_rectangle(&h->non_zero_count_cache[scan8[ 0]], 4, 4, 8, 0, 1);
fill_rectangle(&h->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);
fill_rectangle(&h->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);
} }
s->current_picture.qscale_table[mb_xy]= s->qscale; s->current_picture.qscale_table[mb_xy]= s->qscale;
write_back_non_zero_count(h); write_back_non_zero_count(h);


+ 82
- 50
libavcodec/h264_loopfilter.c View File

@@ -217,10 +217,11 @@ void ff_h264_filter_mb_fast( H264Context *h, int mb_x, int mb_y, uint8_t *img_y,
int mb_xy; int mb_xy;
int mb_type, left_type; int mb_type, left_type;
int qp, qp0, qp1, qpc, qpc0, qpc1, qp_thresh; int qp, qp0, qp1, qpc, qpc0, qpc1, qp_thresh;
int chroma = !(CONFIG_GRAY && (s->flags&CODEC_FLAG_GRAY));


mb_xy = h->mb_xy; mb_xy = h->mb_xy;


if(!h->top_type || !h->h264dsp.h264_loop_filter_strength || h->pps.chroma_qp_diff) {
if(!h->top_type || !h->h264dsp.h264_loop_filter_strength || h->pps.chroma_qp_diff || CHROMA444) {
ff_h264_filter_mb(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize); ff_h264_filter_mb(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize);
return; return;
} }
@@ -262,16 +263,18 @@ void ff_h264_filter_mb_fast( H264Context *h, int mb_x, int mb_y, uint8_t *img_y,
filter_mb_edgeh( &img_y[4*2*linesize], linesize, bS3, qp, h); filter_mb_edgeh( &img_y[4*2*linesize], linesize, bS3, qp, h);
filter_mb_edgeh( &img_y[4*3*linesize], linesize, bS3, qp, h); filter_mb_edgeh( &img_y[4*3*linesize], linesize, bS3, qp, h);
} }
if(left_type){
filter_mb_edgecv( &img_cb[2*0], uvlinesize, bS4, qpc0, h);
filter_mb_edgecv( &img_cr[2*0], uvlinesize, bS4, qpc0, h);
if(chroma){
if(left_type){
filter_mb_edgecv( &img_cb[2*0], uvlinesize, bS4, qpc0, h);
filter_mb_edgecv( &img_cr[2*0], uvlinesize, bS4, qpc0, h);
}
filter_mb_edgecv( &img_cb[2*2], uvlinesize, bS3, qpc, h);
filter_mb_edgecv( &img_cr[2*2], uvlinesize, bS3, qpc, h);
filter_mb_edgech( &img_cb[2*0*uvlinesize], uvlinesize, bSH, qpc1, h);
filter_mb_edgech( &img_cb[2*2*uvlinesize], uvlinesize, bS3, qpc, h);
filter_mb_edgech( &img_cr[2*0*uvlinesize], uvlinesize, bSH, qpc1, h);
filter_mb_edgech( &img_cr[2*2*uvlinesize], uvlinesize, bS3, qpc, h);
} }
filter_mb_edgecv( &img_cb[2*2], uvlinesize, bS3, qpc, h);
filter_mb_edgecv( &img_cr[2*2], uvlinesize, bS3, qpc, h);
filter_mb_edgech( &img_cb[2*0*uvlinesize], uvlinesize, bSH, qpc1, h);
filter_mb_edgech( &img_cb[2*2*uvlinesize], uvlinesize, bS3, qpc, h);
filter_mb_edgech( &img_cr[2*0*uvlinesize], uvlinesize, bSH, qpc1, h);
filter_mb_edgech( &img_cr[2*2*uvlinesize], uvlinesize, bS3, qpc, h);
return; return;
} else { } else {
LOCAL_ALIGNED_8(int16_t, bS, [2], [4][4]); LOCAL_ALIGNED_8(int16_t, bS, [2], [4][4]);
@@ -298,7 +301,7 @@ void ff_h264_filter_mb_fast( H264Context *h, int mb_x, int mb_y, uint8_t *img_y,
#define FILTER(hv,dir,edge)\ #define FILTER(hv,dir,edge)\
if(AV_RN64A(bS[dir][edge])) { \ if(AV_RN64A(bS[dir][edge])) { \
filter_mb_edge##hv( &img_y[4*edge*(dir?linesize:1)], linesize, bS[dir][edge], edge ? qp : qp##dir, h );\ filter_mb_edge##hv( &img_y[4*edge*(dir?linesize:1)], linesize, bS[dir][edge], edge ? qp : qp##dir, h );\
if(!(edge&1)) {\
if(chroma && !(edge&1)) {\
filter_mb_edgec##hv( &img_cb[2*edge*(dir?uvlinesize:1)], uvlinesize, bS[dir][edge], edge ? qpc : qpc##dir, h );\ filter_mb_edgec##hv( &img_cb[2*edge*(dir?uvlinesize:1)], uvlinesize, bS[dir][edge], edge ? qpc : qpc##dir, h );\
filter_mb_edgec##hv( &img_cr[2*edge*(dir?uvlinesize:1)], uvlinesize, bS[dir][edge], edge ? qpc : qpc##dir, h );\ filter_mb_edgec##hv( &img_cr[2*edge*(dir?uvlinesize:1)], uvlinesize, bS[dir][edge], edge ? qpc : qpc##dir, h );\
}\ }\
@@ -353,9 +356,10 @@ static int check_mv(H264Context *h, long b_idx, long bn_idx, int mvy_limit){
return v; return v;
} }


static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize, int mb_xy, int mb_type, int mvy_limit, int first_vertical_edge_done, int dir) {
static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint8_t *img_cb, uint8_t *img_cr, unsigned int linesize, unsigned int uvlinesize, int mb_xy, int mb_type, int mvy_limit, int first_vertical_edge_done, int chroma, int chroma444, int dir) {
MpegEncContext * const s = &h->s; MpegEncContext * const s = &h->s;
int edge; int edge;
int chroma_qp_avg[2];
const int mbm_xy = dir == 0 ? mb_xy -1 : h->top_mb_xy; const int mbm_xy = dir == 0 ? mb_xy -1 : h->top_mb_xy;
const int mbm_type = dir == 0 ? h->left_type[0] : h->top_type; const int mbm_type = dir == 0 ? h->left_type[0] : h->top_type;


@@ -394,7 +398,7 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
bS[2]= 1+((h->cbp_table[mbn_xy] & 8)||h->non_zero_count_cache[scan8[0]+2]); bS[2]= 1+((h->cbp_table[mbn_xy] & 8)||h->non_zero_count_cache[scan8[0]+2]);
bS[3]= 1+((h->cbp_table[mbn_xy] & 8)||h->non_zero_count_cache[scan8[0]+3]); bS[3]= 1+((h->cbp_table[mbn_xy] & 8)||h->non_zero_count_cache[scan8[0]+3]);
}else{ }else{
const uint8_t *mbn_nnz = h->non_zero_count[mbn_xy] + 4+3*8;
const uint8_t *mbn_nnz = h->non_zero_count[mbn_xy] + 3*4;
int i; int i;
for( i = 0; i < 4; i++ ) { for( i = 0; i < 4; i++ ) {
bS[i] = 1 + !!(h->non_zero_count_cache[scan8[0]+i] | mbn_nnz[i]); bS[i] = 1 + !!(h->non_zero_count_cache[scan8[0]+i] | mbn_nnz[i]);
@@ -407,10 +411,17 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, tmp_linesize, tmp_uvlinesize); tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, tmp_linesize, tmp_uvlinesize);
{ int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); } { int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); }
filter_mb_edgeh( &img_y[j*linesize], tmp_linesize, bS, qp, h ); filter_mb_edgeh( &img_y[j*linesize], tmp_linesize, bS, qp, h );
filter_mb_edgech( &img_cb[j*uvlinesize], tmp_uvlinesize, bS,
( h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1, h);
filter_mb_edgech( &img_cr[j*uvlinesize], tmp_uvlinesize, bS,
( h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1, h);
chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1;
chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbn_xy] ) + 1 ) >> 1;
if (chroma) {
if (chroma444) {
filter_mb_edgeh (&img_cb[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[0], h);
filter_mb_edgeh (&img_cr[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[1], h);
} else {
filter_mb_edgech(&img_cb[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[0], h);
filter_mb_edgech(&img_cr[j*uvlinesize], tmp_uvlinesize, bS, chroma_qp_avg[1], h);
}
}
} }
}else{ }else{
DECLARE_ALIGNED(8, int16_t, bS)[4]; DECLARE_ALIGNED(8, int16_t, bS)[4];
@@ -465,23 +476,29 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
//tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d, QPc:%d, QPcn:%d\n", mb_x, mb_y, dir, edge, qp, h->chroma_qp[0], s->current_picture.qscale_table[mbn_xy]); //tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d, QPc:%d, QPcn:%d\n", mb_x, mb_y, dir, edge, qp, h->chroma_qp[0], s->current_picture.qscale_table[mbn_xy]);
tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize); tprintf(s->avctx, "filter mb:%d/%d dir:%d edge:%d, QPy:%d ls:%d uvls:%d", mb_x, mb_y, dir, edge, qp, linesize, uvlinesize);
//{ int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); } //{ int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); }
chroma_qp_avg[0] = (h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbm_xy] ) + 1 ) >> 1;
chroma_qp_avg[1] = (h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbm_xy] ) + 1 ) >> 1;
if( dir == 0 ) { if( dir == 0 ) {
filter_mb_edgev( &img_y[0], linesize, bS, qp, h ); filter_mb_edgev( &img_y[0], linesize, bS, qp, h );
{
int qp= ( h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbm_xy] ) + 1 ) >> 1;
filter_mb_edgecv( &img_cb[0], uvlinesize, bS, qp, h);
if(h->pps.chroma_qp_diff)
qp= ( h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbm_xy] ) + 1 ) >> 1;
filter_mb_edgecv( &img_cr[0], uvlinesize, bS, qp, h);
if (chroma) {
if (chroma444) {
filter_mb_edgev ( &img_cb[0], uvlinesize, bS, chroma_qp_avg[0], h);
filter_mb_edgev ( &img_cr[0], uvlinesize, bS, chroma_qp_avg[1], h);
} else {
filter_mb_edgecv( &img_cb[0], uvlinesize, bS, chroma_qp_avg[0], h);
filter_mb_edgecv( &img_cr[0], uvlinesize, bS, chroma_qp_avg[1], h);
}
} }
} else { } else {
filter_mb_edgeh( &img_y[0], linesize, bS, qp, h ); filter_mb_edgeh( &img_y[0], linesize, bS, qp, h );
{
int qp= ( h->chroma_qp[0] + get_chroma_qp( h, 0, s->current_picture.qscale_table[mbm_xy] ) + 1 ) >> 1;
filter_mb_edgech( &img_cb[0], uvlinesize, bS, qp, h);
if(h->pps.chroma_qp_diff)
qp= ( h->chroma_qp[1] + get_chroma_qp( h, 1, s->current_picture.qscale_table[mbm_xy] ) + 1 ) >> 1;
filter_mb_edgech( &img_cr[0], uvlinesize, bS, qp, h);
if (chroma) {
if (chroma444) {
filter_mb_edgeh ( &img_cb[0], uvlinesize, bS, chroma_qp_avg[0], h);
filter_mb_edgeh ( &img_cr[0], uvlinesize, bS, chroma_qp_avg[1], h);
} else {
filter_mb_edgech( &img_cb[0], uvlinesize, bS, chroma_qp_avg[0], h);
filter_mb_edgech( &img_cr[0], uvlinesize, bS, chroma_qp_avg[1], h);
}
} }
} }
} }
@@ -545,15 +562,25 @@ static av_always_inline void filter_mb_dir(H264Context *h, int mb_x, int mb_y, u
//{ int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); } //{ int i; for (i = 0; i < 4; i++) tprintf(s->avctx, " bS[%d]:%d", i, bS[i]); tprintf(s->avctx, "\n"); }
if( dir == 0 ) { if( dir == 0 ) {
filter_mb_edgev( &img_y[4*edge << h->pixel_shift], linesize, bS, qp, h ); filter_mb_edgev( &img_y[4*edge << h->pixel_shift], linesize, bS, qp, h );
if( (edge&1) == 0 ) {
filter_mb_edgecv( &img_cb[2*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[0], h);
filter_mb_edgecv( &img_cr[2*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[1], h);
if (chroma) {
if (chroma444) {
filter_mb_edgev ( &img_cb[4*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[0], h);
filter_mb_edgev ( &img_cr[4*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[1], h);
} else if( (edge&1) == 0 ) {
filter_mb_edgecv( &img_cb[2*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[0], h);
filter_mb_edgecv( &img_cr[2*edge << h->pixel_shift], uvlinesize, bS, h->chroma_qp[1], h);
}
} }
} else { } else {
filter_mb_edgeh( &img_y[4*edge*linesize], linesize, bS, qp, h ); filter_mb_edgeh( &img_y[4*edge*linesize], linesize, bS, qp, h );
if( (edge&1) == 0 ) {
filter_mb_edgech( &img_cb[2*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[0], h);
filter_mb_edgech( &img_cr[2*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[1], h);
if (chroma) {
if (chroma444) {
filter_mb_edgeh ( &img_cb[4*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[0], h);
filter_mb_edgeh ( &img_cr[4*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[1], h);
} else if( (edge&1) == 0 ) {
filter_mb_edgech( &img_cb[2*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[0], h);
filter_mb_edgech( &img_cr[2*edge*uvlinesize], uvlinesize, bS, h->chroma_qp[1], h);
}
} }
} }
} }
@@ -566,6 +593,7 @@ void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint
const int mvy_limit = IS_INTERLACED(mb_type) ? 2 : 4; const int mvy_limit = IS_INTERLACED(mb_type) ? 2 : 4;
int first_vertical_edge_done = 0; int first_vertical_edge_done = 0;
av_unused int dir; av_unused int dir;
int chroma = !(CONFIG_GRAY && (s->flags&CODEC_FLAG_GRAY));


if (FRAME_MBAFF if (FRAME_MBAFF
// and current and left pair do not have the same interlaced type // and current and left pair do not have the same interlaced type
@@ -589,11 +617,11 @@ void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint
} else { } else {
static const uint8_t offset[2][2][8]={ static const uint8_t offset[2][2][8]={
{ {
{7+8*0, 7+8*0, 7+8*0, 7+8*0, 7+8*1, 7+8*1, 7+8*1, 7+8*1},
{7+8*2, 7+8*2, 7+8*2, 7+8*2, 7+8*3, 7+8*3, 7+8*3, 7+8*3},
{3+4*0, 3+4*0, 3+4*0, 3+4*0, 3+4*1, 3+4*1, 3+4*1, 3+4*1},
{3+4*2, 3+4*2, 3+4*2, 3+4*2, 3+4*3, 3+4*3, 3+4*3, 3+4*3},
},{ },{
{7+8*0, 7+8*1, 7+8*2, 7+8*3, 7+8*0, 7+8*1, 7+8*2, 7+8*3},
{7+8*0, 7+8*1, 7+8*2, 7+8*3, 7+8*0, 7+8*1, 7+8*2, 7+8*3},
{3+4*0, 3+4*1, 3+4*2, 3+4*3, 3+4*0, 3+4*1, 3+4*2, 3+4*3},
{3+4*0, 3+4*1, 3+4*2, 3+4*3, 3+4*0, 3+4*1, 3+4*2, 3+4*3},
} }
}; };
const uint8_t *off= offset[MB_FIELD][mb_y&1]; const uint8_t *off= offset[MB_FIELD][mb_y&1];
@@ -634,25 +662,29 @@ void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint
if(MB_FIELD){ if(MB_FIELD){
filter_mb_mbaff_edgev ( h, img_y , linesize, bS , 1, qp [0] ); filter_mb_mbaff_edgev ( h, img_y , linesize, bS , 1, qp [0] );
filter_mb_mbaff_edgev ( h, img_y + 8* linesize, linesize, bS+4, 1, qp [1] ); filter_mb_mbaff_edgev ( h, img_y + 8* linesize, linesize, bS+4, 1, qp [1] );
filter_mb_mbaff_edgecv( h, img_cb, uvlinesize, bS , 1, bqp[0] );
filter_mb_mbaff_edgecv( h, img_cb + 4*uvlinesize, uvlinesize, bS+4, 1, bqp[1] );
filter_mb_mbaff_edgecv( h, img_cr, uvlinesize, bS , 1, rqp[0] );
filter_mb_mbaff_edgecv( h, img_cr + 4*uvlinesize, uvlinesize, bS+4, 1, rqp[1] );
if (chroma){
filter_mb_mbaff_edgecv( h, img_cb, uvlinesize, bS , 1, bqp[0] );
filter_mb_mbaff_edgecv( h, img_cb + 4*uvlinesize, uvlinesize, bS+4, 1, bqp[1] );
filter_mb_mbaff_edgecv( h, img_cr, uvlinesize, bS , 1, rqp[0] );
filter_mb_mbaff_edgecv( h, img_cr + 4*uvlinesize, uvlinesize, bS+4, 1, rqp[1] );
}
}else{ }else{
filter_mb_mbaff_edgev ( h, img_y , 2* linesize, bS , 2, qp [0] ); filter_mb_mbaff_edgev ( h, img_y , 2* linesize, bS , 2, qp [0] );
filter_mb_mbaff_edgev ( h, img_y + linesize, 2* linesize, bS+1, 2, qp [1] ); filter_mb_mbaff_edgev ( h, img_y + linesize, 2* linesize, bS+1, 2, qp [1] );
filter_mb_mbaff_edgecv( h, img_cb, 2*uvlinesize, bS , 2, bqp[0] );
filter_mb_mbaff_edgecv( h, img_cb + uvlinesize, 2*uvlinesize, bS+1, 2, bqp[1] );
filter_mb_mbaff_edgecv( h, img_cr, 2*uvlinesize, bS , 2, rqp[0] );
filter_mb_mbaff_edgecv( h, img_cr + uvlinesize, 2*uvlinesize, bS+1, 2, rqp[1] );
if (chroma){
filter_mb_mbaff_edgecv( h, img_cb, 2*uvlinesize, bS , 2, bqp[0] );
filter_mb_mbaff_edgecv( h, img_cb + uvlinesize, 2*uvlinesize, bS+1, 2, bqp[1] );
filter_mb_mbaff_edgecv( h, img_cr, 2*uvlinesize, bS , 2, rqp[0] );
filter_mb_mbaff_edgecv( h, img_cr + uvlinesize, 2*uvlinesize, bS+1, 2, rqp[1] );
}
} }
} }


#if CONFIG_SMALL #if CONFIG_SMALL
for( dir = 0; dir < 2; dir++ ) for( dir = 0; dir < 2; dir++ )
filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, dir ? 0 : first_vertical_edge_done, dir);
filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, dir ? 0 : first_vertical_edge_done, chroma, CHROMA444, dir);
#else #else
filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, first_vertical_edge_done, 0);
filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, 0, 1);
filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, first_vertical_edge_done, chroma, CHROMA444, 0);
filter_mb_dir(h, mb_x, mb_y, img_y, img_cb, img_cr, linesize, uvlinesize, mb_xy, mb_type, mvy_limit, 0, chroma, CHROMA444, 1);
#endif #endif
} }

+ 11
- 3
libavcodec/h264_ps.c View File

@@ -269,7 +269,7 @@ static void decode_scaling_matrices(H264Context *h, SPS *sps, PPS *pps, int is_s
fallback_sps ? sps->scaling_matrix4[0] : default_scaling4[0], fallback_sps ? sps->scaling_matrix4[0] : default_scaling4[0],
fallback_sps ? sps->scaling_matrix4[3] : default_scaling4[1], fallback_sps ? sps->scaling_matrix4[3] : default_scaling4[1],
fallback_sps ? sps->scaling_matrix8[0] : default_scaling8[0], fallback_sps ? sps->scaling_matrix8[0] : default_scaling8[0],
fallback_sps ? sps->scaling_matrix8[1] : default_scaling8[1]
fallback_sps ? sps->scaling_matrix8[3] : default_scaling8[1]
}; };
if(get_bits1(&s->gb)){ if(get_bits1(&s->gb)){
sps->scaling_matrix_present |= is_sps; sps->scaling_matrix_present |= is_sps;
@@ -281,7 +281,15 @@ static void decode_scaling_matrices(H264Context *h, SPS *sps, PPS *pps, int is_s
decode_scaling_list(h,scaling_matrix4[5],16,default_scaling4[1],scaling_matrix4[4]); // Inter, Cb decode_scaling_list(h,scaling_matrix4[5],16,default_scaling4[1],scaling_matrix4[4]); // Inter, Cb
if(is_sps || pps->transform_8x8_mode){ if(is_sps || pps->transform_8x8_mode){
decode_scaling_list(h,scaling_matrix8[0],64,default_scaling8[0],fallback[2]); // Intra, Y decode_scaling_list(h,scaling_matrix8[0],64,default_scaling8[0],fallback[2]); // Intra, Y
decode_scaling_list(h,scaling_matrix8[1],64,default_scaling8[1],fallback[3]); // Inter, Y
if(h->sps.chroma_format_idc == 3){
decode_scaling_list(h,scaling_matrix8[1],64,default_scaling8[0],scaling_matrix8[0]); // Intra, Cr
decode_scaling_list(h,scaling_matrix8[2],64,default_scaling8[0],scaling_matrix8[1]); // Intra, Cb
}
decode_scaling_list(h,scaling_matrix8[3],64,default_scaling8[1],fallback[3]); // Inter, Y
if(h->sps.chroma_format_idc == 3){
decode_scaling_list(h,scaling_matrix8[4],64,default_scaling8[1],scaling_matrix8[3]); // Inter, Cr
decode_scaling_list(h,scaling_matrix8[5],64,default_scaling8[1],scaling_matrix8[4]); // Inter, Cb
}
} }
} }
} }
@@ -395,7 +403,7 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){
if(sps->crop_left || sps->crop_top){ if(sps->crop_left || sps->crop_top){
av_log(h->s.avctx, AV_LOG_ERROR, "insane cropping not completely supported, this could look slightly wrong ...\n"); av_log(h->s.avctx, AV_LOG_ERROR, "insane cropping not completely supported, this could look slightly wrong ...\n");
} }
if(sps->crop_right >= 8 || sps->crop_bottom >= 8){
if(sps->crop_right >= (8<<CHROMA444) || sps->crop_bottom >= (8<<CHROMA444)){
av_log(h->s.avctx, AV_LOG_ERROR, "brainfart cropping not supported, this could look slightly wrong ...\n"); av_log(h->s.avctx, AV_LOG_ERROR, "brainfart cropping not supported, this could look slightly wrong ...\n");
} }
}else{ }else{


+ 4
- 4
libavcodec/h264dsp.h View File

@@ -66,10 +66,10 @@ typedef struct H264DSPContext{
void (*h264_idct_dc_add)(uint8_t *dst/*align 4*/, DCTELEM *block/*align 16*/, int stride); void (*h264_idct_dc_add)(uint8_t *dst/*align 4*/, DCTELEM *block/*align 16*/, int stride);
void (*h264_idct8_dc_add)(uint8_t *dst/*align 8*/, DCTELEM *block/*align 16*/, int stride); void (*h264_idct8_dc_add)(uint8_t *dst/*align 8*/, DCTELEM *block/*align 16*/, int stride);


void (*h264_idct_add16)(uint8_t *dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[6*8]);
void (*h264_idct8_add4)(uint8_t *dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[6*8]);
void (*h264_idct_add8)(uint8_t **dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[6*8]);
void (*h264_idct_add16intra)(uint8_t *dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[6*8]);
void (*h264_idct_add16)(uint8_t *dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[15*8]);
void (*h264_idct8_add4)(uint8_t *dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[15*8]);
void (*h264_idct_add8)(uint8_t **dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[15*8]);
void (*h264_idct_add16intra)(uint8_t *dst/*align 16*/, const int *blockoffset, DCTELEM *block/*align 16*/, int stride, const uint8_t nnzc[15*8]);
void (*h264_luma_dc_dequant_idct)(DCTELEM *output, DCTELEM *input/*align 16*/, int qmul); void (*h264_luma_dc_dequant_idct)(DCTELEM *output, DCTELEM *input/*align 16*/, int qmul);
void (*h264_chroma_dc_dequant_idct)(DCTELEM *block, int qmul); void (*h264_chroma_dc_dequant_idct)(DCTELEM *block, int qmul);
}H264DSPContext; }H264DSPContext;


+ 25
- 19
libavcodec/h264idct_template.c View File

@@ -30,15 +30,19 @@
#ifndef AVCODEC_H264IDCT_INTERNAL_H #ifndef AVCODEC_H264IDCT_INTERNAL_H
#define AVCODEC_H264IDCT_INTERNAL_H #define AVCODEC_H264IDCT_INTERNAL_H
//FIXME this table is a duplicate from h264data.h, and will be removed once the tables from, h264 have been split //FIXME this table is a duplicate from h264data.h, and will be removed once the tables from, h264 have been split
static const uint8_t scan8[16 + 2*4]={
4+1*8, 5+1*8, 4+2*8, 5+2*8,
6+1*8, 7+1*8, 6+2*8, 7+2*8,
4+3*8, 5+3*8, 4+4*8, 5+4*8,
6+3*8, 7+3*8, 6+4*8, 7+4*8,
1+1*8, 2+1*8,
1+2*8, 2+2*8,
1+4*8, 2+4*8,
1+5*8, 2+5*8,
static const uint8_t scan8[16*3]={
4+ 1*8, 5+ 1*8, 4+ 2*8, 5+ 2*8,
6+ 1*8, 7+ 1*8, 6+ 2*8, 7+ 2*8,
4+ 3*8, 5+ 3*8, 4+ 4*8, 5+ 4*8,
6+ 3*8, 7+ 3*8, 6+ 4*8, 7+ 4*8,
4+ 6*8, 5+ 6*8, 4+ 7*8, 5+ 7*8,
6+ 6*8, 7+ 6*8, 6+ 7*8, 7+ 7*8,
4+ 8*8, 5+ 8*8, 4+ 9*8, 5+ 9*8,
6+ 8*8, 7+ 8*8, 6+ 9*8, 7+ 9*8,
4+11*8, 5+11*8, 4+12*8, 5+12*8,
6+11*8, 7+11*8, 6+12*8, 7+12*8,
4+13*8, 5+13*8, 4+14*8, 5+14*8,
6+13*8, 7+13*8, 6+14*8, 7+14*8
}; };
#endif #endif


@@ -190,7 +194,7 @@ void FUNCC(ff_h264_idct8_dc_add)(uint8_t *p_dst, DCTELEM *block, int stride){
} }
} }


void FUNCC(ff_h264_idct_add16)(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){
void FUNCC(ff_h264_idct_add16)(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
int i; int i;
for(i=0; i<16; i++){ for(i=0; i<16; i++){
int nnz = nnzc[ scan8[i] ]; int nnz = nnzc[ scan8[i] ];
@@ -201,7 +205,7 @@ void FUNCC(ff_h264_idct_add16)(uint8_t *dst, const int *block_offset, DCTELEM *b
} }
} }


void FUNCC(ff_h264_idct_add16intra)(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){
void FUNCC(ff_h264_idct_add16intra)(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
int i; int i;
for(i=0; i<16; i++){ for(i=0; i<16; i++){
if(nnzc[ scan8[i] ]) FUNCC(idct_internal )(dst + block_offset[i], block + i*16*sizeof(pixel), stride, 4, 6, 1); if(nnzc[ scan8[i] ]) FUNCC(idct_internal )(dst + block_offset[i], block + i*16*sizeof(pixel), stride, 4, 6, 1);
@@ -209,7 +213,7 @@ void FUNCC(ff_h264_idct_add16intra)(uint8_t *dst, const int *block_offset, DCTEL
} }
} }


void FUNCC(ff_h264_idct8_add4)(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){
void FUNCC(ff_h264_idct8_add4)(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
int i; int i;
for(i=0; i<16; i+=4){ for(i=0; i<16; i+=4){
int nnz = nnzc[ scan8[i] ]; int nnz = nnzc[ scan8[i] ];
@@ -220,13 +224,15 @@ void FUNCC(ff_h264_idct8_add4)(uint8_t *dst, const int *block_offset, DCTELEM *b
} }
} }


void FUNCC(ff_h264_idct_add8)(uint8_t **dest, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){
int i;
for(i=16; i<16+8; i++){
if(nnzc[ scan8[i] ])
FUNCC(ff_h264_idct_add )(dest[(i&4)>>2] + block_offset[i], block + i*16*sizeof(pixel), stride);
else if(((dctcoef*)block)[i*16])
FUNCC(ff_h264_idct_dc_add)(dest[(i&4)>>2] + block_offset[i], block + i*16*sizeof(pixel), stride);
void FUNCC(ff_h264_idct_add8)(uint8_t **dest, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
int i, j;
for(j=1; j<3; j++){
for(i=j*16; i<j*16+4; i++){
if(nnzc[ scan8[i] ])
FUNCC(ff_h264_idct_add )(dest[j-1] + block_offset[i], block + i*16*sizeof(pixel), stride);
else if(((dctcoef*)block)[i*16])
FUNCC(ff_h264_idct_dc_add)(dest[j-1] + block_offset[i], block + i*16*sizeof(pixel), stride);
}
} }
} }
/** /**


+ 19
- 9
libavcodec/mpegvideo.c View File

@@ -1180,12 +1180,17 @@ void MPV_frame_end(MpegEncContext *s)
&& s->current_picture.reference && s->current_picture.reference
&& !s->intra_only && !s->intra_only
&& !(s->flags&CODEC_FLAG_EMU_EDGE)) { && !(s->flags&CODEC_FLAG_EMU_EDGE)) {
int edges = EDGE_BOTTOM | EDGE_TOP, h = s->v_edge_pos;

s->dsp.draw_edges(s->current_picture.data[0], s->linesize , s->h_edge_pos , h , EDGE_WIDTH , edges);
s->dsp.draw_edges(s->current_picture.data[1], s->uvlinesize, s->h_edge_pos>>1, h>>1, EDGE_WIDTH/2, edges);
s->dsp.draw_edges(s->current_picture.data[2], s->uvlinesize, s->h_edge_pos>>1, h>>1, EDGE_WIDTH/2, edges);

int hshift = av_pix_fmt_descriptors[s->avctx->pix_fmt].log2_chroma_w;
int vshift = av_pix_fmt_descriptors[s->avctx->pix_fmt].log2_chroma_h;
s->dsp.draw_edges(s->current_picture.data[0], s->linesize ,
s->h_edge_pos , s->v_edge_pos,
EDGE_WIDTH , EDGE_WIDTH , EDGE_TOP | EDGE_BOTTOM);
s->dsp.draw_edges(s->current_picture.data[1], s->uvlinesize,
s->h_edge_pos>>hshift, s->v_edge_pos>>vshift,
EDGE_WIDTH>>hshift, EDGE_WIDTH>>vshift, EDGE_TOP | EDGE_BOTTOM);
s->dsp.draw_edges(s->current_picture.data[2], s->uvlinesize,
s->h_edge_pos>>hshift, s->v_edge_pos>>vshift,
EDGE_WIDTH>>hshift, EDGE_WIDTH>>vshift, EDGE_TOP | EDGE_BOTTOM);
} }


emms_c(); emms_c();
@@ -2289,14 +2294,19 @@ void ff_draw_horiz_band(MpegEncContext *s, int y, int h){
&& !s->intra_only && !s->intra_only
&& !(s->flags&CODEC_FLAG_EMU_EDGE)) { && !(s->flags&CODEC_FLAG_EMU_EDGE)) {
int sides = 0, edge_h; int sides = 0, edge_h;
int hshift = av_pix_fmt_descriptors[s->avctx->pix_fmt].log2_chroma_w;
int vshift = av_pix_fmt_descriptors[s->avctx->pix_fmt].log2_chroma_h;
if (y==0) sides |= EDGE_TOP; if (y==0) sides |= EDGE_TOP;
if (y + h >= s->v_edge_pos) sides |= EDGE_BOTTOM; if (y + h >= s->v_edge_pos) sides |= EDGE_BOTTOM;


edge_h= FFMIN(h, s->v_edge_pos - y); edge_h= FFMIN(h, s->v_edge_pos - y);


s->dsp.draw_edges(s->current_picture_ptr->data[0] + y *s->linesize , s->linesize , s->h_edge_pos , edge_h , EDGE_WIDTH , sides);
s->dsp.draw_edges(s->current_picture_ptr->data[1] + (y>>1)*s->uvlinesize, s->uvlinesize, s->h_edge_pos>>1, edge_h>>1, EDGE_WIDTH/2, sides);
s->dsp.draw_edges(s->current_picture_ptr->data[2] + (y>>1)*s->uvlinesize, s->uvlinesize, s->h_edge_pos>>1, edge_h>>1, EDGE_WIDTH/2, sides);
s->dsp.draw_edges(s->current_picture_ptr->data[0] + y *s->linesize , s->linesize,
s->h_edge_pos , edge_h , EDGE_WIDTH , EDGE_WIDTH , sides);
s->dsp.draw_edges(s->current_picture_ptr->data[1] + (y>>vshift)*s->uvlinesize, s->uvlinesize,
s->h_edge_pos>>hshift, edge_h>>hshift, EDGE_WIDTH>>hshift, EDGE_WIDTH>>vshift, sides);
s->dsp.draw_edges(s->current_picture_ptr->data[2] + (y>>vshift)*s->uvlinesize, s->uvlinesize,
s->h_edge_pos>>hshift, edge_h>>hshift, EDGE_WIDTH>>hshift, EDGE_WIDTH>>vshift, sides);
} }


h= FFMIN(h, s->avctx->height - y); h= FFMIN(h, s->avctx->height - y);


+ 12
- 10
libavcodec/ppc/h264_altivec.c View File

@@ -527,7 +527,7 @@ static void ff_h264_idct8_dc_add_altivec(uint8_t *dst, DCTELEM *block, int strid
h264_idct_dc_add_internal(dst, block, stride, 8); h264_idct_dc_add_internal(dst, block, stride, 8);
} }


static void ff_h264_idct_add16_altivec(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){
static void ff_h264_idct_add16_altivec(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
int i; int i;
for(i=0; i<16; i++){ for(i=0; i<16; i++){
int nnz = nnzc[ scan8[i] ]; int nnz = nnzc[ scan8[i] ];
@@ -538,7 +538,7 @@ static void ff_h264_idct_add16_altivec(uint8_t *dst, const int *block_offset, DC
} }
} }


static void ff_h264_idct_add16intra_altivec(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){
static void ff_h264_idct_add16intra_altivec(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
int i; int i;
for(i=0; i<16; i++){ for(i=0; i<16; i++){
if(nnzc[ scan8[i] ]) ff_h264_idct_add_altivec(dst + block_offset[i], block + i*16, stride); if(nnzc[ scan8[i] ]) ff_h264_idct_add_altivec(dst + block_offset[i], block + i*16, stride);
@@ -546,7 +546,7 @@ static void ff_h264_idct_add16intra_altivec(uint8_t *dst, const int *block_offse
} }
} }


static void ff_h264_idct8_add4_altivec(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){
static void ff_h264_idct8_add4_altivec(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
int i; int i;
for(i=0; i<16; i+=4){ for(i=0; i<16; i+=4){
int nnz = nnzc[ scan8[i] ]; int nnz = nnzc[ scan8[i] ];
@@ -557,13 +557,15 @@ static void ff_h264_idct8_add4_altivec(uint8_t *dst, const int *block_offset, DC
} }
} }


static void ff_h264_idct_add8_altivec(uint8_t **dest, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){
int i;
for(i=16; i<16+8; i++){
if(nnzc[ scan8[i] ])
ff_h264_idct_add_altivec(dest[(i&4)>>2] + block_offset[i], block + i*16, stride);
else if(block[i*16])
h264_idct_dc_add_altivec(dest[(i&4)>>2] + block_offset[i], block + i*16, stride);
static void ff_h264_idct_add8_altivec(uint8_t **dest, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[15*8]){
int i, j;
for (j = 1; j < 3; j++) {
for(i = j * 16; i < j * 16 + 4; i++){
if(nnzc[ scan8[i] ])
ff_h264_idct_add_altivec(dest[j-1] + block_offset[i], block + i*16, stride);
else if(block[i*16])
h264_idct_dc_add_altivec(dest[j-1] + block_offset[i], block + i*16, stride);
}
} }
} }




+ 9
- 3
libavcodec/snow.c View File

@@ -1976,9 +1976,15 @@ static int frame_start(SnowContext *s){
int h= s->avctx->height; int h= s->avctx->height;


if(s->current_picture.data[0]){ if(s->current_picture.data[0]){
s->dsp.draw_edges(s->current_picture.data[0], s->current_picture.linesize[0], w , h , EDGE_WIDTH , EDGE_TOP|EDGE_BOTTOM);
s->dsp.draw_edges(s->current_picture.data[1], s->current_picture.linesize[1], w>>1, h>>1, EDGE_WIDTH/2, EDGE_TOP|EDGE_BOTTOM);
s->dsp.draw_edges(s->current_picture.data[2], s->current_picture.linesize[2], w>>1, h>>1, EDGE_WIDTH/2, EDGE_TOP|EDGE_BOTTOM);
s->dsp.draw_edges(s->current_picture.data[0],
s->current_picture.linesize[0], w , h ,
EDGE_WIDTH , EDGE_WIDTH , EDGE_TOP | EDGE_BOTTOM);
s->dsp.draw_edges(s->current_picture.data[1],
s->current_picture.linesize[1], w>>1, h>>1,
EDGE_WIDTH/2, EDGE_WIDTH/2, EDGE_TOP | EDGE_BOTTOM);
s->dsp.draw_edges(s->current_picture.data[2],
s->current_picture.linesize[2], w>>1, h>>1,
EDGE_WIDTH/2, EDGE_WIDTH/2, EDGE_TOP | EDGE_BOTTOM);
} }


release_buffer(s->avctx); release_buffer(s->avctx);


+ 16
- 12
libavcodec/svq3.c View File

@@ -635,8 +635,9 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
memset(h->intra4x4_pred_mode+h->mb2br_xy[mb_xy], DC_PRED, 8); memset(h->intra4x4_pred_mode+h->mb2br_xy[mb_xy], DC_PRED, 8);
} }
if (!IS_SKIP(mb_type) || s->pict_type == AV_PICTURE_TYPE_B) { if (!IS_SKIP(mb_type) || s->pict_type == AV_PICTURE_TYPE_B) {
memset(h->non_zero_count_cache + 8, 0, 4*9*sizeof(uint8_t));
s->dsp.clear_blocks(h->mb);
memset(h->non_zero_count_cache + 8, 0, 14*8*sizeof(uint8_t));
s->dsp.clear_blocks(h->mb+ 0);
s->dsp.clear_blocks(h->mb+384);
} }


if (!IS_INTRA16x16(mb_type) && (!IS_SKIP(mb_type) || s->pict_type == AV_PICTURE_TYPE_B)) { if (!IS_INTRA16x16(mb_type) && (!IS_SKIP(mb_type) || s->pict_type == AV_PICTURE_TYPE_B)) {
@@ -656,8 +657,8 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
} }
} }
if (IS_INTRA16x16(mb_type)) { if (IS_INTRA16x16(mb_type)) {
AV_ZERO128(h->mb_luma_dc+0);
AV_ZERO128(h->mb_luma_dc+8);
AV_ZERO128(h->mb_luma_dc[0]+0);
AV_ZERO128(h->mb_luma_dc[0]+8);
if (svq3_decode_block(&s->gb, h->mb_luma_dc, 0, 1)){ if (svq3_decode_block(&s->gb, h->mb_luma_dc, 0, 1)){
av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding intra luma dc\n"); av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding intra luma dc\n");
return -1; return -1;
@@ -683,20 +684,23 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type)
} }


if ((cbp & 0x30)) { if ((cbp & 0x30)) {
for (i = 0; i < 2; ++i) {
if (svq3_decode_block(&s->gb, &h->mb[16*(16 + 4*i)], 0, 3)){
for (i = 1; i < 3; ++i) {
if (svq3_decode_block(&s->gb, &h->mb[16*16*i], 0, 3)){
av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding chroma dc block\n"); av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding chroma dc block\n");
return -1; return -1;
} }
} }


if ((cbp & 0x20)) { if ((cbp & 0x20)) {
for (i = 0; i < 8; i++) {
h->non_zero_count_cache[ scan8[16+i] ] = 1;

if (svq3_decode_block(&s->gb, &h->mb[16*(16 + i)], 1, 1)){
av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding chroma ac block\n");
return -1;
for (i = 1; i < 3; i++) {
for (j = 0; j < 4; j++) {
k = 16*i + j;
h->non_zero_count_cache[ scan8[k] ] = 1;

if (svq3_decode_block(&s->gb, &h->mb[16*k], 1, 1)){
av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding chroma ac block\n");
return -1;
}
} }
} }
} }


+ 2
- 2
libavcodec/x86/dsputil_mmx.c View File

@@ -762,7 +762,7 @@ static void h263_h_loop_filter_mmx(uint8_t *src, int stride, int qscale){


/* draw the edges of width 'w' of an image of size width, height /* draw the edges of width 'w' of an image of size width, height
this mmx version can only handle w==8 || w==16 */ this mmx version can only handle w==8 || w==16 */
static void draw_edges_mmx(uint8_t *buf, int wrap, int width, int height, int w, int sides)
static void draw_edges_mmx(uint8_t *buf, int wrap, int width, int height, int w, int h, int sides)
{ {
uint8_t *ptr, *last_line; uint8_t *ptr, *last_line;
int i; int i;
@@ -817,7 +817,7 @@ static void draw_edges_mmx(uint8_t *buf, int wrap, int width, int height, int w,


/* top and bottom (and hopefully also the corners) */ /* top and bottom (and hopefully also the corners) */
if (sides&EDGE_TOP) { if (sides&EDGE_TOP) {
for(i = 0; i < w; i += 4) {
for(i = 0; i < h; i += 4) {
ptr= buf - (i + 1) * wrap - w; ptr= buf - (i + 1) * wrap - w;
__asm__ volatile( __asm__ volatile(
"1: \n\t" "1: \n\t"


+ 9
- 6
libavcodec/x86/h264_i386.h View File

@@ -36,7 +36,7 @@
#if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) #if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS)
static int decode_significance_x86(CABACContext *c, int max_coeff, static int decode_significance_x86(CABACContext *c, int max_coeff,
uint8_t *significant_coeff_ctx_base, uint8_t *significant_coeff_ctx_base,
int *index){
int *index, x86_reg last_off){
void *end= significant_coeff_ctx_base + max_coeff - 1; void *end= significant_coeff_ctx_base + max_coeff - 1;
int minusstart= -(int)significant_coeff_ctx_base; int minusstart= -(int)significant_coeff_ctx_base;
int minusindex= 4-(int)index; int minusindex= 4-(int)index;
@@ -52,10 +52,12 @@ static int decode_significance_x86(CABACContext *c, int max_coeff,


"test $1, %%edx \n\t" "test $1, %%edx \n\t"
" jz 3f \n\t" " jz 3f \n\t"
"add %7, %1 \n\t"


BRANCHLESS_GET_CABAC("%%edx", "%3", "61(%1)", "%%ebx",
BRANCHLESS_GET_CABAC("%%edx", "%3", "(%1)", "%%ebx",
"%%bx", "%%esi", "%%eax", "%%al") "%%bx", "%%esi", "%%eax", "%%al")


"sub %7, %1 \n\t"
"mov %2, %%"REG_a" \n\t" "mov %2, %%"REG_a" \n\t"
"movl %4, %%ecx \n\t" "movl %4, %%ecx \n\t"
"add %1, %%"REG_c" \n\t" "add %1, %%"REG_c" \n\t"
@@ -82,7 +84,7 @@ static int decode_significance_x86(CABACContext *c, int max_coeff,
"movl %%esi, "RANGE "(%3) \n\t" "movl %%esi, "RANGE "(%3) \n\t"
"movl %%ebx, "LOW "(%3) \n\t" "movl %%ebx, "LOW "(%3) \n\t"
:"=&a"(coeff_count), "+r"(significant_coeff_ctx_base), "+m"(index) :"=&a"(coeff_count), "+r"(significant_coeff_ctx_base), "+m"(index)
:"r"(c), "m"(minusstart), "m"(end), "m"(minusindex)
:"r"(c), "m"(minusstart), "m"(end), "m"(minusindex), "m"(last_off)
: "%"REG_c, "%ebx", "%edx", "%esi", "memory" : "%"REG_c, "%ebx", "%edx", "%esi", "memory"
); );
return coeff_count; return coeff_count;
@@ -90,7 +92,7 @@ static int decode_significance_x86(CABACContext *c, int max_coeff,


static int decode_significance_8x8_x86(CABACContext *c, static int decode_significance_8x8_x86(CABACContext *c,
uint8_t *significant_coeff_ctx_base, uint8_t *significant_coeff_ctx_base,
int *index, const uint8_t *sig_off){
int *index, x86_reg last_off, const uint8_t *sig_off){
int minusindex= 4-(int)index; int minusindex= 4-(int)index;
int coeff_count; int coeff_count;
x86_reg last=0; x86_reg last=0;
@@ -114,8 +116,9 @@ static int decode_significance_8x8_x86(CABACContext *c,


"movzbl "MANGLE(last_coeff_flag_offset_8x8)"(%%edi), %%edi\n\t" "movzbl "MANGLE(last_coeff_flag_offset_8x8)"(%%edi), %%edi\n\t"
"add %5, %%"REG_D" \n\t" "add %5, %%"REG_D" \n\t"
"add %7, %%"REG_D" \n\t"


BRANCHLESS_GET_CABAC("%%edx", "%3", "15(%%"REG_D")", "%%ebx",
BRANCHLESS_GET_CABAC("%%edx", "%3", "(%%"REG_D")", "%%ebx",
"%%bx", "%%esi", "%%eax", "%%al") "%%bx", "%%esi", "%%eax", "%%al")


"mov %2, %%"REG_a" \n\t" "mov %2, %%"REG_a" \n\t"
@@ -142,7 +145,7 @@ static int decode_significance_8x8_x86(CABACContext *c,
"movl %%esi, "RANGE "(%3) \n\t" "movl %%esi, "RANGE "(%3) \n\t"
"movl %%ebx, "LOW "(%3) \n\t" "movl %%ebx, "LOW "(%3) \n\t"
:"=&a"(coeff_count),"+m"(last), "+m"(index) :"=&a"(coeff_count),"+m"(last), "+m"(index)
:"r"(c), "m"(minusindex), "m"(significant_coeff_ctx_base), "m"(sig_off)
:"r"(c), "m"(minusindex), "m"(significant_coeff_ctx_base), "m"(sig_off), "m"(last_off)
: "%"REG_c, "%ebx", "%edx", "%esi", "%"REG_D, "memory" : "%"REG_c, "%ebx", "%edx", "%esi", "%"REG_D, "memory"
); );
return coeff_count; return coeff_count;


+ 27
- 17
libavcodec/x86/h264_idct.asm View File

@@ -32,14 +32,18 @@
SECTION_RODATA SECTION_RODATA


; FIXME this table is a duplicate from h264data.h, and will be removed once the tables from, h264 have been split ; FIXME this table is a duplicate from h264data.h, and will be removed once the tables from, h264 have been split
scan8_mem: db 4+1*8, 5+1*8, 4+2*8, 5+2*8
db 6+1*8, 7+1*8, 6+2*8, 7+2*8
db 4+3*8, 5+3*8, 4+4*8, 5+4*8
db 6+3*8, 7+3*8, 6+4*8, 7+4*8
db 1+1*8, 2+1*8
db 1+2*8, 2+2*8
db 1+4*8, 2+4*8
db 1+5*8, 2+5*8
scan8_mem: db 4+ 1*8, 5+ 1*8, 4+ 2*8, 5+ 2*8
db 6+ 1*8, 7+ 1*8, 6+ 2*8, 7+ 2*8
db 4+ 3*8, 5+ 3*8, 4+ 4*8, 5+ 4*8
db 6+ 3*8, 7+ 3*8, 6+ 4*8, 7+ 4*8
db 4+ 6*8, 5+ 6*8, 4+ 7*8, 5+ 7*8
db 6+ 6*8, 7+ 6*8, 6+ 7*8, 7+ 7*8
db 4+ 8*8, 5+ 8*8, 4+ 9*8, 5+ 9*8
db 6+ 8*8, 7+ 8*8, 6+ 9*8, 7+ 9*8
db 4+11*8, 5+11*8, 4+12*8, 5+12*8
db 6+11*8, 7+11*8, 6+12*8, 7+12*8
db 4+13*8, 5+13*8, 4+14*8, 5+14*8
db 6+13*8, 7+13*8, 6+14*8, 7+14*8
%ifdef PIC %ifdef PIC
%define scan8 r11 %define scan8 r11
%else %else
@@ -617,6 +621,8 @@ cglobal h264_idct_add8_8_mmx, 5, 7, 0
mov r10, r0 mov r10, r0
%endif %endif
call h264_idct_add8_mmx_plane call h264_idct_add8_mmx_plane
mov r5, 32
add r2, 384
%ifdef ARCH_X86_64 %ifdef ARCH_X86_64
add r10, gprsize add r10, gprsize
%else %else
@@ -678,6 +684,8 @@ cglobal h264_idct_add8_8_mmx2, 5, 7, 0
lea r11, [scan8_mem] lea r11, [scan8_mem]
%endif %endif
call h264_idct_add8_mmx2_plane call h264_idct_add8_mmx2_plane
mov r5, 32
add r2, 384
%ifdef ARCH_X86_64 %ifdef ARCH_X86_64
add r10, gprsize add r10, gprsize
%else %else
@@ -810,12 +818,12 @@ cglobal h264_idct_add16intra_8_sse2, 5, 7, 8
test r0, r0 test r0, r0
jz .try%1dc jz .try%1dc
%ifdef ARCH_X86_64 %ifdef ARCH_X86_64
mov r0d, dword [r1+%1*8+64]
mov r0d, dword [r1+(%1&1)*8+64*(1+(%1>>1))]
add r0, [r10] add r0, [r10]
%else %else
mov r0, r0m mov r0, r0m
mov r0, [r0] mov r0, [r0]
add r0, dword [r1+%1*8+64]
add r0, dword [r1+(%1&1)*8+64*(1+(%1>>1))]
%endif %endif
call x264_add8x4_idct_sse2 call x264_add8x4_idct_sse2
jmp .cycle%1end jmp .cycle%1end
@@ -824,16 +832,18 @@ cglobal h264_idct_add16intra_8_sse2, 5, 7, 8
or r0w, word [r2+32] or r0w, word [r2+32]
jz .cycle%1end jz .cycle%1end
%ifdef ARCH_X86_64 %ifdef ARCH_X86_64
mov r0d, dword [r1+%1*8+64]
mov r0d, dword [r1+(%1&1)*8+64*(1+(%1>>1))]
add r0, [r10] add r0, [r10]
%else %else
mov r0, r0m mov r0, r0m
mov r0, [r0] mov r0, [r0]
add r0, dword [r1+%1*8+64]
add r0, dword [r1+(%1&1)*8+64*(1+(%1>>1))]
%endif %endif
call h264_idct_dc_add8_mmx2 call h264_idct_dc_add8_mmx2
.cycle%1end .cycle%1end
%if %1 < 3
%if %1 == 1
add r2, 384+64
%elif %1 < 3
add r2, 64 add r2, 64
%endif %endif
%endmacro %endmacro
@@ -845,15 +855,15 @@ cglobal h264_idct_add8_8_sse2, 5, 7, 8
%ifdef ARCH_X86_64 %ifdef ARCH_X86_64
mov r10, r0 mov r10, r0
%endif %endif
add8_sse2_cycle 0, 0x09
add8_sse2_cycle 1, 0x11
add8_sse2_cycle 0, 0x34
add8_sse2_cycle 1, 0x3c
%ifdef ARCH_X86_64 %ifdef ARCH_X86_64
add r10, gprsize add r10, gprsize
%else %else
add r0mp, gprsize add r0mp, gprsize
%endif %endif
add8_sse2_cycle 2, 0x21
add8_sse2_cycle 3, 0x29
add8_sse2_cycle 2, 0x5c
add8_sse2_cycle 3, 0x64
RET RET


;void ff_h264_luma_dc_dequant_idct_mmx(DCTELEM *output, DCTELEM *input, int qmul) ;void ff_h264_luma_dc_dequant_idct_mmx(DCTELEM *output, DCTELEM *input, int qmul)


+ 20
- 15
libavcodec/x86/h264_idct_10bit.asm View File

@@ -29,14 +29,18 @@ SECTION_RODATA


pw_pixel_max: times 8 dw ((1 << 10)-1) pw_pixel_max: times 8 dw ((1 << 10)-1)
pd_32: times 4 dd 32 pd_32: times 4 dd 32
scan8_mem: db 4+1*8, 5+1*8, 4+2*8, 5+2*8
db 6+1*8, 7+1*8, 6+2*8, 7+2*8
db 4+3*8, 5+3*8, 4+4*8, 5+4*8
db 6+3*8, 7+3*8, 6+4*8, 7+4*8
db 1+1*8, 2+1*8
db 1+2*8, 2+2*8
db 1+4*8, 2+4*8
db 1+5*8, 2+5*8
scan8_mem: db 4+ 1*8, 5+ 1*8, 4+ 2*8, 5+ 2*8
db 6+ 1*8, 7+ 1*8, 6+ 2*8, 7+ 2*8
db 4+ 3*8, 5+ 3*8, 4+ 4*8, 5+ 4*8
db 6+ 3*8, 7+ 3*8, 6+ 4*8, 7+ 4*8
db 4+ 6*8, 5+ 6*8, 4+ 7*8, 5+ 7*8
db 6+ 6*8, 7+ 6*8, 6+ 7*8, 7+ 7*8
db 4+ 8*8, 5+ 8*8, 4+ 9*8, 5+ 9*8
db 6+ 8*8, 7+ 8*8, 6+ 9*8, 7+ 9*8
db 4+11*8, 5+11*8, 4+12*8, 5+12*8
db 6+11*8, 7+11*8, 6+12*8, 7+12*8
db 4+13*8, 5+13*8, 4+14*8, 5+14*8
db 6+13*8, 7+13*8, 6+14*8, 7+14*8


%ifdef PIC %ifdef PIC
%define scan8 r11 %define scan8 r11
@@ -306,7 +310,7 @@ INIT_AVX
IDCT_ADD16INTRA_10 avx IDCT_ADD16INTRA_10 avx
%endif %endif


%assign last_block 24
%assign last_block 36
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------
; h264_idct_add8(pixel **dst, const int *block_offset, dctcoef *block, int stride, const uint8_t nnzc[6*8]) ; h264_idct_add8(pixel **dst, const int *block_offset, dctcoef *block, int stride, const uint8_t nnzc[6*8])
;----------------------------------------------------------------------------- ;-----------------------------------------------------------------------------
@@ -317,21 +321,22 @@ cglobal h264_idct_add8_10_%1,5,7
%endif %endif
add r2, 1024 add r2, 1024
mov r0, [r0] mov r0, [r0]
ADD16_OP_INTRA %1, 16, 1+1*8
ADD16_OP_INTRA %1, 18, 1+2*8
ADD16_OP_INTRA %1, 16, 4+ 6*8
ADD16_OP_INTRA %1, 18, 4+ 7*8
add r2, 1024-128*2
%ifdef ARCH_X86_64 %ifdef ARCH_X86_64
mov r0, [r10+gprsize] mov r0, [r10+gprsize]
%else %else
mov r0, r0m mov r0, r0m
mov r0, [r0+gprsize] mov r0, [r0+gprsize]
%endif %endif
ADD16_OP_INTRA %1, 20, 1+4*8
ADD16_OP_INTRA %1, 22, 1+5*8
ADD16_OP_INTRA %1, 32, 4+11*8
ADD16_OP_INTRA %1, 34, 4+12*8
REP_RET REP_RET
AC %1, 16 AC %1, 16
AC %1, 18 AC %1, 18
AC %1, 20
AC %1, 22
AC %1, 32
AC %1, 34


%endmacro ; IDCT_ADD8 %endmacro ; IDCT_ADD8




+ 248
- 102
libswscale/swscale.c View File

@@ -506,6 +506,13 @@ static void yuv2nv12X_c(SwsContext *c, const int16_t *lumFilter,
} }
} }


#define output_pixel(pos, val) \
if (target == PIX_FMT_GRAY16BE) { \
AV_WB16(pos, val); \
} else { \
AV_WL16(pos, val); \
}

static av_always_inline void static av_always_inline void
yuv2gray16_X_c_template(SwsContext *c, const int16_t *lumFilter, yuv2gray16_X_c_template(SwsContext *c, const int16_t *lumFilter,
const int16_t **lumSrc, int lumFilterSize, const int16_t **lumSrc, int lumFilterSize,
@@ -516,12 +523,6 @@ yuv2gray16_X_c_template(SwsContext *c, const int16_t *lumFilter,
{ {
int i; int i;


#define output_pixel(pos, val) \
if (target == PIX_FMT_GRAY16BE) { \
AV_WB16(pos, val); \
} else { \
AV_WL16(pos, val); \
}
for (i = 0; i < (dstW >> 1); i++) { for (i = 0; i < (dstW >> 1); i++) {
int j; int j;
int Y1 = 1 << 18; int Y1 = 1 << 18;
@@ -583,10 +584,11 @@ yuv2gray16_1_c_template(SwsContext *c, const uint16_t *buf0,
output_pixel(&dest[2 * i2 + 0], Y1); output_pixel(&dest[2 * i2 + 0], Y1);
output_pixel(&dest[2 * i2 + 2], Y2); output_pixel(&dest[2 * i2 + 2], Y2);
} }
#undef output_pixel
} }


#define YUV2PACKEDWRAPPER(name, ext, fmt) \
#undef output_pixel

#define YUV2PACKEDWRAPPER(name, base, ext, fmt) \
static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \ static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
const int16_t **lumSrc, int lumFilterSize, \ const int16_t **lumSrc, int lumFilterSize, \
const int16_t *chrFilter, const int16_t **chrUSrc, \ const int16_t *chrFilter, const int16_t **chrUSrc, \
@@ -594,7 +596,7 @@ static void name ## ext ## _X_c(SwsContext *c, const int16_t *lumFilter, \
const int16_t **alpSrc, uint8_t *dest, int dstW, \ const int16_t **alpSrc, uint8_t *dest, int dstW, \
int y) \ int y) \
{ \ { \
name ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \
chrFilter, chrUSrc, chrVSrc, chrFilterSize, \ chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
alpSrc, dest, dstW, y, fmt); \ alpSrc, dest, dstW, y, fmt); \
} \ } \
@@ -606,7 +608,7 @@ static void name ## ext ## _2_c(SwsContext *c, const uint16_t *buf0, \
const uint16_t *abuf1, uint8_t *dest, int dstW, \ const uint16_t *abuf1, uint8_t *dest, int dstW, \
int yalpha, int uvalpha, int y) \ int yalpha, int uvalpha, int y) \
{ \ { \
name ## _2_c_template(c, buf0, buf1, ubuf0, ubuf1, \
name ## base ## _2_c_template(c, buf0, buf1, ubuf0, ubuf1, \
vbuf0, vbuf1, abuf0, abuf1, \ vbuf0, vbuf1, abuf0, abuf1, \
dest, dstW, yalpha, uvalpha, y, fmt); \ dest, dstW, yalpha, uvalpha, y, fmt); \
} \ } \
@@ -618,13 +620,20 @@ static void name ## ext ## _1_c(SwsContext *c, const uint16_t *buf0, \
int uvalpha, enum PixelFormat dstFormat, \ int uvalpha, enum PixelFormat dstFormat, \
int flags, int y) \ int flags, int y) \
{ \ { \
name ## _1_c_template(c, buf0, ubuf0, ubuf1, vbuf0, \
name ## base ## _1_c_template(c, buf0, ubuf0, ubuf1, vbuf0, \
vbuf1, abuf0, dest, dstW, uvalpha, \ vbuf1, abuf0, dest, dstW, uvalpha, \
dstFormat, flags, y, fmt); \ dstFormat, flags, y, fmt); \
} }


YUV2PACKEDWRAPPER(yuv2gray16, LE, PIX_FMT_GRAY16LE);
YUV2PACKEDWRAPPER(yuv2gray16, BE, PIX_FMT_GRAY16BE);
YUV2PACKEDWRAPPER(yuv2gray16,, LE, PIX_FMT_GRAY16LE);
YUV2PACKEDWRAPPER(yuv2gray16,, BE, PIX_FMT_GRAY16BE);

#define output_pixel(pos, acc) \
if (target == PIX_FMT_MONOBLACK) { \
pos = acc; \
} else { \
pos = ~acc; \
}


static av_always_inline void static av_always_inline void
yuv2mono_X_c_template(SwsContext *c, const int16_t *lumFilter, yuv2mono_X_c_template(SwsContext *c, const int16_t *lumFilter,
@@ -639,12 +648,6 @@ yuv2mono_X_c_template(SwsContext *c, const int16_t *lumFilter,
int i; int i;
int acc = 0; int acc = 0;


#define output_pixel(pos, acc) \
if (target == PIX_FMT_MONOBLACK) { \
pos = acc; \
} else { \
pos = ~acc; \
}
for (i = 0; i < dstW - 1; i += 2) { for (i = 0; i < dstW - 1; i += 2) {
int j; int j;
int Y1 = 1 << 18; int Y1 = 1 << 18;
@@ -718,21 +721,12 @@ yuv2mono_1_c_template(SwsContext *c, const uint16_t *buf0,
acc += acc + g[(buf0[i + 7] >> 7) + d128[7]]; acc += acc + g[(buf0[i + 7] >> 7) + d128[7]];
output_pixel(*dest++, acc); output_pixel(*dest++, acc);
} }
#undef output_pixel
} }


YUV2PACKEDWRAPPER(yuv2mono, white, PIX_FMT_MONOWHITE);
YUV2PACKEDWRAPPER(yuv2mono, black, PIX_FMT_MONOBLACK);
#undef output_pixel


static av_always_inline void
yuv2422_X_c_template(SwsContext *c, const int16_t *lumFilter,
const int16_t **lumSrc, int lumFilterSize,
const int16_t *chrFilter, const int16_t **chrUSrc,
const int16_t **chrVSrc, int chrFilterSize,
const int16_t **alpSrc, uint8_t *dest, int dstW,
int y, enum PixelFormat target)
{
int i;
YUV2PACKEDWRAPPER(yuv2mono,, white, PIX_FMT_MONOWHITE);
YUV2PACKEDWRAPPER(yuv2mono,, black, PIX_FMT_MONOBLACK);


#define output_pixels(pos, Y1, U, Y2, V) \ #define output_pixels(pos, Y1, U, Y2, V) \
if (target == PIX_FMT_YUYV422) { \ if (target == PIX_FMT_YUYV422) { \
@@ -747,6 +741,16 @@ yuv2422_X_c_template(SwsContext *c, const int16_t *lumFilter,
dest[pos + 3] = Y2; \ dest[pos + 3] = Y2; \
} }


static av_always_inline void
yuv2422_X_c_template(SwsContext *c, const int16_t *lumFilter,
const int16_t **lumSrc, int lumFilterSize,
const int16_t *chrFilter, const int16_t **chrUSrc,
const int16_t **chrVSrc, int chrFilterSize,
const int16_t **alpSrc, uint8_t *dest, int dstW,
int y, enum PixelFormat target)
{
int i;

for (i = 0; i < (dstW >> 1); i++) { for (i = 0; i < (dstW >> 1); i++) {
int j; int j;
int Y1 = 1 << 18; int Y1 = 1 << 18;
@@ -828,11 +832,156 @@ yuv2422_1_c_template(SwsContext *c, const uint16_t *buf0,
output_pixels(i * 4, Y1, U, Y2, V); output_pixels(i * 4, Y1, U, Y2, V);
} }
} }
}

#undef output_pixels #undef output_pixels

YUV2PACKEDWRAPPER(yuv2, 422, yuyv422, PIX_FMT_YUYV422);
YUV2PACKEDWRAPPER(yuv2, 422, uyvy422, PIX_FMT_UYVY422);

#define r_b ((target == PIX_FMT_RGB48LE || target == PIX_FMT_RGB48BE) ? r : b)
#define b_r ((target == PIX_FMT_RGB48LE || target == PIX_FMT_RGB48BE) ? b : r)

static av_always_inline void
yuv2rgb48_X_c_template(SwsContext *c, const int16_t *lumFilter,
const int16_t **lumSrc, int lumFilterSize,
const int16_t *chrFilter, const int16_t **chrUSrc,
const int16_t **chrVSrc, int chrFilterSize,
const int16_t **alpSrc, uint8_t *dest, int dstW,
int y, enum PixelFormat target)
{
int i;

for (i = 0; i < (dstW >> 1); i++) {
int j;
int Y1 = 1 << 18;
int Y2 = 1 << 18;
int U = 1 << 18;
int V = 1 << 18;
const uint8_t *r, *g, *b;

for (j = 0; j < lumFilterSize; j++) {
Y1 += lumSrc[j][i * 2] * lumFilter[j];
Y2 += lumSrc[j][i * 2 + 1] * lumFilter[j];
}
for (j = 0; j < chrFilterSize; j++) {
U += chrUSrc[j][i] * chrFilter[j];
V += chrVSrc[j][i] * chrFilter[j];
}
Y1 >>= 19;
Y2 >>= 19;
U >>= 19;
V >>= 19;
if ((Y1 | Y2 | U | V) & 0x100) {
Y1 = av_clip_uint8(Y1);
Y2 = av_clip_uint8(Y2);
U = av_clip_uint8(U);
V = av_clip_uint8(V);
}

/* FIXME fix tables so that clipping is not needed and then use _NOCLIP*/
r = (const uint8_t *) c->table_rV[V];
g = (const uint8_t *)(c->table_gU[U] + c->table_gV[V]);
b = (const uint8_t *) c->table_bU[U];

dest[ 0] = dest[ 1] = r_b[Y1];
dest[ 2] = dest[ 3] = g[Y1];
dest[ 4] = dest[ 5] = b_r[Y1];
dest[ 6] = dest[ 7] = r_b[Y2];
dest[ 8] = dest[ 9] = g[Y2];
dest[10] = dest[11] = b_r[Y2];
dest += 12;
}
}

static av_always_inline void
yuv2rgb48_2_c_template(SwsContext *c, const uint16_t *buf0,
const uint16_t *buf1, const uint16_t *ubuf0,
const uint16_t *ubuf1, const uint16_t *vbuf0,
const uint16_t *vbuf1, const uint16_t *abuf0,
const uint16_t *abuf1, uint8_t *dest, int dstW,
int yalpha, int uvalpha, int y,
enum PixelFormat target)
{
int yalpha1 = 4095 - yalpha;
int uvalpha1 = 4095 - uvalpha;
int i;

for (i = 0; i < (dstW >> 1); i++) {
int Y1 = (buf0[i * 2] * yalpha1 + buf1[i * 2] * yalpha) >> 19;
int Y2 = (buf0[i * 2 + 1] * yalpha1 + buf1[i * 2 + 1] * yalpha) >> 19;
int U = (ubuf0[i] * uvalpha1 + ubuf1[i] * uvalpha) >> 19;
int V = (vbuf0[i] * uvalpha1 + vbuf1[i] * uvalpha) >> 19;
const uint8_t *r = (const uint8_t *) c->table_rV[V],
*g = (const uint8_t *)(c->table_gU[U] + c->table_gV[V]),
*b = (const uint8_t *) c->table_bU[U];

dest[ 0] = dest[ 1] = r_b[Y1];
dest[ 2] = dest[ 3] = g[Y1];
dest[ 4] = dest[ 5] = b_r[Y1];
dest[ 6] = dest[ 7] = r_b[Y2];
dest[ 8] = dest[ 9] = g[Y2];
dest[10] = dest[11] = b_r[Y2];
dest += 12;
}
}

static av_always_inline void
yuv2rgb48_1_c_template(SwsContext *c, const uint16_t *buf0,
const uint16_t *ubuf0, const uint16_t *ubuf1,
const uint16_t *vbuf0, const uint16_t *vbuf1,
const uint16_t *abuf0, uint8_t *dest, int dstW,
int uvalpha, enum PixelFormat dstFormat,
int flags, int y, enum PixelFormat target)
{
int i;

if (uvalpha < 2048) {
for (i = 0; i < (dstW >> 1); i++) {
int Y1 = buf0[i * 2] >> 7;
int Y2 = buf0[i * 2 + 1] >> 7;
int U = ubuf1[i] >> 7;
int V = vbuf1[i] >> 7;
const uint8_t *r = (const uint8_t *) c->table_rV[V],
*g = (const uint8_t *)(c->table_gU[U] + c->table_gV[V]),
*b = (const uint8_t *) c->table_bU[U];

dest[ 0] = dest[ 1] = r_b[Y1];
dest[ 2] = dest[ 3] = g[Y1];
dest[ 4] = dest[ 5] = b_r[Y1];
dest[ 6] = dest[ 7] = r_b[Y2];
dest[ 8] = dest[ 9] = g[Y2];
dest[10] = dest[11] = b_r[Y2];
dest += 12;
}
} else {
for (i = 0; i < (dstW >> 1); i++) {
int Y1 = buf0[i * 2] >> 7;
int Y2 = buf0[i * 2 + 1] >> 7;
int U = (ubuf0[i] + ubuf1[i]) >> 8;
int V = (vbuf0[i] + vbuf1[i]) >> 8;
const uint8_t *r = (const uint8_t *) c->table_rV[V],
*g = (const uint8_t *)(c->table_gU[U] + c->table_gV[V]),
*b = (const uint8_t *) c->table_bU[U];

dest[ 0] = dest[ 1] = r_b[Y1];
dest[ 2] = dest[ 3] = g[Y1];
dest[ 4] = dest[ 5] = b_r[Y1];
dest[ 6] = dest[ 7] = r_b[Y2];
dest[ 8] = dest[ 9] = g[Y2];
dest[10] = dest[11] = b_r[Y2];
dest += 12;
}
}
} }


YUV2PACKEDWRAPPER(yuv2422, yuyv, PIX_FMT_YUYV422);
YUV2PACKEDWRAPPER(yuv2422, uyvy, PIX_FMT_UYVY422);
#undef r_b
#undef b_r

YUV2PACKEDWRAPPER(yuv2, rgb48, rgb48be, PIX_FMT_RGB48BE);
//YUV2PACKEDWRAPPER(yuv2, rgb48, rgb48le, PIX_FMT_RGB48LE);
YUV2PACKEDWRAPPER(yuv2, rgb48, bgr48be, PIX_FMT_BGR48BE);
//YUV2PACKEDWRAPPER(yuv2, rgb48, bgr48le, PIX_FMT_BGR48LE);


#define YSCALE_YUV_2_RGBX_C(type,alpha) \ #define YSCALE_YUV_2_RGBX_C(type,alpha) \
for (i=0; i<(dstW>>1); i++) {\ for (i=0; i<(dstW>>1); i++) {\
@@ -974,36 +1123,6 @@ YUV2PACKEDWRAPPER(yuv2422, uyvy, PIX_FMT_UYVY422);


#define YSCALE_YUV_2_ANYRGB_C(func)\ #define YSCALE_YUV_2_ANYRGB_C(func)\
switch(c->dstFormat) {\ switch(c->dstFormat) {\
case PIX_FMT_RGB48BE:\
case PIX_FMT_RGB48LE:\
func(uint8_t,0)\
((uint8_t*)dest)[ 0]= r[Y1];\
((uint8_t*)dest)[ 1]= r[Y1];\
((uint8_t*)dest)[ 2]= g[Y1];\
((uint8_t*)dest)[ 3]= g[Y1];\
((uint8_t*)dest)[ 4]= b[Y1];\
((uint8_t*)dest)[ 5]= b[Y1];\
((uint8_t*)dest)[ 6]= r[Y2];\
((uint8_t*)dest)[ 7]= r[Y2];\
((uint8_t*)dest)[ 8]= g[Y2];\
((uint8_t*)dest)[ 9]= g[Y2];\
((uint8_t*)dest)[10]= b[Y2];\
((uint8_t*)dest)[11]= b[Y2];\
dest+=12;\
}\
break;\
case PIX_FMT_BGR48BE:\
case PIX_FMT_BGR48LE:\
func(uint8_t,0)\
((uint8_t*)dest)[ 0] = ((uint8_t*)dest)[ 1] = b[Y1];\
((uint8_t*)dest)[ 2] = ((uint8_t*)dest)[ 3] = g[Y1];\
((uint8_t*)dest)[ 4] = ((uint8_t*)dest)[ 5] = r[Y1];\
((uint8_t*)dest)[ 6] = ((uint8_t*)dest)[ 7] = b[Y2];\
((uint8_t*)dest)[ 8] = ((uint8_t*)dest)[ 9] = g[Y2];\
((uint8_t*)dest)[10] = ((uint8_t*)dest)[11] = r[Y2];\
dest+=12;\
}\
break;\
case PIX_FMT_RGBA:\ case PIX_FMT_RGBA:\
case PIX_FMT_BGRA:\ case PIX_FMT_BGRA:\
if (CONFIG_SMALL) {\ if (CONFIG_SMALL) {\
@@ -1294,19 +1413,21 @@ static av_always_inline void fillPlane(uint8_t* plane, int stride,
} }
} }


#define input_pixel(pos) (isBE(origin) ? AV_RB16(pos) : AV_RL16(pos))

#define r ((origin == PIX_FMT_BGR48BE || origin == PIX_FMT_BGR48LE) ? b_r : r_b)
#define b ((origin == PIX_FMT_BGR48BE || origin == PIX_FMT_BGR48LE) ? r_b : b_r)

static av_always_inline void static av_always_inline void
rgb48ToY_c_template(int16_t *dst, const uint16_t *src, int width, rgb48ToY_c_template(int16_t *dst, const uint16_t *src, int width,
enum PixelFormat origin) enum PixelFormat origin)
{ {
int i; int i;
for (i = 0; i < width; i++) { for (i = 0; i < width; i++) {
#define input_pixel(pos) (isBE(origin) ? AV_RB16(pos) : AV_RL16(pos))
int a = input_pixel(&src[i*3+0]);
int g = input_pixel(&src[i*3+1]);
int c = input_pixel(&src[i*3+2]);
int r_b = input_pixel(&src[i*3+0]);
int g = input_pixel(&src[i*3+1]);
int b_r = input_pixel(&src[i*3+2]);


#define r ((origin == PIX_FMT_BGR48BE || origin == PIX_FMT_BGR48LE) ? c : a)
#define b ((origin == PIX_FMT_BGR48BE || origin == PIX_FMT_BGR48LE) ? a : c)
dst[i] = (RY*r + GY*g + BY*b + (32<<(RGB2YUV_SHIFT-1+8)) + (1<<(RGB2YUV_SHIFT-7+8))) >> (RGB2YUV_SHIFT-6+8); dst[i] = (RY*r + GY*g + BY*b + (32<<(RGB2YUV_SHIFT-1+8)) + (1<<(RGB2YUV_SHIFT-7+8))) >> (RGB2YUV_SHIFT-6+8);
} }
} }
@@ -1319,9 +1440,9 @@ rgb48ToUV_c_template(int16_t *dstU, int16_t *dstV,
int i; int i;
assert(src1==src2); assert(src1==src2);
for (i = 0; i < width; i++) { for (i = 0; i < width; i++) {
int a = input_pixel(&src1[3*i + 0]);
int g = input_pixel(&src1[3*i + 1]);
int c = input_pixel(&src1[3*i + 2]);
int r_b = input_pixel(&src1[i*3+0]);
int g = input_pixel(&src1[i*3+1]);
int b_r = input_pixel(&src1[i*3+2]);


dstU[i] = (RU*r + GU*g + BU*b + (256<<(RGB2YUV_SHIFT-1+8)) + (1<<(RGB2YUV_SHIFT-7+8))) >> (RGB2YUV_SHIFT-6+8); dstU[i] = (RU*r + GU*g + BU*b + (256<<(RGB2YUV_SHIFT-1+8)) + (1<<(RGB2YUV_SHIFT-7+8))) >> (RGB2YUV_SHIFT-6+8);
dstV[i] = (RV*r + GV*g + BV*b + (256<<(RGB2YUV_SHIFT-1+8)) + (1<<(RGB2YUV_SHIFT-7+8))) >> (RGB2YUV_SHIFT-6+8); dstV[i] = (RV*r + GV*g + BV*b + (256<<(RGB2YUV_SHIFT-1+8)) + (1<<(RGB2YUV_SHIFT-7+8))) >> (RGB2YUV_SHIFT-6+8);
@@ -1336,17 +1457,18 @@ rgb48ToUV_half_c_template(int16_t *dstU, int16_t *dstV,
int i; int i;
assert(src1==src2); assert(src1==src2);
for (i = 0; i < width; i++) { for (i = 0; i < width; i++) {
int a = (input_pixel(&src1[6*i + 0])) + (input_pixel(&src1[6*i + 3]));
int g = (input_pixel(&src1[6*i + 1])) + (input_pixel(&src1[6*i + 4]));
int c = (input_pixel(&src1[6*i + 2])) + (input_pixel(&src1[6*i + 5]));
int r_b = (input_pixel(&src1[6*i + 0])) + (input_pixel(&src1[6*i + 3]));
int g = (input_pixel(&src1[6*i + 1])) + (input_pixel(&src1[6*i + 4]));
int b_r = (input_pixel(&src1[6*i + 2])) + (input_pixel(&src1[6*i + 5]));


dstU[i]= (RU*r + GU*g + BU*b + (256U<<(RGB2YUV_SHIFT+8)) + (1<<(RGB2YUV_SHIFT-6+8))) >> (RGB2YUV_SHIFT-5+8); dstU[i]= (RU*r + GU*g + BU*b + (256U<<(RGB2YUV_SHIFT+8)) + (1<<(RGB2YUV_SHIFT-6+8))) >> (RGB2YUV_SHIFT-5+8);
dstV[i]= (RV*r + GV*g + BV*b + (256U<<(RGB2YUV_SHIFT+8)) + (1<<(RGB2YUV_SHIFT-6+8))) >> (RGB2YUV_SHIFT-5+8); dstV[i]= (RV*r + GV*g + BV*b + (256U<<(RGB2YUV_SHIFT+8)) + (1<<(RGB2YUV_SHIFT-6+8))) >> (RGB2YUV_SHIFT-5+8);
} }
}

#undef r #undef r
#undef b #undef b
#undef input_pixel #undef input_pixel
}


#define rgb48funcs(pattern, BE_LE, origin) \ #define rgb48funcs(pattern, BE_LE, origin) \
static void pattern ## 48 ## BE_LE ## ToY_c(uint8_t *dst, const uint8_t *src, \ static void pattern ## 48 ## BE_LE ## ToY_c(uint8_t *dst, const uint8_t *src, \
@@ -1374,6 +1496,10 @@ rgb48funcs(rgb, BE, PIX_FMT_RGB48BE);
rgb48funcs(bgr, LE, PIX_FMT_BGR48LE); rgb48funcs(bgr, LE, PIX_FMT_BGR48LE);
rgb48funcs(bgr, BE, PIX_FMT_BGR48BE); rgb48funcs(bgr, BE, PIX_FMT_BGR48BE);


#define input_pixel(i) ((origin == PIX_FMT_RGBA || origin == PIX_FMT_BGRA || \
origin == PIX_FMT_ARGB || origin == PIX_FMT_ABGR) ? AV_RN32A(&src[(i)*4]) : \
(isBE(origin) ? AV_RB16(&src[(i)*2]) : AV_RL16(&src[(i)*2])))

static av_always_inline void static av_always_inline void
rgb16_32ToY_c_template(int16_t *dst, const uint8_t *src, rgb16_32ToY_c_template(int16_t *dst, const uint8_t *src,
int width, enum PixelFormat origin, int width, enum PixelFormat origin,
@@ -1386,9 +1512,6 @@ rgb16_32ToY_c_template(int16_t *dst, const uint8_t *src,
int i; int i;


for (i = 0; i < width; i++) { for (i = 0; i < width; i++) {
#define input_pixel(i) ((origin == PIX_FMT_RGBA || origin == PIX_FMT_BGRA || \
origin == PIX_FMT_ARGB || origin == PIX_FMT_ABGR) ? AV_RN32A(&src[(i)*4]) : \
(isBE(origin) ? AV_RB16(&src[(i)*2]) : AV_RL16(&src[(i)*2])))
int px = input_pixel(i) >> shp; int px = input_pixel(i) >> shp;
int b = (px & maskb) >> shb; int b = (px & maskb) >> shb;
int g = (px & maskg) >> shg; int g = (px & maskg) >> shg;
@@ -1454,9 +1577,10 @@ rgb16_32ToUV_half_c_template(int16_t *dstU, int16_t *dstV,
dstU[i] = (ru * r + gu * g + bu * b + (unsigned)rnd) >> ((S)-6+1); dstU[i] = (ru * r + gu * g + bu * b + (unsigned)rnd) >> ((S)-6+1);
dstV[i] = (rv * r + gv * g + bv * b + (unsigned)rnd) >> ((S)-6+1); dstV[i] = (rv * r + gv * g + bv * b + (unsigned)rnd) >> ((S)-6+1);
} }
#undef input_pixel
} }


#undef input_pixel

#define rgb16_32_wrapper(fmt, name, shr, shg, shb, shp, maskr, \ #define rgb16_32_wrapper(fmt, name, shr, shg, shb, shp, maskr, \
maskg, maskb, rsh, gsh, bsh, S) \ maskg, maskb, rsh, gsh, bsh, S) \
static void name ## ToY_c(uint8_t *dst, const uint8_t *src, \ static void name ## ToY_c(uint8_t *dst, const uint8_t *src, \
@@ -1637,6 +1761,22 @@ static av_always_inline void nvXXtoUV_c(uint8_t *dst1, uint8_t *dst2,
} }
} }


static void nv12ToUV_c(uint8_t *dstU, uint8_t *dstV,
const uint8_t *src1, const uint8_t *src2,
int width, uint32_t *unused)
{
nvXXtoUV_c(dstU, dstV, src1, width);
}

static void nv21ToUV_c(uint8_t *dstU, uint8_t *dstV,
const uint8_t *src1, const uint8_t *src2,
int width, uint32_t *unused)
{
nvXXtoUV_c(dstV, dstU, src1, width);
}

#define input_pixel(pos) (isBE(origin) ? AV_RB16(pos) : AV_RL16(pos))

// FIXME Maybe dither instead. // FIXME Maybe dither instead.
static av_always_inline void static av_always_inline void
yuv9_OR_10ToUV_c_template(uint8_t *dstU, uint8_t *dstV, yuv9_OR_10ToUV_c_template(uint8_t *dstU, uint8_t *dstV,
@@ -1647,7 +1787,6 @@ yuv9_OR_10ToUV_c_template(uint8_t *dstU, uint8_t *dstV,
const uint16_t *srcU = (const uint16_t *) _srcU; const uint16_t *srcU = (const uint16_t *) _srcU;
const uint16_t *srcV = (const uint16_t *) _srcV; const uint16_t *srcV = (const uint16_t *) _srcV;


#define input_pixel(pos) (isBE(origin) ? AV_RB16(pos) : AV_RL16(pos))
for (i = 0; i < width; i++) { for (i = 0; i < width; i++) {
dstU[i] = input_pixel(&srcU[i]) >> (depth - 8); dstU[i] = input_pixel(&srcU[i]) >> (depth - 8);
dstV[i] = input_pixel(&srcV[i]) >> (depth - 8); dstV[i] = input_pixel(&srcV[i]) >> (depth - 8);
@@ -1663,9 +1802,10 @@ yuv9_or_10ToY_c_template(uint8_t *dstY, const uint8_t *_srcY,


for (i = 0; i < width; i++) for (i = 0; i < width; i++)
dstY[i] = input_pixel(&srcY[i]) >> (depth - 8); dstY[i] = input_pixel(&srcY[i]) >> (depth - 8);
#undef input_pixel
} }


#undef input_pixel

#define YUV_NBPS(depth, BE_LE, origin) \ #define YUV_NBPS(depth, BE_LE, origin) \
static void BE_LE ## depth ## ToUV_c(uint8_t *dstU, uint8_t *dstV, \ static void BE_LE ## depth ## ToUV_c(uint8_t *dstU, uint8_t *dstV, \
const uint8_t *srcU, const uint8_t *srcV, \ const uint8_t *srcU, const uint8_t *srcV, \
@@ -1684,20 +1824,6 @@ YUV_NBPS( 9, BE, PIX_FMT_YUV420P9BE);
YUV_NBPS(10, LE, PIX_FMT_YUV420P10LE); YUV_NBPS(10, LE, PIX_FMT_YUV420P10LE);
YUV_NBPS(10, BE, PIX_FMT_YUV420P10BE); YUV_NBPS(10, BE, PIX_FMT_YUV420P10BE);


static inline void nv12ToUV_c(uint8_t *dstU, uint8_t *dstV,
const uint8_t *src1, const uint8_t *src2,
int width, uint32_t *unused)
{
nvXXtoUV_c(dstU, dstV, src1, width);
}

static inline void nv21ToUV_c(uint8_t *dstU, uint8_t *dstV,
const uint8_t *src1, const uint8_t *src2,
int width, uint32_t *unused)
{
nvXXtoUV_c(dstV, dstU, src1, width);
}

static void bgr24ToY_c(int16_t *dst, const uint8_t *src, static void bgr24ToY_c(int16_t *dst, const uint8_t *src,
int width, uint32_t *unused) int width, uint32_t *unused)
{ {
@@ -2003,14 +2129,34 @@ find_c_packed_planar_out_funcs(SwsContext *c,
*yuv2packedX = yuv2monoblack_X_c; *yuv2packedX = yuv2monoblack_X_c;
break; break;
case PIX_FMT_YUYV422: case PIX_FMT_YUYV422:
*yuv2packed1 = yuv2422yuyv_1_c;
*yuv2packed2 = yuv2422yuyv_2_c;
*yuv2packedX = yuv2422yuyv_X_c;
*yuv2packed1 = yuv2yuyv422_1_c;
*yuv2packed2 = yuv2yuyv422_2_c;
*yuv2packedX = yuv2yuyv422_X_c;
break; break;
case PIX_FMT_UYVY422: case PIX_FMT_UYVY422:
*yuv2packed1 = yuv2422uyvy_1_c;
*yuv2packed2 = yuv2422uyvy_2_c;
*yuv2packedX = yuv2422uyvy_X_c;
*yuv2packed1 = yuv2uyvy422_1_c;
*yuv2packed2 = yuv2uyvy422_2_c;
*yuv2packedX = yuv2uyvy422_X_c;
break;
case PIX_FMT_RGB48LE:
//*yuv2packed1 = yuv2rgb48le_1_c;
//*yuv2packed2 = yuv2rgb48le_2_c;
//*yuv2packedX = yuv2rgb48le_X_c;
//break;
case PIX_FMT_RGB48BE:
*yuv2packed1 = yuv2rgb48be_1_c;
*yuv2packed2 = yuv2rgb48be_2_c;
*yuv2packedX = yuv2rgb48be_X_c;
break;
case PIX_FMT_BGR48LE:
//*yuv2packed1 = yuv2bgr48le_1_c;
//*yuv2packed2 = yuv2bgr48le_2_c;
//*yuv2packedX = yuv2bgr48le_X_c;
//break;
case PIX_FMT_BGR48BE:
*yuv2packed1 = yuv2bgr48be_1_c;
*yuv2packed2 = yuv2bgr48be_2_c;
*yuv2packedX = yuv2bgr48be_X_c;
break; break;
default: default:
*yuv2packed1 = yuv2packed1_c; *yuv2packed1 = yuv2packed1_c;


Loading…
Cancel
Save