1 #include "../mpeg3private.h"
2 #include "../mpeg3protos.h"
3 #include "mpeg3video.h"
7 void mpeg3video_toc_error()
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 unsigned int mpeg3bits_next_startcode(mpeg3_bits_t
* stream
)
17 /* Perform forwards search */
18 mpeg3bits_byte_align(stream
);
22 * printf("mpeg3bits_next_startcode 1 %lld %lld\n",
23 * stream->demuxer->titles[0]->fs->current_byte,
24 * stream->demuxer->titles[0]->fs->total_bytes);
28 //mpeg3_read_next_packet(stream->demuxer);
29 //printf("mpeg3bits_next_startcode 2 %d %d\n",
30 // stream->demuxer->titles[0]->fs->current_byte,
31 // stream->demuxer->titles[0]->fs->total_bytes);
33 //printf("mpeg3bits_next_startcode 2 %llx\n", mpeg3bits_tell(stream));
37 unsigned int code
= mpeg3bits_showbits32_noptr(stream
);
39 if((code
>> 8) == MPEG3_PACKET_START_CODE_PREFIX
) break;
40 if(mpeg3bits_eof(stream
)) break;
43 mpeg3bits_getbyte_noptr(stream
);
46 * printf("mpeg3bits_next_startcode 3 %08x %d %d\n",
47 * mpeg3bits_showbits32_noptr(stream),
48 * stream->demuxer->titles[0]->fs->current_byte,
49 * stream->demuxer->titles[0]->fs->total_bytes);
53 //printf("mpeg3bits_next_startcode 4 %d %d\n",
54 // stream->demuxer->titles[0]->fs->current_byte,
55 // stream->demuxer->titles[0]->fs->total_bytes);
56 return mpeg3bits_showbits32_noptr(stream
);
59 /* Line up on the beginning of the next code. */
60 int mpeg3video_next_code(mpeg3_bits_t
* stream
, unsigned int code
)
62 while(!mpeg3bits_eof(stream
) &&
63 mpeg3bits_showbits32_noptr(stream
) != code
)
65 mpeg3bits_getbyte_noptr(stream
);
67 return mpeg3bits_eof(stream
);
70 /* Line up on the beginning of the previous code. */
71 int mpeg3video_prev_code(mpeg3_demuxer_t
*demuxer
, unsigned int code
)
73 uint32_t current_code
= 0;
75 #define PREV_CODE_MACRO \
78 current_code |= ((uint32_t)mpeg3demux_read_prev_char(demuxer)) << 24; \
86 while(!mpeg3demux_bof(demuxer
) && current_code
!= code
)
90 return mpeg3demux_bof(demuxer
);
93 long mpeg3video_goptimecode_to_frame(mpeg3video_t
*video
)
95 /* printf("mpeg3video_goptimecode_to_frame %d %d %d %d %f\n", */
96 /* video->gop_timecode.hour, video->gop_timecode.minute, video->gop_timecode.second, video->gop_timecode.frame, video->frame_rate); */
97 return (long)(video
->gop_timecode
.hour
* 3600 * video
->frame_rate
+
98 video
->gop_timecode
.minute
* 60 * video
->frame_rate
+
99 video
->gop_timecode
.second
* video
->frame_rate
+
100 video
->gop_timecode
.frame
) - 1 - video
->first_frame
;
103 int mpeg3video_match_refframes(mpeg3video_t
*video
)
105 unsigned char *dst
, *src
;
108 for(i
= 0; i
< 3; i
++)
110 if(video
->newframe
[i
])
112 if(video
->newframe
[i
] == video
->refframe
[i
])
114 src
= video
->refframe
[i
];
115 dst
= video
->oldrefframe
[i
];
119 src
= video
->oldrefframe
[i
];
120 dst
= video
->refframe
[i
];
124 size
= video
->coded_picture_width
* video
->coded_picture_height
+ 32 * video
->coded_picture_width
;
126 size
= video
->chrom_width
* video
->chrom_height
+ 32 * video
->chrom_width
;
128 memcpy(dst
, src
, size
);
134 int mpeg3video_seek_byte(mpeg3video_t
*video
, int64_t byte
)
136 mpeg3_t
*file
= video
->file
;
137 mpeg3_bits_t
*vstream
= video
->vstream
;
138 mpeg3_demuxer_t
*demuxer
= vstream
->demuxer
;
140 video
->byte_seek
= byte
;
144 // Need PTS now so audio can be synchronized
145 mpeg3bits_seek_byte(vstream
, byte
);
146 // file->percentage_pts = mpeg3demux_scan_pts(demuxer);
150 int mpeg3video_seek_frame(mpeg3video_t
*video
, long frame
)
152 video
->frame_seek
= frame
;
156 int mpeg3_rewind_video(mpeg3video_t
*video
)
158 mpeg3_vtrack_t
*track
= video
->track
;
159 mpeg3_bits_t
*vstream
= video
->vstream
;
161 if(track
->frame_offsets
)
162 mpeg3bits_seek_byte(vstream
, track
->frame_offsets
[0]);
164 mpeg3bits_seek_byte(vstream
, 0);
169 int mpeg3video_seek(mpeg3video_t
*video
)
175 mpeg3_t
*file
= video
->file
;
176 mpeg3_bits_t
*vstream
= video
->vstream
;
177 mpeg3_vtrack_t
*track
= video
->track
;
178 mpeg3_demuxer_t
*demuxer
= vstream
->demuxer
;
181 int match_refframes
= 1;
185 /* Must do seeking here so files which don't use video don't seek. */
186 /* Seeking is done in the demuxer */
187 /* Seek to absolute byte */
188 if(video
->byte_seek
>= 0)
190 byte
= video
->byte_seek
;
191 video
->byte_seek
= -1;
192 mpeg3demux_seek_byte(demuxer
, byte
);
197 //printf("mpeg3video_seek 1\n");
198 mpeg3demux_start_reverse(demuxer
);
200 //printf("mpeg3video_seek 1 %lld\n", mpeg3demux_tell_byte(demuxer));
204 result
= mpeg3video_prev_code(demuxer
, MPEG3_GOP_START_CODE
);
206 result
= mpeg3video_prev_code(demuxer
, MPEG3_SEQUENCE_START_CODE
);
208 //printf("mpeg3video_seek 2 %lld\n", mpeg3demux_tell_byte(demuxer));
213 result
= mpeg3video_prev_code(demuxer
, MPEG3_GOP_START_CODE
);
215 result
= mpeg3video_prev_code(demuxer
, MPEG3_SEQUENCE_START_CODE
);
218 //printf("mpeg3video_seek 3 %lld\n", mpeg3demux_tell_byte(demuxer));
222 mpeg3demux_start_forward(demuxer
);
227 video
->repeat_count
= 0;
228 mpeg3bits_reset(vstream
);
229 mpeg3video_read_frame_backend(video
, 0);
230 mpeg3_rewind_video(video
);
231 video
->repeat_count
= 0;
235 mpeg3bits_reset(vstream
);
237 //printf("mpeg3video_seek 4 %lld\n", mpeg3demux_tell_byte(demuxer));
238 // Read up to the correct byte
240 video
->repeat_count
= 0;
242 !mpeg3demux_eof(demuxer
) &&
243 mpeg3demux_tell_byte(demuxer
) < byte
)
245 result
= mpeg3video_read_frame_backend(video
, 0);
248 //printf("mpeg3video_seek 5 %lld\n", mpeg3demux_tell_byte(demuxer));
253 mpeg3demux_reset_pts(demuxer
);
255 //printf("mpeg3video_seek 10\n");
259 /* Seek to a frame */
260 if(video
->frame_seek
>= 0)
262 frame_number
= video
->frame_seek
;
263 video
->frame_seek
= -1;
264 if(frame_number
< 0) frame_number
= 0;
265 if(frame_number
> video
->maxframe
) frame_number
= video
->maxframe
;
267 //printf("mpeg3video_seek 1 %ld %ld\n", frame_number, video->framenum);
269 /* Seek to I frame in table of contents */
270 if(track
->frame_offsets
)
272 if((frame_number
< video
->framenum
||
273 frame_number
- video
->framenum
> MPEG3_SEEK_THRESHOLD
))
276 for(i
= track
->total_keyframe_numbers
- 1; i
>= 0; i
--)
278 if(track
->keyframe_numbers
[i
] <= frame_number
)
283 // Go 2 I-frames before current position
286 frame
= track
->keyframe_numbers
[i
];
288 byte
= track
->frame_offsets
[0];
290 byte
= track
->frame_offsets
[frame
];
291 video
->framenum
= track
->keyframe_numbers
[i
];
293 mpeg3bits_seek_byte(vstream
, byte
);
296 // Get first 2 I-frames
299 mpeg3video_get_firstframe(video
);
300 mpeg3video_read_frame_backend(video
, 0);
305 video
->repeat_count
= 0;
306 mpeg3video_drop_frames(video
, frame_number
- video
->framenum
);
313 video
->repeat_count
= 0;
314 mpeg3video_drop_frames(video
, frame_number
- video
->framenum
);
318 /* Discontinue support of seeking without table of contents */
320 mpeg3video_toc_error();
336 /* Seek to start of file */
337 if(frame_number
< 16)
339 video
->repeat_count
= video
->current_repeat
= 0;
340 mpeg3bits_seek_start(vstream
);
342 result
= mpeg3video_drop_frames(video
,
343 frame_number
- video
->framenum
);
347 /* Seek to an I frame. */
348 //printf(__FUNCTION__ " frame_number=%d video->framenum=%d\n", frame_number, video->framenum);
349 if((frame_number
< video
->framenum
||
350 frame_number
- video
->framenum
> MPEG3_SEEK_THRESHOLD
))
355 /* Elementary stream. Estimate frame position from total bytes. */
356 if(file
->is_video_stream
)
358 int64_t byte
= (int64_t)((double)(mpeg3demux_movie_size(demuxer
) /
359 track
->total_frames
) *
361 long minimum
= 65535;
364 /* Get GOP just before frame */
367 result
= mpeg3bits_seek_byte(vstream
, byte
);
368 mpeg3bits_start_reverse(vstream
);
370 if(!result
) result
= mpeg3video_prev_code(vstream
, MPEG3_GOP_START_CODE
);
371 mpeg3bits_start_forward(vstream
);
372 mpeg3bits_getbits(vstream
, 8);
373 if(!result
) result
= mpeg3video_getgophdr(video
);
374 this_gop_start
= mpeg3video_goptimecode_to_frame(video
);
376 //printf("wanted %ld guessed %ld byte %ld result %d\n", frame_number, this_gop_start, byte, result);
377 if(labs(this_gop_start
- frame_number
) >= labs(minimum
))
381 minimum
= this_gop_start
- frame_number
;
382 byte
+= (long)((float)(frame_number
- this_gop_start
) *
383 (double)(mpeg3demux_movie_size(demuxer
) /
384 track
->total_frames
));
385 if(byte
< 0) byte
= 0;
387 }while(!result
&& !done
);
389 //printf("wanted %d guessed %d\n", frame_number, this_gop_start);
392 video
->framenum
= this_gop_start
;
393 result
= mpeg3video_drop_frames(video
, frame_number
- video
->framenum
);
403 mpeg3bits_seek_time(vstream
, (double)frame_number
/ video
->frame_rate
);
405 byte
= mpeg3bits_tell(vstream
);
406 mpeg3bits_start_reverse(vstream
);
407 mpeg3video_prev_code(vstream
, MPEG3_GOP_START_CODE
);
408 mpeg3bits_getbits_reverse(vstream
, 32);
409 mpeg3bits_start_forward(vstream
);
411 while(!result
&& mpeg3bits_tell(vstream
) < byte
)
413 result
= mpeg3video_read_frame_backend(video
, 0);
415 mpeg3video_match_refframes(video
);
419 //printf("seek system 3 %f\n", (double)frame_number / video->frame_rate);
422 video
->framenum
= frame_number
;
427 mpeg3video_drop_frames(video
, frame_number
- video
->framenum
);
446 mpeg3demux_reset_pts(demuxer
);
452 int mpeg3video_previous_frame(mpeg3video_t
*video
)
454 mpeg3_bits_t
*bitstream
= video
->vstream
;
455 mpeg3_demuxer_t
*demuxer
= bitstream
->demuxer
;
457 int64_t target_byte
= 0;
459 if(mpeg3demux_tell_byte(demuxer
) <= 0) return 1;
461 // Get location of end of previous picture
462 mpeg3demux_start_reverse(demuxer
);
463 result
= mpeg3video_prev_code(demuxer
, MPEG3_PICTURE_START_CODE
);
464 if(!result
) result
= mpeg3video_prev_code(demuxer
, MPEG3_PICTURE_START_CODE
);
465 if(!result
) result
= mpeg3video_prev_code(demuxer
, MPEG3_PICTURE_START_CODE
);
466 if(!result
) target_byte
= mpeg3demux_tell_byte(demuxer
);
473 result
= mpeg3video_prev_code(demuxer
, MPEG3_GOP_START_CODE
);
475 result
= mpeg3video_prev_code(demuxer
, MPEG3_SEQUENCE_START_CODE
);
481 result
= mpeg3video_prev_code(demuxer
, MPEG3_GOP_START_CODE
);
483 result
= mpeg3video_prev_code(demuxer
, MPEG3_SEQUENCE_START_CODE
);
486 mpeg3demux_start_forward(demuxer
);
487 mpeg3bits_reset(bitstream
);
489 // Read up to correct byte
491 video
->repeat_count
= 0;
493 !mpeg3demux_eof(demuxer
) &&
494 mpeg3demux_tell_byte(demuxer
) < target_byte
)
496 result
= mpeg3video_read_frame_backend(video
, 0);
499 video
->repeat_count
= 0;
503 int mpeg3video_drop_frames(mpeg3video_t
*video
, long frames
)
506 long frame_number
= video
->framenum
+ frames
;
508 //printf("mpeg3video_drop_frames 1 %d %d\n", frame_number, video->framenum);
509 /* Read the selected number of frames and skip b-frames */
510 while(!result
&& frame_number
> video
->framenum
)
512 result
= mpeg3video_read_frame_backend(video
, frame_number
- video
->framenum
);
514 //printf("mpeg3video_drop_frames 100\n");