static void fill_cache( cache_hnd_t *h, int frame ) { /* shift frames out of the cache as the frame request is beyond the filled cache */ int shift = frame - LAST_FRAME; /* no frames to shift or no frames left to read */ if( shift <= 0 || h->eof ) return; /* the next frames to read are either * A) starting at the end of the current cache, or * B) starting at a new frame that has the end of the cache at the desired frame * and proceeding to fill the entire cache */ int cur_frame = X264_MAX( h->first_frame + h->cur_size, frame - h->max_size + 1 ); /* the new starting point is either * A) the current one shifted the number of frames entering/leaving the cache, or * B) at a new frame that has the end of the cache at the desired frame. */ h->first_frame = X264_MIN( h->first_frame + shift, cur_frame ); h->cur_size = X264_MAX( h->cur_size - shift, 0 ); while( h->cur_size < h->max_size ) { cli_pic_t temp; /* the old front frame is going to shift off, overwrite it with the new frame */ cli_pic_t *cache = h->cache[0]; if( h->prev_filter.get_frame( h->prev_hnd, &temp, cur_frame ) || x264_cli_pic_copy( cache, &temp ) || h->prev_filter.release_frame( h->prev_hnd, &temp, cur_frame ) ) { h->eof = cur_frame; return; } /* the read was successful, shift the frame off the front to the end */ x264_frame_push( (void*)h->cache, x264_frame_shift( (void*)h->cache ) ); cur_frame++; h->cur_size++; } }
static int get_frame( hnd_t handle, cli_pic_t *output, int frame ) { fix_vfr_pts_hnd_t *h = handle; /* if we want the holder picture and it errored, return the error. */ if( frame == h->holder_frame ) { if( h->holder_ret ) return h->holder_ret; } else { /* if we have a holder frame and we don't want it, release the frame */ if( h->holder_frame > 0 && h->holder_frame < frame && h->prev_filter.release_frame( h->prev_hnd, &h->holder, h->holder_frame ) ) return -1; h->holder_frame = -1; if( h->prev_filter.get_frame( h->prev_hnd, &h->holder, frame ) ) return -1; } /* if the frame's duration is not set already, read the next frame to set it. */ if( !h->holder.duration ) { /* allocate a buffer picture if we didn't already */ if( !h->buffer_allocated ) { if( x264_cli_pic_alloc( &h->buffer, h->holder.img.csp, h->holder.img.width, h->holder.img.height ) ) return -1; h->buffer_allocated = 1; } h->holder_frame = frame+1; /* copy the current frame to the buffer, release it, and then read in the next frame to the placeholder */ if( x264_cli_pic_copy( &h->buffer, &h->holder ) || h->prev_filter.release_frame( h->prev_hnd, &h->holder, frame ) ) return -1; h->holder_ret = h->prev_filter.get_frame( h->prev_hnd, &h->holder, h->holder_frame ); /* suppress non-monotonic pts warnings by setting the duration to be at least 1 */ if( !h->holder_ret ) h->last_duration = X264_MAX( h->holder.pts - h->buffer.pts, 1 ); h->buffer.duration = h->last_duration; *output = h->buffer; } else *output = h->holder; output->pts = h->pts; h->pts += output->duration; return 0; }