1 #include "../mpeg3private.h"
2 #include "../mpeg3protos.h"
3 #include "mpeg3video.h"
7 unsigned int mpeg3bits_next_startcode(mpeg3_bits_t
* stream
)
9 /* Perform forwards search */
10 mpeg3bits_byte_align(stream
);
13 //printf("mpeg3bits_next_startcode 1 %lld %lld\n",
14 // stream->demuxer->titles[0]->fs->current_byte,
15 // stream->demuxer->titles[0]->fs->total_bytes);
18 //mpeg3_read_next_packet(stream->demuxer);
19 //printf("mpeg3bits_next_startcode 2 %d %d\n",
20 // stream->demuxer->titles[0]->fs->current_byte,
21 // stream->demuxer->titles[0]->fs->total_bytes);
23 //printf("mpeg3bits_next_startcode 2 %llx\n", mpeg3bits_tell(stream));
27 unsigned int code
= mpeg3bits_showbits32_noptr(stream
);
29 if((code
>> 8) == MPEG3_PACKET_START_CODE_PREFIX
) break;
30 if(mpeg3bits_eof(stream
)) break;
33 mpeg3bits_getbyte_noptr(stream
);
36 * printf("mpeg3bits_next_startcode 3 %08x %d %d\n",
37 * mpeg3bits_showbits32_noptr(stream),
38 * stream->demuxer->titles[0]->fs->current_byte,
39 * stream->demuxer->titles[0]->fs->total_bytes);
43 //printf("mpeg3bits_next_startcode 4 %d %d\n",
44 // stream->demuxer->titles[0]->fs->current_byte,
45 // stream->demuxer->titles[0]->fs->total_bytes);
46 return mpeg3bits_showbits32_noptr(stream
);
49 /* Line up on the beginning of the next code. */
50 int mpeg3video_next_code(mpeg3_bits_t
* stream
, unsigned int code
)
52 while(!mpeg3bits_eof(stream
) &&
53 mpeg3bits_showbits32_noptr(stream
) != code
)
55 mpeg3bits_getbyte_noptr(stream
);
57 return mpeg3bits_eof(stream
);
60 /* Line up on the beginning of the previous code. */
61 int mpeg3video_prev_code(mpeg3_bits_t
* stream
, unsigned int code
)
63 while(!mpeg3bits_bof(stream
) &&
64 mpeg3bits_showbits_reverse(stream
, 32) != code
)
66 //printf("mpeg3video_prev_code %08x %08x\n",
67 // mpeg3bits_showbits_reverse(stream, 32), mpeg3demux_tell(stream->demuxer));
68 mpeg3bits_getbits_reverse(stream
, 8);
70 return mpeg3bits_bof(stream
);
73 long mpeg3video_goptimecode_to_frame(mpeg3video_t
*video
)
75 /* printf("mpeg3video_goptimecode_to_frame %d %d %d %d %f\n", */
76 /* video->gop_timecode.hour, video->gop_timecode.minute, video->gop_timecode.second, video->gop_timecode.frame, video->frame_rate); */
77 return (long)(video
->gop_timecode
.hour
* 3600 * video
->frame_rate
+
78 video
->gop_timecode
.minute
* 60 * video
->frame_rate
+
79 video
->gop_timecode
.second
* video
->frame_rate
+
80 video
->gop_timecode
.frame
) - 1 - video
->first_frame
;
83 int mpeg3video_match_refframes(mpeg3video_t
*video
)
85 unsigned char *dst
, *src
;
88 for(i
= 0; i
< 3; i
++)
90 if(video
->newframe
[i
])
92 if(video
->newframe
[i
] == video
->refframe
[i
])
94 src
= video
->refframe
[i
];
95 dst
= video
->oldrefframe
[i
];
99 src
= video
->oldrefframe
[i
];
100 dst
= video
->refframe
[i
];
104 size
= video
->coded_picture_width
* video
->coded_picture_height
+ 32 * video
->coded_picture_width
;
106 size
= video
->chrom_width
* video
->chrom_height
+ 32 * video
->chrom_width
;
108 memcpy(dst
, src
, size
);
114 int mpeg3video_seek_percentage(mpeg3video_t
*video
, double percentage
)
116 mpeg3_t
*file
= video
->file
;
117 mpeg3_bits_t
*vstream
= video
->vstream
;
118 mpeg3_demuxer_t
*demuxer
= vstream
->demuxer
;
120 video
->percentage_seek
= percentage
;
124 // Need PTS now so audio can be synchronized
125 mpeg3bits_seek_percentage(vstream
, percentage
);
126 file
->percentage_pts
= mpeg3demux_scan_pts(demuxer
);
130 int mpeg3video_seek_frame(mpeg3video_t
*video
, long frame
)
132 video
->frame_seek
= frame
;
136 int mpeg3video_seek(mpeg3video_t
*video
)
142 mpeg3_t
*file
= video
->file
;
143 mpeg3_bits_t
*vstream
= video
->vstream
;
144 mpeg3_vtrack_t
*track
= video
->track
;
145 mpeg3_demuxer_t
*demuxer
= vstream
->demuxer
;
148 int match_refframes
= 1;
151 //printf("mpeg3video_seek 1 %d\n", video->frame_seek);
152 // Must do seeking here so files which don't use video don't seek.
153 /* Seek to percentage */
154 if(video
->percentage_seek
>= 0)
164 //printf("mpeg3video_seek 1 %f\n", video->percentage_seek);
165 percentage
= video
->percentage_seek
;
166 video
->percentage_seek
= -1;
167 mpeg3bits_seek_percentage(vstream
, percentage
);
169 // Go to previous I-frame #1
171 mpeg3bits_start_reverse(vstream
);
172 //printf("mpeg3video_seek 2\n");
175 result
= mpeg3video_prev_code(vstream
, MPEG3_GOP_START_CODE
);
177 result
= mpeg3video_prev_code(vstream
, MPEG3_SEQUENCE_START_CODE
);
178 //printf("mpeg3video_seek 3\n");
180 if(!result
) mpeg3bits_getbits_reverse(vstream
, 32);
182 //printf("mpeg3video_seek 4\n");
185 // Go to previous I-frame #2
187 result
= mpeg3video_prev_code(vstream
, MPEG3_GOP_START_CODE
);
189 result
= mpeg3video_prev_code(vstream
, MPEG3_SEQUENCE_START_CODE
);
190 //printf("mpeg3video_seek 4\n");
192 if(!result
) mpeg3bits_getbits_reverse(vstream
, 32);
194 //printf("mpeg3video_seek 4\n");
198 mpeg3bits_start_forward(vstream
);
199 //printf("mpeg3video_seek 4\n");
201 // Reread first two I frames
202 if(mpeg3bits_tell_percentage(vstream
) <= 0)
204 //printf("mpeg3video_seek 4.1\n");
205 mpeg3bits_seek_percentage(vstream
, 0);
206 //printf("mpeg3video_seek 4.2\n");
207 mpeg3video_get_firstframe(video
);
208 //printf("mpeg3video_seek 4.3\n");
209 mpeg3video_read_frame_backend(video
, 0);
210 //printf("mpeg3video_seek 4.4\n");
213 //printf("mpeg3video_seek 5\n");
216 // Read up to the correct percentage
218 while(!result
&& mpeg3bits_tell_percentage(vstream
) < percentage
)
220 result
= mpeg3video_read_frame_backend(video
, 0);
224 //printf("mpeg3video_seek 6 %f\n", mpeg3demux_scan_pts(demuxer));
228 mpeg3demux_reset_pts(demuxer
);
230 //printf("mpeg3video_seek 7\n");
234 /* Seek to a frame */
235 if(video
->frame_seek
>= 0)
237 frame_number
= video
->frame_seek
;
238 video
->frame_seek
= -1;
239 if(frame_number
< 0) frame_number
= 0;
240 if(frame_number
> video
->maxframe
) frame_number
= video
->maxframe
;
242 //printf("mpeg3video_seek 1 %ld %ld\n", frame_number, video->framenum);
244 /* Seek to I frame in table of contents */
245 if(track
->frame_offsets
)
247 //printf("mpeg3video_seek 2 %d %d\n", video->framenum, frame_number);
248 if((frame_number
< video
->framenum
||
249 frame_number
- video
->framenum
> MPEG3_SEEK_THRESHOLD
))
252 for(i
= track
->total_keyframe_numbers
- 1; i
>= 0; i
--)
254 //printf("mpeg3video_seek 3 %lld %d\n", track->keyframe_numbers[i], frame_number);
255 if(track
->keyframe_numbers
[i
] <= frame_number
)
261 // Go 2 I-frames before current position
264 frame
= track
->keyframe_numbers
[i
];
265 title_number
= (track
->frame_offsets
[frame
] &
266 0xff00000000000000) >> 56;
267 byte
= track
->frame_offsets
[frame
] &
270 video
->framenum
= track
->keyframe_numbers
[i
];
272 mpeg3bits_open_title(vstream
, title_number
);
273 mpeg3bits_seek_byte(vstream
, byte
);
276 // Get first 2 I-frames
279 mpeg3video_get_firstframe(video
);
280 mpeg3video_read_frame_backend(video
, 0);
284 //printf("mpeg3video_seek 2 %ld %ld\n", frame_number, video->framenum);
286 mpeg3video_drop_frames(video
, frame_number
- video
->framenum
);
293 mpeg3video_drop_frames(video
, frame_number
- video
->framenum
);
297 /* Seek to start of file */
298 if(frame_number
< 16)
300 video
->repeat_count
= video
->current_repeat
= 0;
301 mpeg3bits_seek_start(vstream
);
303 result
= mpeg3video_drop_frames(video
,
304 frame_number
- video
->framenum
);
308 /* Seek to an I frame. */
309 //printf(__FUNCTION__ " frame_number=%d video->framenum=%d\n", frame_number, video->framenum);
310 if((frame_number
< video
->framenum
||
311 frame_number
- video
->framenum
> MPEG3_SEEK_THRESHOLD
))
316 /* Elementary stream */
317 if(file
->is_video_stream
)
319 mpeg3_t
*file
= video
->file
;
320 mpeg3_vtrack_t
*track
= video
->track
;
321 int64_t byte
= (int64_t)((double)(mpeg3demuxer_total_bytes(demuxer
) /
322 track
->total_frames
) *
324 long minimum
= 65535;
327 /* Get GOP just before frame */
330 result
= mpeg3bits_seek_byte(vstream
, byte
);
331 mpeg3bits_start_reverse(vstream
);
333 if(!result
) result
= mpeg3video_prev_code(vstream
, MPEG3_GOP_START_CODE
);
334 mpeg3bits_start_forward(vstream
);
335 mpeg3bits_getbits(vstream
, 8);
336 if(!result
) result
= mpeg3video_getgophdr(video
);
337 this_gop_start
= mpeg3video_goptimecode_to_frame(video
);
339 //printf("wanted %ld guessed %ld byte %ld result %d\n", frame_number, this_gop_start, byte, result);
340 if(labs(this_gop_start
- frame_number
) >= labs(minimum
))
344 minimum
= this_gop_start
- frame_number
;
345 byte
+= (long)((float)(frame_number
- this_gop_start
) *
346 (float)(mpeg3demuxer_total_bytes(demuxer
) /
347 track
->total_frames
));
348 if(byte
< 0) byte
= 0;
350 }while(!result
&& !done
);
352 //printf("wanted %d guessed %d\n", frame_number, this_gop_start);
355 video
->framenum
= this_gop_start
;
356 result
= mpeg3video_drop_frames(video
, frame_number
- video
->framenum
);
366 mpeg3bits_seek_time(vstream
, (double)frame_number
/ video
->frame_rate
);
368 percentage
= mpeg3bits_tell_percentage(vstream
);
369 //printf("seek frame %ld percentage %f byte %ld\n", frame_number, percentage, mpeg3bits_tell(vstream));
370 mpeg3bits_start_reverse(vstream
);
371 mpeg3video_prev_code(vstream
, MPEG3_GOP_START_CODE
);
372 mpeg3bits_getbits_reverse(vstream
, 32);
373 mpeg3bits_start_forward(vstream
);
374 //printf("seek system 1 %f\n", (double)frame_number / video->frame_rate);
376 while(!result
&& mpeg3bits_tell_percentage(vstream
) < percentage
)
378 result
= mpeg3video_read_frame_backend(video
, 0);
380 mpeg3video_match_refframes(video
);
382 //printf("seek system 2 %f %f\n", mpeg3bits_tell_percentage(vstream) / percentage);
385 //printf("seek system 3 %f\n", (double)frame_number / video->frame_rate);
388 video
->framenum
= frame_number
;
393 mpeg3video_drop_frames(video
, frame_number
- video
->framenum
);
396 mpeg3demux_reset_pts(demuxer
);
402 int mpeg3video_previous_frame(mpeg3video_t
*video
)
404 if(mpeg3bits_tell_percentage(video
->vstream
) <= 0) return 1;
407 mpeg3bits_start_reverse(video
->vstream
);
408 mpeg3video_prev_code(video
->vstream
, MPEG3_PICTURE_START_CODE
);
409 mpeg3bits_getbits_reverse(video
->vstream
, 32);
411 if(mpeg3bits_bof(video
->vstream
))
412 mpeg3bits_seek_percentage(video
->vstream
, 0);
413 mpeg3bits_start_forward(video
->vstream
);
414 video
->repeat_count
= 0;
418 int mpeg3video_drop_frames(mpeg3video_t
*video
, long frames
)
421 long frame_number
= video
->framenum
+ frames
;
423 //printf("mpeg3video_drop_frames 1 %d %d\n", frame_number, video->framenum);
424 /* Read the selected number of frames and skip b-frames */
425 while(!result
&& frame_number
> video
->framenum
)
427 result
= mpeg3video_read_frame_backend(video
, frame_number
- video
->framenum
);
429 //printf("mpeg3video_drop_frames 100\n");