X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.0%2Flibzmpeg3%2Fvideo%2Fseek.C;fp=cinelerra-5.0%2Flibzmpeg3%2Fvideo%2Fseek.C;h=0000000000000000000000000000000000000000;hb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;hp=a86932955761fb5ad03be37005ebdb5a7e6a836a;hpb=52fcc46226f9df46f9ce9d0566dc568455a7db0b;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.0/libzmpeg3/video/seek.C b/cinelerra-5.0/libzmpeg3/video/seek.C deleted file mode 100644 index a8693295..00000000 --- a/cinelerra-5.0/libzmpeg3/video/seek.C +++ /dev/null @@ -1,293 +0,0 @@ -#include "../libzmpeg3.h" - -static void -toc_error() -{ - zerr( "frame accurate seeking without a table of contents \n" - "is no longer supported. Use mpeg3toc \n" - "to generate a table of contents and load the table of contents instead.\n"); -} - -void zvideo_t:: -cache_frame() -{ - if( output_src[0] ) { - int coded_size = coded_picture_width * coded_picture_height; - int chrom_size = chrom_width * chrom_height; - track->frame_cache->put_frame(framenum-1, - output_src[0], output_src[1], output_src[2], - coded_size, chrom_size, chrom_size); - } -} - -int zvideo_t:: -drop_frames(long frames, int cache_it) -{ - int result = 0; - long frame_number = framenum + frames; -//zmsgs("drop frames framenum %d frames %ld\n", framenum, frames); - -/* Read the selected number of frames and skip b-frames */ - while(!result && frame_number > framenum ) { - if( cache_it ) { - result = read_frame_backend(0); - if( !result && ref_frames > 1 ) - cache_frame(); - } - else { -//zmsgs("framenum %d frame_offset "_LX" last_packet_start "_LX" repeat %d/%d", -// framenum,track->frame_offsets[framenum+1],vstream->demuxer->last_packet_start, -// repeat_fields, current_field); - result = read_frame_backend(frame_number - framenum); -//zmsgs(" type %c\n","XIPBD"[pict_type]); - } - } - - return result; -} - -int zbits_t:: -next_start_code() -{ -//zmsg("1\n"); - /* search forwards */ - prev_byte_align(); - int64_t stream_end = demuxer->stream_end; - if( demuxer->src->is_transport_stream() ) - demuxer->stream_end = demuxer->program_byte + MAX_TS_PROBE; - else if( demuxer->src->is_program_stream() ) - demuxer->stream_end = demuxer->program_byte + MAX_PGM_PROBE; - int zcode = -1, result = -1; - - while( !eof() ) { - int bits = (uint8_t)zcode!=0 ? 24 : 8; - zcode = (zcode<stream_end = stream_end; - return result; -} - -/* Line up on the beginning of the next code. */ -int zbits_t:: -next_code(uint32_t zcode) -{ - while(!eof() && show_bits_noptr(32) != zcode ) { - get_byte_noptr(); - } - return eof(); -} - -/* Line up on the beginning of the previous code. */ -int zdemuxer_t:: -prev_code(uint32_t zcode) -{ - uint32_t current_code = 0; -#define PREV_CODE_MACRO { current_code >>= 8; \ - current_code |= ((uint32_t)read_prev_char()) << 24; } - - PREV_CODE_MACRO - PREV_CODE_MACRO - PREV_CODE_MACRO - PREV_CODE_MACRO - - while( !bof() && current_code != zcode ) { - PREV_CODE_MACRO - } - return bof(); -} - -int zvideo_t:: -seek_byte(int64_t byte) -{ - byte_seek = byte; - return 0; -} - -int zvideo_t:: -seek_frame(long frame) -{ - frame_seek = frame; - return 0; -} - -int zvideo_t:: -rewind_video(int preload) -{ - vstream->reset(); - framenum = 0; - if( track->frame_offsets ) - vstream->seek_byte(track->frame_offsets[0]); - else - vstream->seek_byte(0); - track->reset_pts(); - repeat_data = ref_frames = 0; - last_number = framenum = -1; - return preload ? read_frame_backend(0) : 0; -} - -int zvideo_t:: -seek() -{ - int result = 0; - int64_t byte; - long frame_number; - int debug = 0; - demuxer_t *demux = vstream->demuxer; - -/* Must do seeking here so files which don't use video don't seek. */ -/* Seeking is done in the demuxer */ -/* Seek to absolute byte */ - if( byte_seek >= 0 ) { - byte = byte_seek; - byte_seek = -1; - if( byte != demux->tell_byte() ) { - demux->seek_byte(byte); - track->reset_pts(); - if( byte > 0 ) { - //zmsg("1\n"); - demux->start_reverse(); - //zmsgs("1 "_LD"\n", demux->tell_byte()); - for( int i=0; i<2; ++i ) { /* Rewind 2 I-frames */ - if( has_gops ? - demux->prev_code(GOP_START_CODE) : - demux->prev_code(SEQUENCE_START_CODE) ) break; - } - //zmsgs("2 "_LD"\n", demux->tell_byte()); - demux->start_forward(); - if( track->frame_offsets ) { - int64_t offset = demux->tell_byte(); - for( int k=0; ktotal_keyframe_numbers; ++k ) { - frame_number = track->keyframe_numbers[k]; - if( track->frame_offsets[frame_number] >= offset ) { - /* first entry is special */ - framenum = frame_number>0 ? frame_number-1 : 0; - break; - } - } - } - else { - /* framenum no longer accurate, clear subtitles */ - reset_subtitles(); - } - } - else { /* Read first frame */ - rewind_video(); - } - vstream->reset(); - repeat_data = ref_frames = 0; - //zmsgs("4 "_LD"\n", demux->tell_byte()); - while( !result && !demux->eof() && demux->tell_byte() < byte ) { - result = read_frame_backend(0); - } - } - } - else if( frame_seek >= 0 ) { - /* Seek to a frame number */ - frame_number = frame_seek; - frame_seek = -1; - if( frame_number != framenum ) { - if( debug ) zmsgs("%d\n", __LINE__); - if( frame_number < 0 ) frame_number = 0; - if( frame_number > maxframe ) frame_number = maxframe; - if(debug) zmsgs("%d %ld %d\n", __LINE__, frame_number, framenum); - /* Seek to I frame in table of contents. */ - /* Determine time between seek position and previous subtitle. */ - /* Subtract time difference from subtitle display time. */ - if( frame_number > 0 && track->frame_offsets ) { - if( debug ) zmsgs("%d\n", __LINE__); - track->frame_cache->reset(); - if( debug ) zmsgs("%d\n", __LINE__); - if( frame_number < framenum || - frame_number-framenum > SEEK_THRESHOLD ) { - int idx = track->find_keyframe_index(frame_number); - /* back up 2 I frames, data may reference old refframes */ - if( --idx < 0 ) idx = 0; - idx = track->keyframe_numbers[idx]; - byte = track->frame_offsets[idx]; - /* maybe lots of frames in one block, move is to earliest frame */ - while( idx > 0 && track->frame_offsets[idx-1] == byte ) --idx; - if( debug ) zmsgs("%ld idx=%d, byte="_LD"\n", frame_number,idx,byte); - framenum = idx-1; - vstream->seek_byte(byte); - track->reset_pts(); - repeat_data = ref_frames = 0; - /* get the first I-frame. It does not count in the frame sequence */ - /* phys order is IBBPBBPBB... presentation order is BBIBBPBB... */ - result = read_frame_backend(0); - } - if( debug ) zmsgs("%d %ld %d\n", __LINE__,frame_number,framenum); - if( !result && frame_number > framenum ) { - /* Read up to current frame */ - int n = frame_number - framenum; - result = drop_frames(n, n < MAX_CACHE_FRAMES ? 1 : 0); - if( debug ) zmsgs("%d\n", __LINE__); - } - } - else if( frame_number == 0 ) { - result = rewind_video(); - } - else { - /* No support for seeking without table of contents */ - toc_error(); - result = 1; - } - } - } - else if( framenum < 0 ) { /* preload */ - result = rewind_video(1); - } - else - return 0; - - seek_time = 0; - return result; -} - -int zvideo_t:: -previous_frame() -{ - int result = 0; - int64_t target_byte = 0; - demuxer_t *demux = vstream->demuxer; - if( demux->tell_byte() <= 0 ) return 1; - /* Get location of end of previous picture */ - demux->start_reverse(); - result = demux->prev_code(PICTURE_START_CODE); - if( !result ) result = demux->prev_code(PICTURE_START_CODE); - if( !result ) result = demux->prev_code(PICTURE_START_CODE); - if( !result ) target_byte = demux->tell_byte(); - if( !result ) { /* Rewind 2 I-frames */ - if( has_gops ) - result = demux->prev_code(GOP_START_CODE); - else - result = demux->prev_code(SEQUENCE_START_CODE); - } - - if( !result ) - { - if( has_gops ) - result = demux->prev_code(GOP_START_CODE); - else - result = demux->prev_code(SEQUENCE_START_CODE); - } - - demux->start_forward(); - vstream->reset(); - - result = 0; /* Read up to correct byte */ - repeat_data = ref_frames = 0; - while( !result && !demux->eof() && demux->tell_byte() < target_byte ) { - result = read_frame_backend(0); - } - repeat_data = 0; - - return 0; -} -