.arch armv7-a .text .global csc_ARGB8888_to_YUV420SP_NEON .type csc_ARGB8888_to_YUV420SP_NEON, %function csc_ARGB8888_to_YUV420SP_NEON: .fnstart @r0 pDstY @r1 pDstUV @r2 pSrcRGB @r3 nWidth @r4 pDstY2 = pDstY + nWidth @r5 pSrcRGB2 = pSrcRGB + nWidthx2 @r6 temp7, nWidth16m @r7 temp6, accumilator @r8 temp5, nWidthTemp @r9 temp4, Raw RGB565 @r10 temp3, r,g,b @r11 temp2, immediate operand @r12 temp1, nHeight @r14 temp0, debugging pointer .equ CACHE_LINE_SIZE, 32 .equ PRE_LOAD_OFFSET, 6 stmfd sp!, {r4-r12,r14} @ backup registers ldr r12, [sp, #40] @ load nHeight @ldr r14, [sp, #44] @ load pTest add r4, r0, r3 @r4: pDstY2 = pDstY + nWidth add r5, r2, r3, lsl #2 @r5: pSrcRGB2 = tmpSrcRGB + nWidthx4 sub r8, r3, #16 @r8: nWidthTmp = nWidth -16 @q0: temp1, R @q1: temp2, GB @q2: R @q3: G @q4: B @q5: temp3, output vmov.u16 q6, #66 @coefficient assignment vmov.u16 q7, #129 vmov.u16 q8, #25 vmov.u16 q9, #0x8080 @ 128<<8 + 128 vmov.u16 q10, #0x1000 @ 16<<8 + 128 vorr.u16 q10, #0x0080 vmov.u16 q11, #38 @#-38 vmov.u16 q12, #74 @#-74 vmov.u16 q13, #112 vmov.u16 q14, #94 @#-94 vmov.u16 q15, #18 @#-18 LOOP_NHEIGHT2: stmfd sp!, {r12} @ backup registers LOOP_NWIDTH16: pld [r2, #(CACHE_LINE_SIZE*PRE_LOAD_OFFSET)] @-------------------------------------------YUV ------------------------------------------ vmov.u16 q14, #94 @#94 vmov.u16 q15, #18 @#18 vld4.8 {d0,d1,d2,d3}, [r2]! @loadRGB interleavely vld4.8 {d4,d5,d6,d7}, [r2]! @loadRGB interleavely vmov.u16 d8,d2 vmov.u16 d9,d6 vmov.u16 d10,d1 vmov.u16 d11,d5 vmov.u16 d12,d0 vmov.u16 d13,d4 vand.u16 q4,#0x00FF @R vand.u16 q5,#0x00FF @G vand.u16 q6,#0x00FF @B vmov.u16 q8,q9 @ CalcU() vmla.u16 q8,q6,q13 @112 * B[k] vmls.u16 q8,q4,q11 @q0:U -(38 * R[k]) @128<<6+ 32 + u>>2 vmls.u16 q8,q5,q12 @-(74 * G[k]) vshr.u16 q8,q8, #8 @(128<<8+ 128 + u)>>8 vmov.u16 q7,q9 @CalcV() vmla.u16 q7,q4,q13 @112 * R[k] vmls.u16 q7,q5,q14 @q0:U -(94 * G[k]) @128<<6+ 32 + v>>2 vmls.u16 q7,q6,q15 @-(18 * B[k]) vshr.u16 q7,q7, #8 @(128<<8+ 128 + v)>>8 vtrn.8 q8,q7 vst1.8 {q8}, [r1]! @write UV component to yuv420_buffer+linear_ylanesiez @-------------------------------------------Y ------------------------------------------ vmov.u16 q14, #66 @#66 vmov.u16 q15, #129 @#129 vmov.u16 q8, #25 @#25 @CalcY_Y() vmul.u16 q7,q4,q14 @q0 = 66 *R[k] vmla.u16 q7,q5,q15 @q0 += 129 *G[k] vmla.u16 q7,q6,q8 @q0 += 25 *B[k] vadd.u16 q7,q7,q10 vshr.u16 q7,q7, #8 vmov.u16 d8,d2 vmov.u16 d9,d6 vmov.u16 d10,d1 vmov.u16 d11,d5 vmov.u16 d12,d0 vmov.u16 d13,d4 vshr.u16 q4,q4,#8 @R vshr.u16 q5,q5,#8 @G vshr.u16 q6,q6,#8 @B vmul.u16 q0,q4,q14 @q0 = 66 *R[k] vmla.u16 q0,q5,q15 @q0 += 129 *G[k] vmla.u16 q0,q6,q8 @q0 += 25 *B[k] vadd.u16 q0,q0,q10 vshr.u16 q0,q0, #8 vtrn.8 q7,q0 vst1.8 {q7}, [r0]!@write to Y to yuv420_buffer @-------------------------------------------Y ------------------------------------------ @---------------------------------------------Y1------------------------------------------- pld [r5, #(CACHE_LINE_SIZE*PRE_LOAD_OFFSET)] vld4.8 {d0,d1,d2,d3}, [r5]! @loadRGB interleavely vld4.8 {d4,d5,d6,d7}, [r5]! @loadRGB interleavely vmov.u16 d8,d2 vmov.u16 d9,d6 vmov.u16 d10,d1 vmov.u16 d11,d5 vmov.u16 d12,d0 vmov.u16 d13,d4 vand.u16 q4,#0x00FF @R vand.u16 q5,#0x00FF @G vand.u16 q6,#0x00FF @B vmul.u16 q7,q4,q14 @q0 = 66 *R[k] vmla.u16 q7,q5,q15 @q0 += 129 *G[k] vmla.u16 q7,q6,q8 @q0 += 25 *B[k] vadd.u16 q7,q7,q10 vshr.u16 q7,q7, #8 vmov.u16 d8,d2 vmov.u16 d9,d6 vmov.u16 d10,d1 vmov.u16 d11,d5 vmov.u16 d12,d0 vmov.u16 d13,d4 vshr.u16 q4,q4,#8 @R vshr.u16 q5,q5,#8 @G vshr.u16 q6,q6,#8 @B vmul.u16 q0,q4,q14 @q0 = 66 *R[k] vmla.u16 q0,q5,q15 @q0 += 129 *G[k] vmla.u16 q0,q6,q8 @q0 += 25 *B[k] vadd.u16 q0,q0,q10 vshr.u16 q0,q0, #8 vtrn.8 q7,q0 vst1.8 {q7}, [r4]!@write to Y to yuv420_buffer subs r8,r8,#16 @nWidth16-- BPL LOOP_NWIDTH16 @if nWidth16>0 @-----------------------------------unaligned --------------------------------------- adds r8,r8,#16 @ + 16 - 2 BEQ NO_UNALIGNED @in case that nWidht is multiple of 16 LOOP_NWIDTH2: @----------------------------------pDstRGB1--Y------------------------------------------ @stmfd sp!, {r14} @backup r14 ldr r9, [r2], #4 @loadRGB int ldr r12, [r2], #4 @loadRGB int mov r10, r9,lsr #16 @copy to r10 mov r14, r12 @copy to r10 ldr r6, =0x000000FF and r10, r10, r6 @R: (rgbIn[k] & 0xF800) >> 10; ldr r6, =0x00FF0000 and r14, r14, r6 @R: (rgbIn[k] & 0xF800) >> 10; add r10,r10,r14 mov r11, #66 @accumilator += R*66 mul r7, r10, r11 mov r10, r9,lsr #8 @copy to r10 mov r14, r12,lsl #8 @copy to r10 ldr r6, =0x000000FF and r10, r10, r6 @G: ldr r6, =0x00FF0000 and r14, r14, r6 @G: add r10,r10,r14 mov r11, #129 @accumilator += G *129 mla r7, r10, r11, r7 mov r10, r9 @copy to r10 mov r14, r12,lsl #16 @copy to r10 ldr r6, =0x000000FF and r10, r10, r6 @B ldr r6, =0x00FF0000 and r14, r14, r6 @B add r10,r10,r14 mov r11, #25 @accumilator 1 -= B *25 mla r7, r10, r11, r7 ldr r6, =0x10801080 add r7, r6 lsr r7, #8 strb r7, [r0],#1 lsr r7,#16 strb r7, [r0],#1 @ldmfd sp!, {r14} @load r14 @----------------------------------pDstRGB2--UV------------------------------------------ mov r10, r9 @copy to r10 ldr r7,=0x00008080 mov r12,r7 ldr r6, =0x000000FF and r10, r10, r6 @B: mov r11, #112 @accumilator += B*112 mla r7, r10, r11, r7 mov r11, #18 @accumilator -= B*18 mul r11, r10, r11 sub r12, r12, r11 mov r10, r9, lsr #16 @copy to r10 ldr r6, =0x000000FF and r10, r10, r6 @R: (rgbIn[k] & 0xF800) >> 10; mov r11, #38 @accumilator -= R *38 mul r11, r10, r11 sub r7, r7, r11 mov r11, #112 @accumilator = R *112 mla r12, r10, r11, r12 mov r10, r9,lsr #8 @copy to r10 ldr r6, =0x000000FF and r10, r10, r6 @G: (rgbIn[k] & 0x07E0) >> 5; mov r11, #74 @accumilator -= G*74 mul r11, r10, r11 sub r7, r7, r11 mov r11, #94 @accumilator -= G*94 mul r11, r10, r11 sub r12, r12, r11 lsr r7, #8 @ >>8 strb r7, [r1],#1 lsr r12, #8 @ >>8 strb r12, [r1],#1 @----------------------------------pDstRGB2--Y------------------------------------------ @stmfd sp!, {r14} @backup r14 ldr r9, [r5], #4 @loadRGB int ldr r12, [r5], #4 @loadRGB int mov r10, r9,lsr #16 @copy to r10 mov r14, r12 @copy to r10 ldr r6, =0x000000FF and r10, r10, r6 @R: (rgbIn[k] & 0xF800) >> 10; ldr r6, =0x00FF0000 and r14, r14, r6 @R: (rgbIn[k] & 0xF800) >> 10; add r10,r10,r14 mov r11, #66 @accumilator += R*66 mul r7, r10, r11 mov r10, r9,lsr #8 @copy to r10 mov r14, r12,lsl #8 @copy to r10 ldr r6, =0x000000FF and r10, r10, r6 @G: ldr r6, =0x00FF0000 and r14, r14, r6 @G: add r10,r10,r14 mov r11, #129 @accumilator += G *129 mla r7, r10, r11, r7 mov r10, r9 @copy to r10 mov r14, r12,lsl #16 @copy to r10 ldr r6, =0x000000FF and r10, r10, r6 @B ldr r6, =0x00FF0000 and r14, r14, r6 @B add r10,r10,r14 mov r11, #25 @accumilator 1 -= B *25 mla r7, r10, r11, r7 ldr r6, =0x10801080 add r7, r6 lsr r7, #8 strb r7, [r4],#1 lsr r7,#16 strb r7, [r4],#1 @ldmfd sp!, {r14} @load r14 subs r8,r8,#2 @ nWidth2 -= 2 BGT LOOP_NWIDTH2 @ if nWidth2>0 NO_UNALIGNED: @in case that nWidht is multiple of 16 @----------------------------------------------------------------------------- sub r8, r3, #16 @r8: nWidthTmp = nWidth -16 add r0, r0, r3 @pDstY + nwidth add r2, r2, r3, lsl #2 @pSrcRGB + nwidthx4 add r4, r4, r3 @pDstY2 + nwidth add r5, r5, r3, lsl #2 @pSrcRGB2 + nwidthx4 ldmfd sp!, {r12} subs r12,r12,#2 @nHeight -=2 BGT LOOP_NHEIGHT2 @if nHeight2>0 ldmfd sp!, {r4-r12,pc} @ backup registers .fnend