mirror of https://github.com/FFmpeg/FFmpeg.git
parent
2ea2612df5
commit
65d5d58658
10 changed files with 252 additions and 134 deletions
@ -0,0 +1,80 @@ |
||||
/*
|
||||
* Copyright (c) 2007 Luca Barbato <lu_zero@gentoo.org> |
||||
* |
||||
* This file is part of Libav. |
||||
* |
||||
* Libav is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU Lesser General Public |
||||
* License as published by the Free Software Foundation; either |
||||
* version 2.1 of the License, or (at your option) any later version. |
||||
* |
||||
* Libav is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
* Lesser General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Lesser General Public |
||||
* License along with Libav; if not, write to the Free Software |
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
*/ |
||||
|
||||
#include <stdint.h> |
||||
|
||||
#include "config.h" |
||||
#if HAVE_ALTIVEC_H |
||||
#include <altivec.h> |
||||
#endif |
||||
|
||||
#include "libavutil/attributes.h" |
||||
#include "libavutil/ppc/types_altivec.h" |
||||
#include "libavutil/ppc/util_altivec.h" |
||||
#include "libavcodec/svq1enc.h" |
||||
|
||||
#if HAVE_ALTIVEC |
||||
static int ssd_int8_vs_int16_altivec(const int8_t *pix1, const int16_t *pix2, |
||||
int size) |
||||
{ |
||||
int i, size16 = size >> 4; |
||||
vector signed char vpix1; |
||||
vector signed short vpix2, vdiff, vpix1l, vpix1h; |
||||
union { |
||||
vector signed int vscore; |
||||
int32_t score[4]; |
||||
} u = { .vscore = vec_splat_s32(0) }; |
||||
|
||||
while (size16) { |
||||
// score += (pix1[i] - pix2[i]) * (pix1[i] - pix2[i]);
|
||||
// load pix1 and the first batch of pix2
|
||||
|
||||
vpix1 = vec_unaligned_load(pix1); |
||||
vpix2 = vec_unaligned_load(pix2); |
||||
pix2 += 8; |
||||
// unpack
|
||||
vpix1h = vec_unpackh(vpix1); |
||||
vdiff = vec_sub(vpix1h, vpix2); |
||||
vpix1l = vec_unpackl(vpix1); |
||||
// load another batch from pix2
|
||||
vpix2 = vec_unaligned_load(pix2); |
||||
u.vscore = vec_msum(vdiff, vdiff, u.vscore); |
||||
vdiff = vec_sub(vpix1l, vpix2); |
||||
u.vscore = vec_msum(vdiff, vdiff, u.vscore); |
||||
pix1 += 16; |
||||
pix2 += 8; |
||||
size16--; |
||||
} |
||||
u.vscore = vec_sums(u.vscore, vec_splat_s32(0)); |
||||
|
||||
size %= 16; |
||||
for (i = 0; i < size; i++) |
||||
u.score[3] += (pix1[i] - pix2[i]) * (pix1[i] - pix2[i]); |
||||
|
||||
return u.score[3]; |
||||
} |
||||
#endif /* HAVE_ALTIVEC */ |
||||
|
||||
av_cold void ff_svq1enc_init_ppc(SVQ1EncContext *c) |
||||
{ |
||||
#if HAVE_ALTIVEC |
||||
c->ssd_int8_vs_int16 = ssd_int8_vs_int16_altivec; |
||||
#endif /* HAVE_ALTIVEC */ |
||||
} |
@ -0,0 +1,78 @@ |
||||
/*
|
||||
* SVQ1 encoder |
||||
* |
||||
* This file is part of Libav. |
||||
* |
||||
* Libav is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU Lesser General Public |
||||
* License as published by the Free Software Foundation; either |
||||
* version 2.1 of the License, or (at your option) any later version. |
||||
* |
||||
* Libav is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
* Lesser General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Lesser General Public |
||||
* License along with Libav; if not, write to the Free Software |
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
*/ |
||||
|
||||
#ifndef AVCODEC_SVQ1ENC_H |
||||
#define AVCODEC_SVQ1ENC_H |
||||
|
||||
#include <stdint.h> |
||||
|
||||
#include "libavutil/frame.h" |
||||
#include "avcodec.h" |
||||
#include "dsputil.h" |
||||
#include "get_bits.h" |
||||
#include "hpeldsp.h" |
||||
#include "mpegvideo.h" |
||||
#include "put_bits.h" |
||||
|
||||
typedef struct SVQ1EncContext { |
||||
/* FIXME: Needed for motion estimation, should not be used for anything
|
||||
* else, the idea is to make the motion estimation eventually independent |
||||
* of MpegEncContext, so this will be removed then. */ |
||||
MpegEncContext m; |
||||
AVCodecContext *avctx; |
||||
DSPContext dsp; |
||||
HpelDSPContext hdsp; |
||||
AVFrame *current_picture; |
||||
AVFrame *last_picture; |
||||
PutBitContext pb; |
||||
GetBitContext gb; |
||||
|
||||
/* why ooh why this sick breadth first order,
|
||||
* everything is slower and more complex */ |
||||
PutBitContext reorder_pb[6]; |
||||
|
||||
int frame_width; |
||||
int frame_height; |
||||
|
||||
/* Y plane block dimensions */ |
||||
int y_block_width; |
||||
int y_block_height; |
||||
|
||||
/* U & V plane (C planes) block dimensions */ |
||||
int c_block_width; |
||||
int c_block_height; |
||||
|
||||
uint16_t *mb_type; |
||||
uint32_t *dummy; |
||||
int16_t (*motion_val8[3])[2]; |
||||
int16_t (*motion_val16[3])[2]; |
||||
|
||||
int64_t rd_total; |
||||
|
||||
uint8_t *scratchbuf; |
||||
|
||||
int (*ssd_int8_vs_int16)(const int8_t *pix1, const int16_t *pix2, |
||||
int size); |
||||
} SVQ1EncContext; |
||||
|
||||
void ff_svq1enc_init_ppc(SVQ1EncContext *c); |
||||
void ff_svq1enc_init_x86(SVQ1EncContext *c); |
||||
|
||||
#endif /* AVCODEC_SVQ1ENC_H */ |
@ -0,0 +1,73 @@ |
||||
/*
|
||||
* This file is part of Libav. |
||||
* |
||||
* Libav is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU Lesser General Public |
||||
* License as published by the Free Software Foundation; either |
||||
* version 2.1 of the License, or (at your option) any later version. |
||||
* |
||||
* Libav is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
* Lesser General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Lesser General Public |
||||
* License along with Libav; if not, write to the Free Software |
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
*/ |
||||
|
||||
#include "config.h" |
||||
#include "libavutil/attributes.h" |
||||
#include "libavutil/cpu.h" |
||||
#include "libavutil/x86/asm.h" |
||||
#include "libavutil/x86/cpu.h" |
||||
#include "libavcodec/svq1enc.h" |
||||
|
||||
#if HAVE_INLINE_ASM |
||||
|
||||
static int ssd_int8_vs_int16_mmx(const int8_t *pix1, const int16_t *pix2, |
||||
int size) |
||||
{ |
||||
int sum; |
||||
x86_reg i = size; |
||||
|
||||
__asm__ volatile ( |
||||
"pxor %%mm4, %%mm4 \n" |
||||
"1: \n" |
||||
"sub $8, %0 \n" |
||||
"movq (%2, %0), %%mm2 \n" |
||||
"movq (%3, %0, 2), %%mm0 \n" |
||||
"movq 8(%3, %0, 2), %%mm1 \n" |
||||
"punpckhbw %%mm2, %%mm3 \n" |
||||
"punpcklbw %%mm2, %%mm2 \n" |
||||
"psraw $8, %%mm3 \n" |
||||
"psraw $8, %%mm2 \n" |
||||
"psubw %%mm3, %%mm1 \n" |
||||
"psubw %%mm2, %%mm0 \n" |
||||
"pmaddwd %%mm1, %%mm1 \n" |
||||
"pmaddwd %%mm0, %%mm0 \n" |
||||
"paddd %%mm1, %%mm4 \n" |
||||
"paddd %%mm0, %%mm4 \n" |
||||
"jg 1b \n" |
||||
"movq %%mm4, %%mm3 \n" |
||||
"psrlq $32, %%mm3 \n" |
||||
"paddd %%mm3, %%mm4 \n" |
||||
"movd %%mm4, %1 \n" |
||||
: "+r" (i), "=r" (sum) |
||||
: "r" (pix1), "r" (pix2)); |
||||
|
||||
return sum; |
||||
} |
||||
|
||||
#endif /* HAVE_INLINE_ASM */ |
||||
|
||||
av_cold void ff_svq1enc_init_x86(SVQ1EncContext *c) |
||||
{ |
||||
#if HAVE_INLINE_ASM |
||||
int cpu_flags = av_get_cpu_flags(); |
||||
|
||||
if (INLINE_MMX(cpu_flags)) { |
||||
c->ssd_int8_vs_int16 = ssd_int8_vs_int16_mmx; |
||||
} |
||||
#endif /* HAVE_INLINE_ASM */ |
||||
} |
Loading…
Reference in new issue