1 #include "../libzmpeg3.h"
6 zerr( "frame accurate seeking without a table of contents \n"
7 "is no longer supported. Use mpeg3toc <mpeg file> <table of contents>\n"
8 "to generate a table of contents and load the table of contents instead.\n");
15 int coded_size = coded_picture_width * coded_picture_height;
16 int chrom_size = chrom_width * chrom_height;
17 track->frame_cache->put_frame(framenum-1,
18 output_src[0], output_src[1], output_src[2],
19 coded_size, chrom_size, chrom_size);
24 drop_frames(long frames, int cache_it)
27 long frame_number = framenum + frames;
28 //zmsgs("drop frames framenum %d frames %ld\n", framenum, frames);
30 /* Read the selected number of frames and skip b-frames */
31 while(!result && frame_number > framenum ) {
33 result = read_frame_backend(0);
34 if( !result && ref_frames > 1 )
38 //zmsgs("framenum %d frame_offset %jx last_packet_start %jx repeat %d/%d",
39 // framenum,track->frame_offsets[framenum+1],vstream->demuxer->last_packet_start,
40 // repeat_fields, current_field);
41 result = read_frame_backend(frame_number - framenum);
42 //zmsgs(" type %c\n","XIPBD"[pict_type]);
55 int64_t stream_end = demuxer->stream_end;
56 if( demuxer->src->is_transport_stream() )
57 demuxer->stream_end = demuxer->program_byte + MAX_TS_PROBE;
58 else if( demuxer->src->is_program_stream() )
59 demuxer->stream_end = demuxer->program_byte + MAX_PGM_PROBE;
60 int zcode = -1, result = -1;
63 int bits = (uint8_t)zcode!=0 ? 24 : 8;
64 zcode = (zcode<<bits) | get_bits_noptr(bits);
65 if( (zcode&0xffffff) == PACKET_START_CODE_PREFIX ) {
66 zcode = (zcode<<8) + get_byte_noptr();
67 reset(result = zcode);
68 //zmsgs("5 %04x\n",zcode);
73 demuxer->stream_end = stream_end;
77 /* Line up on the beginning of the next code. */
79 next_code(uint32_t zcode)
81 while(!eof() && show_bits_noptr(32) != zcode ) {
87 /* Line up on the beginning of the previous code. */
89 prev_code(uint32_t zcode)
91 uint32_t current_code = 0;
92 #define PREV_CODE_MACRO { current_code >>= 8; \
93 current_code |= ((uint32_t)read_prev_char()) << 24; }
100 while( !bof() && current_code != zcode ) {
107 seek_byte(int64_t byte)
114 seek_frame(long frame)
121 rewind_video(int preload)
125 if( track->frame_offsets )
126 vstream->seek_byte(track->frame_offsets[0]);
128 vstream->seek_byte(0);
130 repeat_data = ref_frames = 0;
131 last_number = framenum = -1;
132 return preload ? read_frame_backend(0) : 0;
142 demuxer_t *demux = vstream->demuxer;
144 /* Must do seeking here so files which don't use video don't seek. */
145 /* Seeking is done in the demuxer */
146 /* Seek to absolute byte */
147 if( byte_seek >= 0 ) {
150 if( byte != demux->tell_byte() ) {
151 demux->seek_byte(byte);
155 demux->start_reverse();
156 //zmsgs("1 %jd\n", demux->tell_byte());
157 for( int i=0; i<2; ++i ) { /* Rewind 2 I-frames */
159 demux->prev_code(GOP_START_CODE) :
160 demux->prev_code(SEQUENCE_START_CODE) ) break;
162 //zmsgs("2 %jd\n", demux->tell_byte());
163 demux->start_forward();
164 if( track->frame_offsets ) {
165 int64_t offset = demux->tell_byte();
166 for( int k=0; k<track->total_keyframe_numbers; ++k ) {
167 frame_number = track->keyframe_numbers[k];
168 if( track->frame_offsets[frame_number] >= offset ) {
169 /* first entry is special */
170 framenum = frame_number>0 ? frame_number-1 : 0;
176 /* framenum no longer accurate, clear subtitles */
180 else { /* Read first frame */
184 repeat_data = ref_frames = 0;
185 //zmsgs("4 %jd\n", demux->tell_byte());
186 while( !result && !demux->eof() && demux->tell_byte() < byte ) {
187 result = read_frame_backend(0);
191 else if( frame_seek >= 0 ) {
192 /* Seek to a frame number */
193 frame_number = frame_seek;
195 if( frame_number != framenum ) {
196 if( debug ) zmsgs("%d\n", __LINE__);
197 if( frame_number < 0 ) frame_number = 0;
198 if( frame_number > maxframe ) frame_number = maxframe;
199 if(debug) zmsgs("%d %ld %d\n", __LINE__, frame_number, framenum);
200 /* Seek to I frame in table of contents. */
201 /* Determine time between seek position and previous subtitle. */
202 /* Subtract time difference from subtitle display time. */
203 if( frame_number > 0 && track->frame_offsets ) {
204 if( debug ) zmsgs("%d\n", __LINE__);
205 track->frame_cache->reset();
206 if( debug ) zmsgs("%d\n", __LINE__);
207 if( frame_number < framenum ||
208 frame_number-framenum > SEEK_THRESHOLD ) {
209 int idx = track->find_keyframe_index(frame_number);
210 /* back up 2 I frames, data may reference old refframes */
211 if( --idx < 0 ) idx = 0;
212 idx = track->keyframe_numbers[idx];
213 byte = track->frame_offsets[idx];
214 /* maybe lots of frames in one block, move is to earliest frame */
215 while( idx > 0 && track->frame_offsets[idx-1] == byte ) --idx;
216 if( debug ) zmsgs("%ld idx=%d, byte=%jd\n", frame_number,idx,byte);
218 vstream->seek_byte(byte);
220 repeat_data = ref_frames = 0;
221 /* get the first I-frame. It does not count in the frame sequence */
222 /* phys order is IBBPBBPBB... presentation order is BBIBBPBB... */
223 result = read_frame_backend(0);
225 if( debug ) zmsgs("%d %ld %d\n", __LINE__,frame_number,framenum);
226 if( !result && frame_number > framenum ) {
227 /* Read up to current frame */
228 int n = frame_number - framenum;
229 result = drop_frames(n, n < MAX_CACHE_FRAMES ? 1 : 0);
230 if( debug ) zmsgs("%d\n", __LINE__);
233 else if( frame_number == 0 ) {
234 result = rewind_video();
237 /* No support for seeking without table of contents */
243 else if( framenum < 0 ) { /* preload */
244 result = rewind_video(1);
257 int64_t target_byte = 0;
258 demuxer_t *demux = vstream->demuxer;
259 if( demux->tell_byte() <= 0 ) return 1;
260 /* Get location of end of previous picture */
261 demux->start_reverse();
262 result = demux->prev_code(PICTURE_START_CODE);
263 if( !result ) result = demux->prev_code(PICTURE_START_CODE);
264 if( !result ) result = demux->prev_code(PICTURE_START_CODE);
265 if( !result ) target_byte = demux->tell_byte();
266 if( !result ) { /* Rewind 2 I-frames */
268 result = demux->prev_code(GOP_START_CODE);
270 result = demux->prev_code(SEQUENCE_START_CODE);
276 result = demux->prev_code(GOP_START_CODE);
278 result = demux->prev_code(SEQUENCE_START_CODE);
281 demux->start_forward();
284 result = 0; /* Read up to correct byte */
285 repeat_data = ref_frames = 0;
286 while( !result && !demux->eof() && demux->tell_byte() < target_byte ) {
287 result = read_frame_backend(0);