static uint32_t correct_current_frame_number ( lwlibav_video_decode_handler_t *vdhp, AVPacket *pkt, uint32_t i, /* frame_number */ uint32_t goal ) { #define MATCH_DTS( j ) (info[j].dts == pkt->dts) #define MATCH_POS( j ) ((vdhp->lw_seek_flags & SEEK_POS_CORRECTION) && info[j].file_offset == pkt->pos) order_converter_t *oc = vdhp->order_converter; video_frame_info_t *info = vdhp->frame_list; uint32_t p = oc ? oc[i].decoding_to_presentation : i; if( pkt->dts == AV_NOPTS_VALUE || MATCH_DTS( p ) || MATCH_POS( p ) ) return i; if( pkt->dts > info[p].dts ) { /* too forward */ uint32_t limit = MIN( goal, vdhp->frame_count ); if( oc ) while( !MATCH_DTS( oc[++i].decoding_to_presentation ) && !MATCH_POS( oc[ i].decoding_to_presentation ) && i <= limit ); else while( !MATCH_DTS( ++i ) && !MATCH_POS( i ) && i <= limit ); if( i > limit ) return 0; } else { /* too backward */ if( oc ) while( !MATCH_DTS( oc[--i].decoding_to_presentation ) && !MATCH_POS( oc[ i].decoding_to_presentation ) && i ); else while( !MATCH_DTS( --i ) && !MATCH_POS( i ) && i ); if( i == 0 ) return 0; } return i; #undef MATCH_DTS #undef MATCH_POS }
static Obj NFFUNCTION(Obj self, Obj rel, Obj dir, Obj word) { /* word is an integer lists. dir is true/false. rel is a list of lists: square of positive relator+square of negative relator; positions in 1st of letter i; position in 1st of letter -i * if dir=true, replace all (>=1/2)-cyclic occurrences of rel in word by the shorter half * if dir=false, replace all occurrences of the last generator in word by the corresponding bit of rel */ Obj posind = ELM_PLIST(rel,2), negind = ELM_PLIST(rel,3); rel = ELM_PLIST(rel,1); Int n = LEN_PLIST(posind), allocn = n, i = 0, resulti = 0, match = 0, matchlen = 0, j; Obj result = ALLOC_PLIST(allocn); while (i < LEN_PLIST(word)) { /* we produced result[1..resulti] as the compressed version of word[1..i]. additionally, matchlen is maximal such that rel[match..match+matchlen-1] = result[resulti-matchlen+1..resulti] */ i++; Obj wi = ELM_PLIST(word,i); Int vi = INT_INTOBJ(wi); if (dir == False) { if (vi == n) { match = INT_INTOBJ(ELM_PLIST(negind,n)); for (j = 1; j < n; j++) PUSH_LETTER(INT_INTOBJ(ELM_PLIST(rel,j+match))); } else if (vi == -n) { match = INT_INTOBJ(ELM_PLIST(posind,n)); for (j = 1; j < n; j++) PUSH_LETTER(INT_INTOBJ(ELM_PLIST(rel,j+match))); } else PUSH_LETTER(vi); } else { if (resulti && vi == -INT_INTOBJ(ELM_PLIST(result,resulti))) { /* pop letter, and update match */ resulti--; matchlen--; if (matchlen == 0 && resulti) { MATCH_POS(match,INT_INTOBJ(ELM_PLIST(result,resulti))); matchlen = 1; while (resulti > matchlen && ELM_PLIST(result,resulti-matchlen) == ELM_PLIST(rel,match+n-1)) { matchlen++; if (!--match) match = n; } } else match = 0; } else { PUSH_LETTER(vi); if (match && wi == ELM_PLIST(rel,match+matchlen)) { matchlen++; if (matchlen >= (n+1+(match < 2*n))/2) { /* more than half, or exactly half and negatives */ resulti -= matchlen; for (j = n-1; j >= matchlen; j--) PUSH_LETTER(-INT_INTOBJ(ELM_PLIST(rel,j+match))); matchlen = n-matchlen; match = 4*n+1 - (match+n-1); } } else { matchlen = 1; MATCH_POS(match,vi); } } } } SET_LEN_PLIST(result,resulti); return result; }