// Helper: set timer clock static u32 platform_timer_set_clock( unsigned id, u32 clock ) { unsigned i, mini = 0; for( i = 0; i < 3; i ++ ) if( ABSDIFF( clock, MAIN_CLOCK / tmr_prescale[ i ] ) < ABSDIFF( clock, MAIN_CLOCK / tmr_prescale[ mini ] ) ) mini = i; *tmr_ctrl[ id ] = ( *tmr_ctrl[ id ] & ~0xB ) | ( mini << 2 ); return MAIN_CLOCK / tmr_prescale[ mini ]; }
// Helper: set timer clock static u32 platform_timer_set_clock( unsigned id, u32 clock ) { unsigned i, mini = 0; for( i = 0; i < 5; i ++ ) if( ABSDIFF( clock, BOARD_MCK / clkdivs[ i ] ) < ABSDIFF( clock, BOARD_MCK / clkdivs[ mini ] ) ) mini = i; TC_Configure( ( AT91S_TC* )timer_base[ id ], mini | AT91C_TC_WAVE ); return BOARD_MCK / clkdivs[ mini ]; }
/**************************************************************************//** * * @brief Simple lookup of best MSEL and NSEL values for wanted frequency * * Not optimized. * * @param [in] wantedFreq The wanted PLL1 frequency * @param [out] pMsel The best MSEL value for the PLL1_CTRL register * @param [out] pNsel The best NSEL value for the PLL1_CTRL register * *****************************************************************************/ static void cgu_findMN(uint32_t wantedFreq, uint32_t* pMsel, uint32_t* pNsel) { uint32_t besterr = wantedFreq; uint32_t m, n, f, tmp, err; #define ABSDIFF(__a, __b) ( ((__a) < (__b)) ? ((__b) - (__a)) : ((__a) - (__b)) ) for (n = 1; n <=4; n++) { f = 12000000 / n; tmp = 0; for (m = 1; m <= 256; m++) { tmp += f; err = ABSDIFF(tmp, wantedFreq); if (err == 0) { // found perfect match *pMsel = m - 1; *pNsel = n - 1; return; } else if (err < besterr) { *pMsel = m - 1; *pNsel = n - 1; besterr = err; } if (tmp > wantedFreq) { // no point in continuing to increase tmp as value is too high already break; } } } }
int patternsMatch(struct pattern * remembered, struct pattern * observed) { unsigned int done=0 , rP =0 , oP = 0 , timingMismatch = 0; while (!done) { if (remembered->state[rP] == observed->state[oP]) { timingMismatch+=ABSDIFF(remembered->duration[rP],observed->duration[oP]); ++rP; ++oP; } else { fprintf(stderr,"Mismatch at character %u/%u ( %u ) vs %u/%u ( %u )\n", rP,remembered->currentStates,remembered->state[rP] , oP,observed->currentStates,observed->state[oP]); return 0; } //--------------------------------------------------------- if ( (oP==observed->currentStates) || (rP==remembered->currentStates) ) { if (remembered->currentStates>observed->currentStates) { fprintf(stderr,"Mismatch size , our sequence is good up to a point but not complete\n"); return 0; } done=1; } } return 1; }
int closeToRGB(unsigned char R , unsigned char G , unsigned char B , unsigned char targetR , unsigned char targetG , unsigned char targetB , unsigned int threshold) { if ( ( ABSDIFF(R,targetR) < threshold ) && ( ABSDIFF(G,targetG) < threshold ) && ( ABSDIFF(B,targetB) < threshold ) ) { return 1; } return 0; }
void RP_ProcessRTP(RTPStream *ch, char *pck, u32 size) { GF_NetworkCommand com; GF_Err e; GF_RTPHeader hdr; u32 PayloadStart; ch->rtp_bytes += size; /*first decode RTP*/ e = gf_rtp_decode_rtp(ch->rtp_ch, pck, size, &hdr, &PayloadStart); /*corrupted or NULL data*/ if (e || (PayloadStart >= size)) { //gf_term_on_sl_packet(ch->owner->service, ch->channel, NULL, 0, NULL, GF_CORRUPTED_DATA); return; } /*if we must notify some timing, do it now. If the channel has no range, this should NEVER be called*/ if (ch->check_rtp_time /*&& gf_rtp_is_active(ch->rtp_ch)*/) { Double ch_time; /*it may happen that we still receive packets from a previous "play" request. If this is the case, filter until we reach the indicated rtptime*/ if (ch->rtp_ch->rtp_time && (ch->rtp_ch->rtp_first_SN > hdr.SequenceNumber) && (ch->rtp_ch->rtp_time < hdr.TimeStamp) ) { GF_LOG(GF_LOG_WARNING, GF_LOG_RTP, ("[RTP] Rejecting too early packet (TS %d vs signaled rtp time %d - diff %d ms)\n", hdr.TimeStamp, ch->rtp_ch->rtp_time, ((hdr.TimeStamp - ch->rtp_ch->rtp_time)*1000) / ch->rtp_ch->TimeScale)); return; } ch_time = gf_rtp_get_current_time(ch->rtp_ch); /*this is the first packet on the channel (no PAUSE)*/ if (ch->check_rtp_time == RTP_SET_TIME_RTP) { /*Note: in a SEEK with RTSP, the rtp-info time given by the server is the rtp time of the desired range. But the server may (and should) send from the previous I frame on video, so the time of the first rtp packet after a SEEK can actually be less than CurrentStart. We don't drop these packets in order to see the maximum video. We could drop it, this would mean wait for next RAP...*/ memset(&com, 0, sizeof(com)); com.command_type = GF_NET_CHAN_MAP_TIME; com.base.on_channel = ch->channel; if (ch->rtsp) { com.map_time.media_time = ch->current_start + ch_time; } else { com.map_time.media_time = 0; } com.map_time.timestamp = hdr.TimeStamp; com.map_time.reset_buffers = 0; gf_term_on_command(ch->owner->service, &com, GF_OK); GF_LOG(GF_LOG_INFO, GF_LOG_RTP, ("[RTP] Mapping RTP Time seq %d TS %d Media Time %g - rtp info seq %d TS %d\n", hdr.SequenceNumber, hdr.TimeStamp, com.map_time.media_time, ch->rtp_ch->rtp_first_SN, ch->rtp_ch->rtp_time )); /*skip RTCP clock init when RTSP is used*/ if (ch->rtsp) ch->rtcp_init = 1; // if (ch->depacketizer->payt==GF_RTP_PAYT_H264_AVC) ch->depacketizer->flags |= GF_RTP_AVC_WAIT_RAP; } /*this is RESUME on channel, filter packet based on time (darwin seems to send couple of packet before) do not fetch if we're below 10 ms or <0, because this means we already have this packet - as the PAUSE is issued with the RTP currentTime*/ else if (ch_time <= 0.021) { return; } ch->check_rtp_time = RTP_SET_TIME_NONE; } gf_rtp_depacketizer_process(ch->depacketizer, &hdr, pck + PayloadStart, size - PayloadStart); /*last check: signal EOS if we're close to end range in case the server do not send RTCP BYE*/ if ((ch->flags & RTP_HAS_RANGE) && !(ch->flags & RTP_EOS) ) { /*also check last CTS*/ Double ts = (Double) ((u32) ch->depacketizer->sl_hdr.compositionTimeStamp - hdr.TimeStamp); ts /= gf_rtp_get_clockrate(ch->rtp_ch); if (ABSDIFF(ch->range_end, (ts + ch->current_start + gf_rtp_get_current_time(ch->rtp_ch)) ) < 0.2) { ch->flags |= RTP_EOS; ch->stat_stop_time = gf_sys_clock(); gf_term_on_sl_packet(ch->owner->service, ch->channel, NULL, 0, NULL, GF_EOS); } } }
inline unsigned short FindNeighborDepth( unsigned short * full_depth_map, unsigned char * rgb_image, unsigned int search_area_stop, unsigned char r,unsigned char g,unsigned char b, unsigned int dpth_ptr,unsigned int img_ptr, unsigned int x,unsigned int y,unsigned int depth ) { // Heuristic , finds neighborhood depth.. unsigned int SHIFT_3_BYTE = metrics[RESOLUTION_X_3_BYTE]; unsigned int SHIFT_1_BYTE = metrics[RESOLUTION_X]; unsigned int stop_search_up=0,stop_search_down=0; unsigned int dpth_ptr_up=dpth_ptr , dpth_ptr_down=dpth_ptr , y_up=y , y_down=y , img_ptr_up=img_ptr , img_ptr_down=img_ptr; unsigned int search_area=0; unsigned int THRESHOLD=20; while (search_area<search_area_stop) { if ( stop_search_up==0 ) { if (y_up<=1) stop_search_up=1; else { dpth_ptr_up-=SHIFT_1_BYTE; img_ptr_up-=SHIFT_3_BYTE; --y_up; if ( (ABSDIFF(r,rgb_image[img_ptr_up])>THRESHOLD) || (ABSDIFF(g,rgb_image[img_ptr_up+1])>THRESHOLD) || (ABSDIFF(b,rgb_image[img_ptr_up+2])>THRESHOLD) ) stop_search_up=1; else { if (full_depth_map[dpth_ptr_up]!=0) return full_depth_map[dpth_ptr_up]; } } } if ( stop_search_down==0 ) { if (y_down>=metrics[RESOLUTION_Y]) stop_search_down=1; else { dpth_ptr_down+=SHIFT_1_BYTE; img_ptr_down+=SHIFT_3_BYTE; ++y_down; if ( (ABSDIFF(r,rgb_image[img_ptr_down])>THRESHOLD) || (ABSDIFF(g,rgb_image[img_ptr_down+1])>THRESHOLD) || (ABSDIFF(b,rgb_image[img_ptr_down+2])>THRESHOLD) ) stop_search_down=1; else { if (full_depth_map[dpth_ptr_down]!=0) return full_depth_map[dpth_ptr_down]; } } } if ((stop_search_down!=0)&&(stop_search_up!=0)) return 0; ++search_area; } return 0; }
/**********************************************************************************\ Detect Pattern \**********************************************************************************/ void DetectHorizontalLine_Pattern_Ch8(unsigned char* Data, unsigned int width, unsigned int height, int* pattern, size_t patsize, int* linepos, double* match, size_t len) { double sumline1=0; unsigned int center_line = ROUNDUINT((double(height)/2))-1; double curMatch = 0; unsigned int i=0,i2=0,i3 = 0; unsigned int j = 0; unsigned char* pLine = Data; // Get all slopes double* pSumWidth = new double[height]; for (i2=0; i2<len; i2++) { linepos[i2] = 0; match[i2] = 0; } unsigned int patcount = 0; for (i2=0; i2<patsize; i2++) { if (pattern[i2] != -1) patcount++; } // Only run through needed lines for (j=0; j<height; j++) { pSumWidth[j]=0; for (i=0; i<width; i++) { pSumWidth[j] += *pLine++; } pSumWidth[j] /= width; // Norm between [0,255] } // Only run through needed lines for (j=0; j<(height-patsize); j++) { curMatch = 0; for (i=0; i<patsize; i++) { if (pattern[i] != -1) { sumline1 = pSumWidth[j+i]; curMatch += ABSDIFF(sumline1, pattern[i]); } } // Calc matching percentage curMatch /= patcount; curMatch /= 0xFF; curMatch = 100*(1-curMatch); for (i2=0; i2<len; i2++) { if (curMatch > match[i2]) { // shift one down for (i3=i2+1; i3<len; i3++) { match[i3] = match[i3-1]; linepos[i3] = linepos[i3-1]; } match[i2] = curMatch; // calc from center if image linepos[i2] = j-center_line; break; } } } delete [] pSumWidth; }