/* ------------------------------------------------------------------ * Copyright (C) 1998-2009 PacketVideo * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. * See the License for the specific language governing permissions * and limitations under the License. * ------------------------------------------------------------------- */ #ifndef _VLC_ENCODE_INLINE_H_ #define _VLC_ENCODE_INLINE_H_ #if !defined(PV_ARM_GCC_V5) && !defined(PV_ARM_GCC_V4) __inline Int zero_run_search(UInt *bitmapzz, Short *dataBlock, RunLevelBlock *RLB, Int nc) { Int idx, run, level, j; UInt end, match; idx = 0; j = 0; run = 0; match = 1 << 31; if (nc > 32) end = 1; else end = 1 << (32 - nc); while (match >= end) { if ((match&bitmapzz[0]) == 0) { run++; j++; match >>= 1; } else { match >>= 1; level = dataBlock[j]; dataBlock[j] = 0; /* reset output */ j++; if (level < 0) { RLB->level[idx] = -level; RLB->s[idx] = 1; RLB->run[idx] = run; run = 0; idx++; } else { RLB->level[idx] = level; RLB->s[idx] = 0; RLB->run[idx] = run; run = 0; idx++; } } } nc -= 32; if (nc > 0) { match = 1 << 31; end = 1 << (32 - nc); while (match >= end) { if ((match&bitmapzz[1]) == 0) { run++; j++; match >>= 1; } else { match >>= 1; level = dataBlock[j]; dataBlock[j] = 0; /* reset output */ j++; if (level < 0) { RLB->level[idx] = -level; RLB->s[idx] = 1; RLB->run[idx] = run; run = 0; idx++; } else { RLB->level[idx] = level; RLB->s[idx] = 0; RLB->run[idx] = run; run = 0; idx++; } } } } return idx; } #elif defined(__CC_ARM) /* only work with arm v5 */ __inline Int zero_run_search(UInt *bitmapzz, Short *dataBlock, RunLevelBlock *RLB, Int nc) { OSCL_UNUSED_ARG(nc); Int idx, run, level, j; UInt end, match; Int zzorder; idx = 0; run = 0; j = -1; __asm { ldr match, [bitmapzz] clz run, match } zzorder = 0; while (run < 32) { __asm { mov end, #0x80000000 mov end, end, lsr run /* mask*/ bic match, match, end /* remove it from bitmap */ mov run, run, lsl #1 /* 05/09/02 */ ldrsh level, [dataBlock, run] /* load data */ strh zzorder, [dataBlock, run] /* reset output */ add j, j, #1 rsb run, j, run, lsr #1 /* delta run */ add j, j, run /* current position */ } if (level < 0) { RLB->level[idx] = -level; RLB->s[idx] = 1; RLB->run[idx] = run; run = 0; idx++; } else { RLB->level[idx] = level; RLB->s[idx] = 0; RLB->run[idx] = run; run = 0; idx++; } __asm { clz run, match } } __asm { ldr match, [bitmapzz, #4] clz run, match } while (run < 32) { __asm { mov end, #0x80000000 mov end, end, lsr run /* mask*/ bic match, match, end /* remove it from bitmap */ add run, run, #32 /* current position */ mov run, run, lsl #1 /* 09/02/05 */ ldrsh level, [dataBlock, run] /* load data */ strh zzorder, [dataBlock, run] /* reset output */ add j, j, #1 rsb run, j, run, lsr #1 /* delta run */ add j, j, run /* current position */ } if (level < 0) { RLB->level[idx] = -level; RLB->s[idx] = 1; RLB->run[idx] = run; run = 0; idx++; } else { RLB->level[idx] = level; RLB->s[idx] = 0; RLB->run[idx] = run; run = 0; idx++; } __asm { clz run, match } } return idx; } #elif ( defined(PV_ARM_GCC_V4) || defined(PV_ARM_GCC_V5) ) /* ARM GNU COMPILER */ __inline Int m4v_enc_clz(UInt temp) { register Int rb; register UInt ra = (UInt)temp; asm volatile("clz %0, %1" : "=&r"(rb) : "r"(ra) ); return (rb); } __inline Int zero_run_search(UInt *bitmapzz, Short *dataBlock, RunLevelBlock *RLB, Int nc) { OSCL_UNUSED_ARG(nc); Int idx, run, level = 0, j; UInt end = 0, match; Int zzorder; idx = 0; run = 0; j = -1; match = *bitmapzz; run = m4v_enc_clz(match); zzorder = 0; while (run < 32) { asm volatile("mov %0, #0x80000000\n\t" "mov %0, %0, lsr %1\n\t" "bic %2, %2, %0\n\t" "mov %1, %1, lsl #1\n\t" "ldrsh %3, [%6, %1]\n\t" "strh %5, [%6, %1]\n\t" "add %4, %4, #1\n\t" "rsb %1, %4, %1, lsr #1\n\t" "add %4, %4, %1" : "+r"(end), "+r"(run), "+r"(match), "=r"(level), "+r"(j) : "r"(zzorder), "r"(dataBlock)); if (level < 0) { RLB->level[idx] = -level; RLB->s[idx] = 1; RLB->run[idx] = run; run = 0; idx++; } else { RLB->level[idx] = level; RLB->s[idx] = 0; RLB->run[idx] = run; run = 0; idx++; } run = m4v_enc_clz(match); } match = bitmapzz[1]; run = m4v_enc_clz(match); while (run < 32) { asm volatile("mov %0, #0x80000000\n\t" "mov %0, %0, lsr %1\n\t" "bic %2, %2, %0\n\t" "add %1, %1, #32\n\t" "mov %1, %1, lsl #1\n\t" "ldrsh %3, [%6, %1]\n\t" "strh %5, [%6, %1]\n\t" "add %4, %4, #1\n\t" "rsb %1, %4, %1, lsr #1\n\t" "add %4, %4, %1" : "+r"(end), "+r"(run), "+r"(match), "+r"(level), "+r"(j) : "r"(zzorder), "r"(dataBlock)); if (level < 0) { RLB->level[idx] = -level; RLB->s[idx] = 1; RLB->run[idx] = run; run = 0; idx++; } else { RLB->level[idx] = level; RLB->s[idx] = 0; RLB->run[idx] = run; run = 0; idx++; } run = m4v_enc_clz(match); } return idx; } #endif #endif // _VLC_ENCODE_INLINE_H_