* 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) | |||
| 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) | |||
| PROGS-$(CONFIG_FFMPEG) += ffmpeg | |||
| @@ -24,6 +29,8 @@ ALLPROGS = $(BASENAMES:%=%$(EXESUF)) | |||
| ALLPROGS_G = $(BASENAMES:%=%_g$(EXESUF)) | |||
| ALLMANPAGES = $(BASENAMES:%=%.1) | |||
| ALLFFLIBS = avcodec avdevice avfilter avformat avutil postproc swscale | |||
| FFLIBS-$(CONFIG_AVDEVICE) += avdevice | |||
| FFLIBS-$(CONFIG_AVFILTER) += avfilter | |||
| FFLIBS-$(CONFIG_AVFORMAT) += avformat | |||
| @@ -6,11 +6,6 @@ | |||
| all: all-yes | |||
| ifndef SUBDIR | |||
| vpath %.c $(SRC_DIR) | |||
| vpath %.h $(SRC_DIR) | |||
| vpath %.S $(SRC_DIR) | |||
| vpath %.asm $(SRC_DIR) | |||
| vpath %.v $(SRC_DIR) | |||
| ifndef V | |||
| Q = @ | |||
| @@ -25,8 +20,6 @@ $(foreach VAR,$(SILENT),$(eval override $(VAR) = @$($(VAR)))) | |||
| $(eval INSTALL = @$(call ECHO,INSTALL,$$(^:$(SRC_DIR)/%=%)); $(INSTALL)) | |||
| endif | |||
| ALLFFLIBS = avcodec avdevice avfilter avformat avutil postproc swscale | |||
| IFLAGS := -I. -I$(SRC_PATH) | |||
| CPPFLAGS := $(IFLAGS) $(CPPFLAGS) | |||
| CFLAGS += $(ECFLAGS) | |||
| @@ -2215,15 +2215,9 @@ static av_cold int allocate_buffers(AVCodecContext *avctx) | |||
| AC3EncodeContext *s = avctx->priv_data; | |||
| 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 * | |||
| AC3_MAX_COEFS * sizeof(*s->bap_buffer), alloc_fail); | |||
| 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; | |||
| int ret, frame_size_58; | |||
| s->avctx = avctx; | |||
| s->eac3 = avctx->codec_id == CODEC_ID_EAC3; | |||
| 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->normalize_samples = ff_ac3_fixed_normalize_samples; | |||
| 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->apply_mdct = ff_ac3_fixed_apply_mdct; | |||
| 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->apply_window = ff_ac3_float_apply_window; | |||
| 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->apply_mdct = ff_ac3_float_apply_mdct; | |||
| s->apply_channel_coupling = ff_ac3_float_apply_channel_coupling; | |||
| @@ -135,6 +135,7 @@ typedef struct AC3Block { | |||
| typedef struct AC3EncodeContext { | |||
| AVClass *av_class; ///< AVClass used for AVOption | |||
| AC3EncOptions options; ///< encoding options | |||
| AVCodecContext *avctx; ///< parent AVCodecContext | |||
| PutBitContext pb; ///< bitstream writer context | |||
| DSPContext dsp; | |||
| AC3DSPContext ac3dsp; ///< AC-3 optimized functions | |||
| @@ -230,6 +231,7 @@ typedef struct AC3EncodeContext { | |||
| void (*scale_coefficients)(struct AC3EncodeContext *s); | |||
| /* fixed vs. float templated function pointers */ | |||
| int (*allocate_sample_buffers)(struct AC3EncodeContext *s); | |||
| void (*deinterleave_input_samples)(struct AC3EncodeContext *s, | |||
| const SampleType *samples); | |||
| 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 */ | |||
| 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, | |||
| const SampleType *samples); | |||
| void ff_ac3_float_deinterleave_input_samples(AC3EncodeContext *s, | |||
| @@ -31,6 +31,26 @@ | |||
| #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. | |||
| * 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_add16 = ff_h264_idct_add16_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_dc_add = ff_h264_idct8_dc_add_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) | |||
| */ | |||
| .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 | |||
| push {r4-r9,lr} | |||
| mov ip, #0 | |||
| @@ -44,50 +59,20 @@ function ff_dct_unquantize_h263_armv5te, export=1 | |||
| 1: | |||
| 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 r9, [r0], #2 | |||
| strh r5, [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 r9, [r0], #2 | |||
| @@ -333,6 +333,20 @@ function idct_col_armv5te | |||
| ldr pc, [sp], #4 | |||
| 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 | |||
| str lr, [sp, #-4]! | |||
| @@ -341,27 +355,15 @@ function idct_col_put_armv5te | |||
| ldmfd sp!, {a3, a4} | |||
| ldr lr, [sp, #32] | |||
| 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 | |||
| 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 | |||
| 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 | |||
| movs a4, a4, asr #20 | |||
| movmi a4, #0 | |||
| cmp a4, #255 | |||
| clip a4, a4, asr #20 | |||
| ldr v1, [sp, #28] | |||
| movgt a4, #255 | |||
| strh a2, [v1] | |||
| add a2, v1, #2 | |||
| str a2, [sp, #28] | |||
| @@ -371,79 +373,43 @@ function idct_col_put_armv5te | |||
| strh a2, [v2, v1]! | |||
| 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 | |||
| 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 | |||
| strh a2, [v1, lr]! | |||
| 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 | |||
| 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 | |||
| ldmfd sp!, {a3, a4} | |||
| strh a2, [v2, -lr]! | |||
| 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 | |||
| 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 | |||
| strh a2, [v1, lr]! | |||
| 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 | |||
| 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 | |||
| ldmfd sp!, {a3, a4} | |||
| strh a2, [v2, -lr]! | |||
| 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 | |||
| 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 | |||
| strh a2, [v1, lr] | |||
| 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 | |||
| 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 | |||
| strh a2, [v2, -lr] | |||
| @@ -460,36 +426,22 @@ function idct_col_add_armv5te | |||
| ldmfd sp!, {a3, a4} | |||
| ldrh ip, [lr] | |||
| add a2, a3, v1 | |||
| mov a2, a2, asr #20 | |||
| sub a3, a3, v1 | |||
| 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 | |||
| 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 | |||
| ldr v1, [sp, #32] | |||
| sub a4, a4, v2 | |||
| rsb v2, v1, v1, lsl #3 | |||
| ldrh ip, [v2, lr]! | |||
| strh a2, [lr] | |||
| mov a3, a3, asr #20 | |||
| 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 | |||
| 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 | |||
| str a2, [sp, #28] | |||
| orr a2, a3, a4, lsl #8 | |||
| @@ -498,102 +450,60 @@ function idct_col_add_armv5te | |||
| ldmfd sp!, {a3, a4} | |||
| ldrh ip, [lr, v1]! | |||
| sub a2, a3, v3 | |||
| mov a2, a2, asr #20 | |||
| add a3, a3, v3 | |||
| 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 | |||
| 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 | |||
| add a4, a4, v4 | |||
| ldrh ip, [v2, -v1]! | |||
| strh a2, [lr] | |||
| mov a3, a3, asr #20 | |||
| 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 | |||
| 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 | |||
| strh a2, [v2] | |||
| ldmfd sp!, {a3, a4} | |||
| ldrh ip, [lr, v1]! | |||
| add a2, a3, v5 | |||
| mov a2, a2, asr #20 | |||
| sub a3, a3, v5 | |||
| 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 | |||
| 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 | |||
| sub a4, a4, v6 | |||
| ldrh ip, [v2, -v1]! | |||
| strh a2, [lr] | |||
| mov a3, a3, asr #20 | |||
| 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 | |||
| 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 | |||
| strh a2, [v2] | |||
| ldmfd sp!, {a3, a4} | |||
| ldrh ip, [lr, v1]! | |||
| add a2, a3, v7 | |||
| mov a2, a2, asr #20 | |||
| sub a3, a3, v7 | |||
| 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 | |||
| 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 | |||
| sub a4, a4, fp | |||
| ldrh ip, [v2, -v1]! | |||
| strh a2, [lr] | |||
| mov a3, a3, asr #20 | |||
| 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 | |||
| 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 | |||
| strh a2, [v2] | |||
| @@ -505,7 +505,7 @@ typedef struct DSPContext { | |||
| #define BASIS_SHIFT 16 | |||
| #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_TOP 1 | |||
| #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 */ | |||
| //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; | |||
| 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; | |||
| last_line = buf + (height - 1) * wrap; | |||
| 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 | |||
| 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 | |||
| } | |||
| @@ -39,9 +39,6 @@ | |||
| #define interlaced_dct interlaced_dct_is_a_bad_name | |||
| #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 COEFF_TOKEN_VLC_BITS 8 | |||
| #define TOTAL_ZEROS_VLC_BITS 9 | |||
| @@ -60,8 +57,6 @@ | |||
| * of progressive decoding by about 2%. */ | |||
| #define ALLOW_INTERLACE | |||
| #define ALLOW_NOCHROMA | |||
| #define FMO 0 | |||
| /** | |||
| @@ -85,16 +80,12 @@ | |||
| #endif | |||
| #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 | |||
| #define CABAC h->pps.cabac | |||
| #endif | |||
| #define CHROMA444 (h->sps.chroma_format_idc == 3) | |||
| #define EXTENDED_SAR 255 | |||
| #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 scaling_matrix_present; | |||
| 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 vcl_hrd_parameters_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 transform_8x8_mode; ///< transform_8x8_mode_flag | |||
| 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 | |||
| int chroma_qp_diff; | |||
| }PPS; | |||
| @@ -298,21 +289,15 @@ typedef struct H264Context{ | |||
| unsigned int top_samples_available; | |||
| unsigned int topright_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. | |||
| * 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. | |||
| @@ -336,7 +321,7 @@ typedef struct H264Context{ | |||
| * block_offset[ 0..23] for frame 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 *mb2br_xy; | |||
| @@ -356,9 +341,9 @@ typedef struct H264Context{ | |||
| 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 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 (*dequant8_coeff[2])[64]; | |||
| uint32_t (*dequant8_coeff[6])[64]; | |||
| int slice_num; | |||
| uint16_t *slice_table; ///< slice_table_base + 2*mb_stride + 1 | |||
| @@ -408,15 +393,15 @@ typedef struct H264Context{ | |||
| GetBitContext *intra_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 | |||
| /** | |||
| * 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 */ | |||
| uint16_t *cbp_table; | |||
| @@ -721,27 +706,43 @@ o-o o-o | |||
| */ | |||
| /* 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. | |||
| */ | |||
| #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 | |||
| 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){ | |||
| @@ -773,11 +774,11 @@ static void fill_decode_neighbors(H264Context *h, int mb_type){ | |||
| MpegEncContext * const s = &h->s; | |||
| const int mb_xy= h->mb_xy; | |||
| 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; | |||
| @@ -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) | |||
| 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++) { | |||
| 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{ | |||
| 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) { | |||
| h->top_cbp = h->cbp_table[top_xy]; | |||
| } else { | |||
| h->top_cbp = IS_INTRA(mb_type) ? 0x1CF : 0x00F; | |||
| h->top_cbp = IS_INTRA(mb_type) ? 0x7CF : 0x00F; | |||
| } | |||
| // left_cbp | |||
| 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[1]]>>(left_block[2]&(~1)))&2) << 2); | |||
| } 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){ | |||
| 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){ | |||
| @@ -1267,8 +1287,7 @@ static void av_unused decode_mb_skip(H264Context *h){ | |||
| const int mb_xy= h->mb_xy; | |||
| 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) | |||
| 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 | |||
| 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); | |||
| total_coeff= coeff_token>>2; | |||
| }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); | |||
| total_coeff= coeff_token>>2; | |||
| }else{ | |||
| @@ -482,7 +482,8 @@ static int decode_residual(H264Context *h, GetBitContext *gb, DCTELEM *block, in | |||
| if(total_coeff == max_coeff) | |||
| zeros_left=0; | |||
| 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); | |||
| else | |||
| 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; | |||
| } | |||
| 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){ | |||
| MpegEncContext * const s = &h->s; | |||
| int mb_xy; | |||
| int partition_count; | |||
| unsigned int mb_type, cbp; | |||
| 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; | |||
| 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)){ | |||
| 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. | |||
| align_get_bits(&s->gb); | |||
| // 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); | |||
| } | |||
| // In deblocking, the quantizer is 0 | |||
| s->current_picture.qscale_table[mb_xy]= 0; | |||
| // 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; | |||
| return 0; | |||
| @@ -668,7 +739,7 @@ decode_intra_mb: | |||
| if(h->intra16x16_pred_mode < 0) | |||
| return -1; | |||
| } | |||
| if(CHROMA){ | |||
| if(decode_chroma){ | |||
| pred_mode= ff_h264_check_intra_pred_mode(h, get_ue_golomb_31(&s->gb)); | |||
| if(pred_mode < 0) | |||
| return -1; | |||
| @@ -896,15 +967,19 @@ decode_intra_mb: | |||
| if(!IS_INTRA16x16(mb_type)){ | |||
| 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]; | |||
| else cbp= golomb_to_inter_cbp [cbp]; | |||
| }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]; | |||
| else cbp= golomb_to_inter_cbp_gray[cbp]; | |||
| } | |||
| @@ -918,8 +993,9 @@ decode_intra_mb: | |||
| s->current_picture.mb_type[mb_xy]= mb_type; | |||
| if(cbp || IS_INTRA16x16(mb_type)){ | |||
| int i8x8, i4x4, chroma_idx; | |||
| int i4x4, chroma_idx; | |||
| int dquant; | |||
| int ret; | |||
| GetBitContext *gb= IS_INTRA(mb_type) ? h->intra_gb_ptr : h->inter_gb_ptr; | |||
| const uint8_t *scan, *scan8x8; | |||
| 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[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++){ | |||
| 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; | |||
| } | |||
| } | |||
| } | |||
| }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{ | |||
| 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; | |||
| 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_type, left_type; | |||
| int qp, qp0, qp1, qpc, qpc0, qpc1, qp_thresh; | |||
| int chroma = !(CONFIG_GRAY && (s->flags&CODEC_FLAG_GRAY)); | |||
| 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); | |||
| 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*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; | |||
| } else { | |||
| 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)\ | |||
| 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 );\ | |||
| 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_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; | |||
| } | |||
| 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; | |||
| int edge; | |||
| int chroma_qp_avg[2]; | |||
| 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; | |||
| @@ -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[3]= 1+((h->cbp_table[mbn_xy] & 8)||h->non_zero_count_cache[scan8[0]+3]); | |||
| }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; | |||
| for( i = 0; i < 4; 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); | |||
| { 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_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{ | |||
| 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 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"); } | |||
| 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 ) { | |||
| 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 { | |||
| 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"); } | |||
| if( dir == 0 ) { | |||
| 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 { | |||
| 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; | |||
| int first_vertical_edge_done = 0; | |||
| av_unused int dir; | |||
| int chroma = !(CONFIG_GRAY && (s->flags&CODEC_FLAG_GRAY)); | |||
| if (FRAME_MBAFF | |||
| // 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 { | |||
| 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]; | |||
| @@ -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){ | |||
| 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_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{ | |||
| 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_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 | |||
| 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 | |||
| 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 | |||
| } | |||
| @@ -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[3] : default_scaling4[1], | |||
| 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)){ | |||
| 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 | |||
| 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[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){ | |||
| 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"); | |||
| } | |||
| }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_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_chroma_dc_dequant_idct)(DCTELEM *block, int qmul); | |||
| }H264DSPContext; | |||
| @@ -30,15 +30,19 @@ | |||
| #ifndef 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 | |||
| 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 | |||
| @@ -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; | |||
| for(i=0; i<16; 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; | |||
| 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); | |||
| @@ -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; | |||
| for(i=0; i<16; i+=4){ | |||
| 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->intra_only | |||
| && !(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(); | |||
| @@ -2289,14 +2294,19 @@ void ff_draw_horiz_band(MpegEncContext *s, int y, int h){ | |||
| && !s->intra_only | |||
| && !(s->flags&CODEC_FLAG_EMU_EDGE)) { | |||
| 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 + h >= s->v_edge_pos) sides |= EDGE_BOTTOM; | |||
| 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); | |||
| @@ -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); | |||
| } | |||
| 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; | |||
| for(i=0; i<16; 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; | |||
| for(i=0; i<16; i++){ | |||
| 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; | |||
| for(i=0; i<16; i+=4){ | |||
| 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; | |||
| 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); | |||
| @@ -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); | |||
| } | |||
| 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)) { | |||
| @@ -656,8 +657,8 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int 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)){ | |||
| av_log(h->s.avctx, AV_LOG_ERROR, "error while decoding intra luma dc\n"); | |||
| return -1; | |||
| @@ -683,20 +684,23 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type) | |||
| } | |||
| 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"); | |||
| return -1; | |||
| } | |||
| } | |||
| 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 | |||
| 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; | |||
| 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) */ | |||
| if (sides&EDGE_TOP) { | |||
| for(i = 0; i < w; i += 4) { | |||
| for(i = 0; i < h; i += 4) { | |||
| ptr= buf - (i + 1) * wrap - w; | |||
| __asm__ volatile( | |||
| "1: \n\t" | |||
| @@ -36,7 +36,7 @@ | |||
| #if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) | |||
| static int decode_significance_x86(CABACContext *c, int max_coeff, | |||
| uint8_t *significant_coeff_ctx_base, | |||
| int *index){ | |||
| int *index, x86_reg last_off){ | |||
| void *end= significant_coeff_ctx_base + max_coeff - 1; | |||
| int minusstart= -(int)significant_coeff_ctx_base; | |||
| int minusindex= 4-(int)index; | |||
| @@ -52,10 +52,12 @@ static int decode_significance_x86(CABACContext *c, int max_coeff, | |||
| "test $1, %%edx \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") | |||
| "sub %7, %1 \n\t" | |||
| "mov %2, %%"REG_a" \n\t" | |||
| "movl %4, %%ecx \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 %%ebx, "LOW "(%3) \n\t" | |||
| :"=&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" | |||
| ); | |||
| 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, | |||
| 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 coeff_count; | |||
| 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" | |||
| "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") | |||
| "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 %%ebx, "LOW "(%3) \n\t" | |||
| :"=&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" | |||
| ); | |||
| return coeff_count; | |||
| @@ -32,14 +32,18 @@ | |||
| SECTION_RODATA | |||
| ; 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 | |||
| %define scan8 r11 | |||
| %else | |||
| @@ -617,6 +621,8 @@ cglobal h264_idct_add8_8_mmx, 5, 7, 0 | |||
| mov r10, r0 | |||
| %endif | |||
| call h264_idct_add8_mmx_plane | |||
| mov r5, 32 | |||
| add r2, 384 | |||
| %ifdef ARCH_X86_64 | |||
| add r10, gprsize | |||
| %else | |||
| @@ -678,6 +684,8 @@ cglobal h264_idct_add8_8_mmx2, 5, 7, 0 | |||
| lea r11, [scan8_mem] | |||
| %endif | |||
| call h264_idct_add8_mmx2_plane | |||
| mov r5, 32 | |||
| add r2, 384 | |||
| %ifdef ARCH_X86_64 | |||
| add r10, gprsize | |||
| %else | |||
| @@ -810,12 +818,12 @@ cglobal h264_idct_add16intra_8_sse2, 5, 7, 8 | |||
| test r0, r0 | |||
| jz .try%1dc | |||
| %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] | |||
| %else | |||
| mov r0, r0m | |||
| mov r0, [r0] | |||
| add r0, dword [r1+%1*8+64] | |||
| add r0, dword [r1+(%1&1)*8+64*(1+(%1>>1))] | |||
| %endif | |||
| call x264_add8x4_idct_sse2 | |||
| jmp .cycle%1end | |||
| @@ -824,16 +832,18 @@ cglobal h264_idct_add16intra_8_sse2, 5, 7, 8 | |||
| or r0w, word [r2+32] | |||
| jz .cycle%1end | |||
| %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] | |||
| %else | |||
| mov r0, r0m | |||
| mov r0, [r0] | |||
| add r0, dword [r1+%1*8+64] | |||
| add r0, dword [r1+(%1&1)*8+64*(1+(%1>>1))] | |||
| %endif | |||
| call h264_idct_dc_add8_mmx2 | |||
| .cycle%1end | |||
| %if %1 < 3 | |||
| %if %1 == 1 | |||
| add r2, 384+64 | |||
| %elif %1 < 3 | |||
| add r2, 64 | |||
| %endif | |||
| %endmacro | |||
| @@ -845,15 +855,15 @@ cglobal h264_idct_add8_8_sse2, 5, 7, 8 | |||
| %ifdef ARCH_X86_64 | |||
| mov r10, r0 | |||
| %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 | |||
| add r10, gprsize | |||
| %else | |||
| add r0mp, gprsize | |||
| %endif | |||
| add8_sse2_cycle 2, 0x21 | |||
| add8_sse2_cycle 3, 0x29 | |||
| add8_sse2_cycle 2, 0x5c | |||
| add8_sse2_cycle 3, 0x64 | |||
| RET | |||
| ;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) | |||
| 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 | |||
| %define scan8 r11 | |||
| @@ -306,7 +310,7 @@ INIT_AVX | |||
| IDCT_ADD16INTRA_10 avx | |||
| %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]) | |||
| ;----------------------------------------------------------------------------- | |||
| @@ -317,21 +321,22 @@ cglobal h264_idct_add8_10_%1,5,7 | |||
| %endif | |||
| add r2, 1024 | |||
| 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 | |||
| mov r0, [r10+gprsize] | |||
| %else | |||
| mov r0, r0m | |||
| mov r0, [r0+gprsize] | |||
| %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 | |||
| AC %1, 16 | |||
| AC %1, 18 | |||
| AC %1, 20 | |||
| AC %1, 22 | |||
| AC %1, 32 | |||
| AC %1, 34 | |||
| %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 | |||
| yuv2gray16_X_c_template(SwsContext *c, const int16_t *lumFilter, | |||
| const int16_t **lumSrc, int lumFilterSize, | |||
| @@ -516,12 +523,6 @@ yuv2gray16_X_c_template(SwsContext *c, const int16_t *lumFilter, | |||
| { | |||
| 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++) { | |||
| int j; | |||
| 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 + 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, \ | |||
| const int16_t **lumSrc, int lumFilterSize, \ | |||
| 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, \ | |||
| int y) \ | |||
| { \ | |||
| name ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \ | |||
| name ## base ## _X_c_template(c, lumFilter, lumSrc, lumFilterSize, \ | |||
| chrFilter, chrUSrc, chrVSrc, chrFilterSize, \ | |||
| 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, \ | |||
| 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, \ | |||
| 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 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, \ | |||
| 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 | |||
| 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 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) { | |||
| int j; | |||
| 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]]; | |||
| 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) \ | |||
| if (target == PIX_FMT_YUYV422) { \ | |||
| @@ -747,6 +741,16 @@ yuv2422_X_c_template(SwsContext *c, const int16_t *lumFilter, | |||
| 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++) { | |||
| int j; | |||
| 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); | |||
| } | |||
| } | |||
| } | |||
| #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) \ | |||
| for (i=0; i<(dstW>>1); i++) {\ | |||
| @@ -974,36 +1123,6 @@ YUV2PACKEDWRAPPER(yuv2422, uyvy, PIX_FMT_UYVY422); | |||
| #define YSCALE_YUV_2_ANYRGB_C(func)\ | |||
| 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_BGRA:\ | |||
| 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 | |||
| rgb48ToY_c_template(int16_t *dst, const uint16_t *src, int width, | |||
| enum PixelFormat origin) | |||
| { | |||
| int 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); | |||
| } | |||
| } | |||
| @@ -1319,9 +1440,9 @@ rgb48ToUV_c_template(int16_t *dstU, int16_t *dstV, | |||
| int i; | |||
| assert(src1==src2); | |||
| 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); | |||
| 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; | |||
| assert(src1==src2); | |||
| 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); | |||
| dstV[i]= (RV*r + GV*g + BV*b + (256U<<(RGB2YUV_SHIFT+8)) + (1<<(RGB2YUV_SHIFT-6+8))) >> (RGB2YUV_SHIFT-5+8); | |||
| } | |||
| } | |||
| #undef r | |||
| #undef b | |||
| #undef input_pixel | |||
| } | |||
| #define rgb48funcs(pattern, BE_LE, origin) \ | |||
| 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, 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 | |||
| rgb16_32ToY_c_template(int16_t *dst, const uint8_t *src, | |||
| int width, enum PixelFormat origin, | |||
| @@ -1386,9 +1512,6 @@ rgb16_32ToY_c_template(int16_t *dst, const uint8_t *src, | |||
| int 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 b = (px & maskb) >> shb; | |||
| 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); | |||
| 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, \ | |||
| maskg, maskb, rsh, gsh, bsh, S) \ | |||
| 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. | |||
| static av_always_inline void | |||
| 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 *srcV = (const uint16_t *) _srcV; | |||
| #define input_pixel(pos) (isBE(origin) ? AV_RB16(pos) : AV_RL16(pos)) | |||
| for (i = 0; i < width; i++) { | |||
| dstU[i] = input_pixel(&srcU[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++) | |||
| dstY[i] = input_pixel(&srcY[i]) >> (depth - 8); | |||
| #undef input_pixel | |||
| } | |||
| #undef input_pixel | |||
| #define YUV_NBPS(depth, BE_LE, origin) \ | |||
| static void BE_LE ## depth ## ToUV_c(uint8_t *dstU, uint8_t *dstV, \ | |||
| 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, 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, | |||
| int width, uint32_t *unused) | |||
| { | |||
| @@ -2003,14 +2129,34 @@ find_c_packed_planar_out_funcs(SwsContext *c, | |||
| *yuv2packedX = yuv2monoblack_X_c; | |||
| break; | |||
| 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; | |||
| 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; | |||
| default: | |||
| *yuv2packed1 = yuv2packed1_c; | |||