* 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
| @@ -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 | ||||
| @@ -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) | ||||
| @@ -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; | ||||
| @@ -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, | ||||
| @@ -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. | ||||
| @@ -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; | ||||
| @@ -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 | ||||
| @@ -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] | ||||
| @@ -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 | ||||
| @@ -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 | ||||
| } | } | ||||
| @@ -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; | ||||
| @@ -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); | ||||
| @@ -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 | ||||
| } | } | ||||
| @@ -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{ | ||||
| @@ -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; | ||||
| @@ -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); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| /** | /** | ||||
| @@ -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); | ||||
| @@ -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); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -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); | ||||
| @@ -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; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -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" | ||||
| @@ -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; | ||||
| @@ -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) | ||||
| @@ -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 | ||||
| @@ -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; | ||||