Fixed initialisation of tf in file_open(). Without setting the memory to 0,
[cinelerra_cv/mob.git] / libmpeg3 / video / seek.c
blob181e0a5387a897f23f7090a26655b593e5cae579
1 #include "../mpeg3private.h"
2 #include "../mpeg3protos.h"
3 #include "mpeg3video.h"
4 #include <stdlib.h>
5 #include <string.h>
7 void mpeg3video_toc_error()
9 fprintf(stderr,
10 "mpeg3video_seek: frame accurate seeking without a table of contents \n"
11 "is no longer supported. Use mpeg3toc <mpeg file> <table of contents>\n"
12 "to generate a table of contents and load the table of contents instead.\n");
15 int mpeg3video_drop_frames(mpeg3video_t *video, long frames, int cache_it)
17 int result = 0;
18 long frame_number = video->framenum + frames;
19 mpeg3_vtrack_t *track = video->track;
20 /* first 3 frames are garbage as proven by printfs in the read_frame calls */
21 int drop_count = 3;
23 /* Read the selected number of frames and skip b-frames */
24 while(!result && frame_number > video->framenum)
26 if(cache_it)
28 result = mpeg3video_read_frame_backend(video, 0);
29 if(video->output_src[0] && drop_count--)
31 mpeg3_cache_put_frame(track->frame_cache,
32 video->framenum - 1,
33 video->output_src[0],
34 video->output_src[1],
35 video->output_src[2],
36 video->coded_picture_width * video->coded_picture_height,
37 video->chrom_width * video->chrom_height,
38 video->chrom_width * video->chrom_height);
39 //printf("mpeg3video_drop_frames 1 %d\n", video->framenum);
42 else
44 result = mpeg3video_read_frame_backend(video, frame_number - video->framenum);
48 return result;
51 unsigned int mpeg3bits_next_startcode(mpeg3_bits_t* stream)
53 /* Perform forwards search */
54 mpeg3bits_byte_align(stream);
58 * printf("mpeg3bits_next_startcode 1 %lld %lld\n",
59 * stream->demuxer->titles[0]->fs->current_byte,
60 * stream->demuxer->titles[0]->fs->total_bytes);
64 //mpeg3_read_next_packet(stream->demuxer);
65 //printf("mpeg3bits_next_startcode 2 %d %d\n",
66 // stream->demuxer->titles[0]->fs->current_byte,
67 // stream->demuxer->titles[0]->fs->total_bytes);
69 //printf("mpeg3bits_next_startcode 2 %llx\n", mpeg3bits_tell(stream));
70 /* Perform search */
71 while(1)
73 unsigned int code = mpeg3bits_showbits32_noptr(stream);
75 if((code >> 8) == MPEG3_PACKET_START_CODE_PREFIX) break;
76 if(mpeg3bits_eof(stream)) break;
79 mpeg3bits_getbyte_noptr(stream);
82 * printf("mpeg3bits_next_startcode 3 %08x %d %d\n",
83 * mpeg3bits_showbits32_noptr(stream),
84 * stream->demuxer->titles[0]->fs->current_byte,
85 * stream->demuxer->titles[0]->fs->total_bytes);
89 //printf("mpeg3bits_next_startcode 4 %d %d\n",
90 // stream->demuxer->titles[0]->fs->current_byte,
91 // stream->demuxer->titles[0]->fs->total_bytes);
92 return mpeg3bits_showbits32_noptr(stream);
95 /* Line up on the beginning of the next code. */
96 int mpeg3video_next_code(mpeg3_bits_t* stream, unsigned int code)
98 while(!mpeg3bits_eof(stream) &&
99 mpeg3bits_showbits32_noptr(stream) != code)
101 mpeg3bits_getbyte_noptr(stream);
103 return mpeg3bits_eof(stream);
106 /* Line up on the beginning of the previous code. */
107 int mpeg3video_prev_code(mpeg3_demuxer_t *demuxer, unsigned int code)
109 uint32_t current_code = 0;
111 #define PREV_CODE_MACRO \
113 current_code >>= 8; \
114 current_code |= ((uint32_t)mpeg3demux_read_prev_char(demuxer)) << 24; \
117 PREV_CODE_MACRO
118 PREV_CODE_MACRO
119 PREV_CODE_MACRO
120 PREV_CODE_MACRO
122 while(!mpeg3demux_bof(demuxer) && current_code != code)
124 PREV_CODE_MACRO
126 return mpeg3demux_bof(demuxer);
129 long mpeg3video_goptimecode_to_frame(mpeg3video_t *video)
131 /* printf("mpeg3video_goptimecode_to_frame %d %d %d %d %f\n", */
132 /* video->gop_timecode.hour, video->gop_timecode.minute, video->gop_timecode.second, video->gop_timecode.frame, video->frame_rate); */
133 return (long)(video->gop_timecode.hour * 3600 * video->frame_rate +
134 video->gop_timecode.minute * 60 * video->frame_rate +
135 video->gop_timecode.second * video->frame_rate +
136 video->gop_timecode.frame) - 1 - video->first_frame;
139 int mpeg3video_match_refframes(mpeg3video_t *video)
141 unsigned char *dst, *src;
142 int i, j, size;
144 for(i = 0; i < 3; i++)
146 if(video->newframe[i])
148 if(video->newframe[i] == video->refframe[i])
150 src = video->refframe[i];
151 dst = video->oldrefframe[i];
153 else
155 src = video->oldrefframe[i];
156 dst = video->refframe[i];
159 if(i == 0)
160 size = video->coded_picture_width * video->coded_picture_height + 32 * video->coded_picture_width;
161 else
162 size = video->chrom_width * video->chrom_height + 32 * video->chrom_width;
164 memcpy(dst, src, size);
167 return 0;
170 int mpeg3video_seek_byte(mpeg3video_t *video, int64_t byte)
172 mpeg3_t *file = video->file;
173 mpeg3_bits_t *vstream = video->vstream;
174 mpeg3_demuxer_t *demuxer = vstream->demuxer;
176 video->byte_seek = byte;
180 // Need PTS now so audio can be synchronized
181 mpeg3bits_seek_byte(vstream, byte);
182 // file->percentage_pts = mpeg3demux_scan_pts(demuxer);
183 return 0;
186 int mpeg3video_seek_frame(mpeg3video_t *video, long frame)
188 video->frame_seek = frame;
189 return 0;
192 int mpeg3_rewind_video(mpeg3video_t *video)
194 mpeg3_vtrack_t *track = video->track;
195 mpeg3_bits_t *vstream = video->vstream;
197 if(track->frame_offsets)
198 mpeg3bits_seek_byte(vstream, track->frame_offsets[0]);
199 else
200 mpeg3bits_seek_byte(vstream, 0);
202 return 0;
205 int mpeg3video_seek(mpeg3video_t *video)
207 long this_gop_start;
208 int result = 0;
209 int back_step;
210 int attempts;
211 mpeg3_t *file = video->file;
212 mpeg3_bits_t *vstream = video->vstream;
213 mpeg3_vtrack_t *track = video->track;
214 mpeg3_demuxer_t *demuxer = vstream->demuxer;
215 int64_t byte;
216 long frame_number;
217 int match_refframes = 1;
221 /* Must do seeking here so files which don't use video don't seek. */
222 /* Seeking is done in the demuxer */
223 /* Seek to absolute byte */
224 if(video->byte_seek >= 0)
226 byte = video->byte_seek;
227 video->byte_seek = -1;
228 mpeg3demux_seek_byte(demuxer, byte);
231 // Clear subtitles
232 mpeg3_reset_subtitles(file);
235 // Rewind 2 I-frames
236 if(byte > 0)
238 //printf("mpeg3video_seek 1\n");
239 mpeg3demux_start_reverse(demuxer);
241 //printf("mpeg3video_seek 1 %lld\n", mpeg3demux_tell_byte(demuxer));
242 if(!result)
244 if(video->has_gops)
245 result = mpeg3video_prev_code(demuxer, MPEG3_GOP_START_CODE);
246 else
247 result = mpeg3video_prev_code(demuxer, MPEG3_SEQUENCE_START_CODE);
249 //printf("mpeg3video_seek 2 %lld\n", mpeg3demux_tell_byte(demuxer));
251 if(!result)
253 if(video->has_gops)
254 result = mpeg3video_prev_code(demuxer, MPEG3_GOP_START_CODE);
255 else
256 result = mpeg3video_prev_code(demuxer, MPEG3_SEQUENCE_START_CODE);
259 //printf("mpeg3video_seek 3 %lld\n", mpeg3demux_tell_byte(demuxer));
263 mpeg3demux_start_forward(demuxer);
265 else
267 // Read first frame
268 video->repeat_count = 0;
269 mpeg3bits_reset(vstream);
270 mpeg3video_read_frame_backend(video, 0);
271 mpeg3_rewind_video(video);
272 video->repeat_count = 0;
276 mpeg3bits_reset(vstream);
278 //printf("mpeg3video_seek 4 %lld\n", mpeg3demux_tell_byte(demuxer));
279 // Read up to the correct byte
280 result = 0;
281 video->repeat_count = 0;
282 while(!result &&
283 !mpeg3demux_eof(demuxer) &&
284 mpeg3demux_tell_byte(demuxer) < byte)
286 result = mpeg3video_read_frame_backend(video, 0);
289 //printf("mpeg3video_seek 5 %lld\n", mpeg3demux_tell_byte(demuxer));
294 mpeg3demux_reset_pts(demuxer);
296 //printf("mpeg3video_seek 10\n");
299 else
300 /* Seek to a frame */
301 if(video->frame_seek >= 0)
303 // Clear subtitles
304 mpeg3_reset_subtitles(file);
307 frame_number = video->frame_seek;
308 video->frame_seek = -1;
309 if(frame_number < 0) frame_number = 0;
310 if(frame_number > video->maxframe) frame_number = video->maxframe;
312 //printf("mpeg3video_seek 1 %ld %ld\n", frame_number, video->framenum);
314 /* Seek to I frame in table of contents. */
315 /* Determine time between seek position and previous subtitle. */
316 /* Subtract time difference from subtitle display time. */
317 if(track->frame_offsets)
319 mpeg3_reset_cache(track->frame_cache);
321 if((frame_number < video->framenum ||
322 frame_number - video->framenum > MPEG3_SEEK_THRESHOLD))
324 int i;
325 for(i = track->total_keyframe_numbers - 1; i >= 0; i--)
327 if(track->keyframe_numbers[i] <= frame_number)
329 int frame;
330 int64_t byte;
332 // Go 2 I-frames before current position
333 if(i > 0) i--;
335 frame = track->keyframe_numbers[i];
336 if(frame == 0)
337 byte = track->frame_offsets[0];
338 else
339 byte = track->frame_offsets[frame];
340 video->framenum = track->keyframe_numbers[i];
342 mpeg3bits_seek_byte(vstream, byte);
345 // Get first 2 I-frames
346 if(byte == 0)
348 mpeg3video_get_firstframe(video);
349 mpeg3video_read_frame_backend(video, 0);
354 video->repeat_count = 0;
356 // Read up to current frame
357 mpeg3video_drop_frames(video, frame_number - video->framenum, 1);
358 break;
362 else
364 video->repeat_count = 0;
365 mpeg3video_drop_frames(video, frame_number - video->framenum, 0);
368 else
369 /* No support for seeking without table of contents */
371 mpeg3video_toc_error();
376 mpeg3demux_reset_pts(demuxer);
379 return result;
382 int mpeg3video_previous_frame(mpeg3video_t *video)
384 mpeg3_bits_t *bitstream = video->vstream;
385 mpeg3_demuxer_t *demuxer = bitstream->demuxer;
386 int result = 0;
387 int64_t target_byte = 0;
389 if(mpeg3demux_tell_byte(demuxer) <= 0) return 1;
391 // Get location of end of previous picture
392 mpeg3demux_start_reverse(demuxer);
393 result = mpeg3video_prev_code(demuxer, MPEG3_PICTURE_START_CODE);
394 if(!result) result = mpeg3video_prev_code(demuxer, MPEG3_PICTURE_START_CODE);
395 if(!result) result = mpeg3video_prev_code(demuxer, MPEG3_PICTURE_START_CODE);
396 if(!result) target_byte = mpeg3demux_tell_byte(demuxer);
399 // Rewind 2 I-frames
400 if(!result)
402 if(video->has_gops)
403 result = mpeg3video_prev_code(demuxer, MPEG3_GOP_START_CODE);
404 else
405 result = mpeg3video_prev_code(demuxer, MPEG3_SEQUENCE_START_CODE);
408 if(!result)
410 if(video->has_gops)
411 result = mpeg3video_prev_code(demuxer, MPEG3_GOP_START_CODE);
412 else
413 result = mpeg3video_prev_code(demuxer, MPEG3_SEQUENCE_START_CODE);
416 mpeg3demux_start_forward(demuxer);
417 mpeg3bits_reset(bitstream);
419 // Read up to correct byte
420 result = 0;
421 video->repeat_count = 0;
422 while(!result &&
423 !mpeg3demux_eof(demuxer) &&
424 mpeg3demux_tell_byte(demuxer) < target_byte)
426 result = mpeg3video_read_frame_backend(video, 0);
429 video->repeat_count = 0;
430 return 0;