Commit c78ab927 authored by jehan's avatar jehan
Browse files

Merge branch 'dev_android_video' of git.linphone.org:mediastreamer2-private into dev_android_video

parents ff6c49c8 91879863
......@@ -26,7 +26,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
void ms_line_rgb2rgb565_4(const int16_t *r, const int16_t *g, const int16_t *b, uint16_t *dst, int width);
void ms_line_rgb2rgb565_8(const int16_t *r, const int16_t *g, const int16_t *b, uint16_t *dst, int width);
void ms_line_scale_8(const uint32_t *grid, const int16_t *src[], int16_t *dst[], int dst_width);
void ms_line_scale_8(const uint32_t *grid, const int16_t * const src[], int16_t *dst[], int dst_width, const int16_t *filter);
void ms_line_scale_simple_8(const uint32_t *grid, const int16_t * const src[], int16_t *dst[], int dst_width);
typedef struct AndroidScalerCtx{
MSVideoSize src_size;
......@@ -34,6 +35,7 @@ typedef struct AndroidScalerCtx{
int16_t *unscaled_2lines[3];
int16_t *hscaled_img[3];
uint32_t *hgrid;
int16_t *hcoeffs;
int hscaled_img_stride;
int unscaled_stride;
int w_inc;
......@@ -63,7 +65,6 @@ static void init_premults(){
}
}
static inline void line_yuv2rgb(uint8_t *y, uint8_t *u, uint8_t *v, int16_t *r, int16_t *g, int16_t *b, int n);
static int32_t yuvmax[4]={255,255,255,255};
......@@ -126,7 +127,6 @@ static inline void yuv2rgb_4x2(const uint8_t *y1, const uint8_t *y2, const uint8
int32x4_t rub;
int32x4_t rr1,rg1,rb1,rr2,rg2,rb2;
int32x4_t max;
int16x4_t res1,res2;
LOAD_Y_PREMULTS(0)
LOAD_Y_PREMULTS(1)
......@@ -136,14 +136,16 @@ static inline void yuv2rgb_4x2(const uint8_t *y1, const uint8_t *y2, const uint8
LOAD_UV_PREMULTS(0)
LOAD_UV_PREMULTS(1)
max=vld1q_s32(yuvmax);
/*the following does not work */
/*max=vdupq_n_s32(255);*/
rr1=vaddq_s32(ry1,rvr);
rr2=vaddq_s32(ry2,rvr);
rg1=vaddq_s32(ry1,rvug);
rg2=vaddq_s32(ry2,rvug);
rb1=vaddq_s32(ry1,rub);
rb2=vaddq_s32(ry2,rub);
max=vld1q_s32(yuvmax);
rr1=vminq_s32(vabsq_s32(vshrq_n_s32(rr1,13)),max);
rr2=vminq_s32(vabsq_s32(vshrq_n_s32(rr2,13)),max);
......@@ -152,20 +154,14 @@ static inline void yuv2rgb_4x2(const uint8_t *y1, const uint8_t *y2, const uint8
rb1=vminq_s32(vabsq_s32(vshrq_n_s32(rb1,13)),max);
rb2=vminq_s32(vabsq_s32(vshrq_n_s32(rb2,13)),max);
res1=vmovn_s32(rr1);
res2=vmovn_s32(rr2);
vst1_s16(r1,res1);
vst1_s16(r2,res2);
res1=vmovn_s32(rg1);
res2=vmovn_s32(rg2);
vst1_s16(g1,res1);
vst1_s16(g2,res2);
res1=vmovn_s32(rb1);
res2=vmovn_s32(rb2);
vst1_s16(b1,res1);
vst1_s16(b2,res2);
vst1_s16(r1,vmovn_s32(rr1));
vst1_s16(r2,vmovn_s32(rr2));
vst1_s16(g1,vmovn_s32(rg1));
vst1_s16(g2,vmovn_s32(rg2));
vst1_s16(b1,vmovn_s32(rb1));
vst1_s16(b2,vmovn_s32(rb2));
}
#endif
......@@ -192,8 +188,8 @@ static void line_yuv2rgb_2(const uint8_t *src_lines[], int src_strides[], int16
/*horizontal scaling of a single line (with 3 color planes)*/
static inline void line_horizontal_scale(AndroidScalerCtx * ctx, int16_t *src_lines[], int16_t *dst_lines[]){
int dst_w=ctx->dst_size.width;
#ifndef ARM
int dst_w=ctx->dst_size.width;
int x=0;
int i,pos;
int inc=ctx->w_inc;
......@@ -206,7 +202,8 @@ static inline void line_horizontal_scale(AndroidScalerCtx * ctx, int16_t *src_li
dst_lines[2][i]=src_lines[2][pos];
}
#else
ms_line_scale_8(ctx->hgrid,src_lines,dst_lines,ctx->dst_w_padded);
//ms_line_scale_simple_8(ctx->hgrid,src_lines,dst_lines,ctx->dst_w_padded);
ms_line_scale_8(ctx->hgrid,src_lines,dst_lines,ctx->dst_w_padded,ctx->hcoeffs);
#endif
}
......@@ -259,10 +256,6 @@ void ms_line_rgb2rgb565(const int16_t *r, const int16_t *g, const int16_t *b, ui
}
}
#else
static inline void ms_line_rgb2rgb565(const int16_t *r, const int16_t *g, const int16_t *b, uint16_t *dst, int width){
ms_line_rgb2rgb565_8(r,g,b,dst,ROUND_UP(width,8));
}
#endif
static void img_yuv2rgb565_scale(AndroidScalerCtx *ctx, uint8_t *src[], int src_strides[], uint8_t *dst[], int dst_strides[]){
......@@ -280,7 +273,11 @@ static void img_yuv2rgb565_scale(AndroidScalerCtx *ctx, uint8_t *src[], int src_
p_src[0]=ctx->hscaled_img[0]+offset;
p_src[1]=ctx->hscaled_img[1]+offset;
p_src[2]=ctx->hscaled_img[2]+offset;
#ifndef ARM
ms_line_rgb2rgb565(p_src[0],p_src[1],p_src[2],(uint16_t*)p_dst,ctx->dst_size.width);
#else
ms_line_rgb2rgb565_8(p_src[0],p_src[1],p_src[2],(uint16_t*)p_dst,ctx->dst_w_padded);
#endif
y+=ctx->h_inc;
p_dst+=dst_strides[0];
}
......@@ -316,11 +313,13 @@ static MSScalerContext *android_create_scaler_context(int src_w, int src_h, MSPi
/*compute the grid (map) for original lines into destination lines*/
ctx->dst_w_padded=ROUND_UP(dst_w,PAD);
ctx->hgrid=ms_new0(uint32_t,ctx->dst_w_padded);
ctx->hcoeffs=ms_new0(int16_t,ctx->dst_w_padded);
tmp=0;
prev=0;
for(i=0;i<dst_w;++i){
int offset=(tmp>>16)*2;
ctx->hgrid[i]=offset-prev;
ctx->hcoeffs[i]=(tmp&0xffff)>>9;
prev=offset;
tmp+=ctx->w_inc;
}
......@@ -349,3 +348,4 @@ MSScalerDesc ms_android_scaler={
android_scaler_process,
android_scaler_context_free
};
/*
mediastreamer2 library - modular sound and video processing and streaming
Copyright (C) 2006-2010 Belledonne Communications SARL (simon.morlat@linphone.org)
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifdef __ELF__
# define ELF
......@@ -71,15 +90,77 @@ function ms_line_rgb2rgb565_8
vshr.u16 q1, q1, #2
vld1.16 {d4,d5}, [r2,:64]!
vshr.u16 q2, q2, #3
vsli.16 q2, q1, #5 /*inserts g into d2*/
vsli.16 q2, q1, #5 /*inserts g into d2*/
vsli.16 q2, q0, #11 /*inserts r into d2 */
vst1.16 {q2}, [r3,:64]!
vst1.16 {q2}, [r3,:64]!
subs r4, r4, #8
bne 1b
pop {r4}
bx lr
.endfunc
.macro load_pixels_4_2 d_reg1, d_reg2, src
add r12, \src, #2 /* offset to reach next pixels */
vld1.16 \d_reg1[0], [\src], r4 /* transfer the pixel pointed by r4 into q2 */
vld1.16 \d_reg1[1], [\src], r5
vld1.16 \d_reg1[2], [\src], r6
vld1.16 \d_reg1[3], [\src], r7
vld1.16 \d_reg2[0], [r12], r4 /* transfer the pixel pointed by r4 into q2 */
vld1.16 \d_reg2[1], [r12], r5
vld1.16 \d_reg2[2], [r12], r6
vld1.16 \d_reg2[3], [r12], r7
.endm
.macro filter_pixels_8 q_srcdst, q_src2
vsub.s16 q9 , \q_src2, \q_srcdst /* q9=x(n+1)-x(n) */
vshl.s16 \q_srcdst , \q_srcdst , #7 /* (x(n)<<7) */
vmla.s16 \q_srcdst , q9, q8 /* q_srcdst += coef * q9 */
vshr.s16 \q_srcdst , \q_srcdst , #7
vabs.s16 \q_srcdst , \q_srcdst
.endm
/*void ms_line_scale_8(const uint32_t *grid, const int16_t **src, int16_t **dst int dst_width, int16_t *filter);*/
function ms_line_scale_8
push {r4-r12,lr} /* we use lr as a normal register here */
ldr lr , [sp ,#40] /*r4-r12+lr= 10 registers 40=10*4 offset to retrieve filter table*/
ldm r1, {r8,r9}
ldr r1, [r1,#8]
ldm r2, {r10,r11}
ldr r2, [r2,#8]
1:
ldm r0!, {r4,r5,r6,r7} /* load 4 entries of the grid into r4,r5,r6,r7 */
load_pixels_4_2 d4, d10, r1
load_pixels_4_2 d6, d12, r8
load_pixels_4_2 d8, d14, r9
ldm r0!, {r4,r5,r6,r7} /* load 4 more entries of the grid into r4,r5,r6,r7 */
load_pixels_4_2 d5, d11, r1
load_pixels_4_2 d7, d13, r8
load_pixels_4_2 d9, d15, r9
/* x(n)= q2,q3,q4 x(n+1)=q5,q6,q7 */
vld1.16 {q8} , [lr]! /* load the filtering coefficients in q8*/
/* we need to compute (coef*(x(n+1)-x(n)) + (x(n)<<7))>>7 */
filter_pixels_8 q2 , q5
filter_pixels_8 q3 , q6
filter_pixels_8 q4 , q7
vst1.16 {q2} , [r2]! /*write q2 (the 8 selected pixels) into memory pointed by r2*/
vst1.16 {q3} , [r10]!
vst1.16 {q4} , [r11]!
subs r3,r3,#8 /*we have processed 8 pixels, decrement width*/
bne 1b
pop {r4-r12,pc}
.endfunc
.macro load_pixels_4 d_reg, src
vld1.16 \d_reg[0], [\src], r4 /* transfer the pixel pointed by r4 into q2 */
vld1.16 \d_reg[1], [\src], r5
......@@ -88,7 +169,7 @@ function ms_line_rgb2rgb565_8
.endm
/*void ms_line_scale_8(const uint32_t *grid, const uint16_t **src, uint16_t **dst int dst_width);*/
function ms_line_scale_8
function ms_line_scale_simple_8
push {r4-r11}
ldr r8, [r1,#4]
ldr r9, [r1,#8]
......@@ -121,7 +202,6 @@ function ms_line_scale_8
.endfunc
.if 0
/* void line_yuv2rgb(uint8_t *y, uint8_t *u, uint8_t *v, int16_t *r, int16_t *g, int16_t *b, int n) */
......@@ -160,4 +240,28 @@ function line_yuv2rgb
bx lr
.endfunc
/*float interpolate_product_single(const float* a, const float *b, unsigned int len, const spx_uint32_t oversample, float *frac)*/
function interpolate_product_single
push {r4-r7}
vld1.f32 r4, [sp#16] /*load frac*/
veor q0, q0 /*set q0 to zero */
add r5 , r0, #4 /*r5=r0+4*/
add r6 , r1, #4 /*r6=r1+4*/
shl r3 , r3, #2 /*r3=oversample*sizeof(float)*/
1:
vld1.f32 {d2[],d3[]}, [r0] !
vld1.f32 {d4[],d5[]}, [r5] !
vld1.f32 q3, [r1], r3
vld1.f32 q4, [r6], r3
vmla.f32 q0, q1 , q3
vmla.f32 q0, q2, q4
subs r2, r2, #2
bne 1f
vmul.f32 q0, q4, q0
vpadd.f32 q0, q0, q0
vpadd.f32 q0, q0, q0
/* vmov.32 r0, d0[0] */
pop {r4-r7}
bx lr
.endif
......@@ -867,6 +867,10 @@ static int enc_set_br(MSFilter *f, void *arg){
s->fps=5;
s->qmin=5;
}
#ifdef ANDROID
/* we have to limit the fps on android due to limited CPU */
if (s->fps>7) s->fps=7;
#endif
if (s->av_context.codec!=NULL){
/*apply new settings dynamically*/
ms_filter_lock(f);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment