00001 #include "../mpeg3private.h"
00002 #include "../mpeg3protos.h"
00003 #include "mpeg3video.h"
00004 #include <stdlib.h>
00005 #include <string.h>
00006
00007 void mpeg3video_toc_error()
00008 {
00009 fprintf(stderr,
00010 "mpeg3video_seek: frame accurate seeking without a table of contents \n"
00011 "is no longer supported. Use mpeg3toc <mpeg file> <table of contents>\n"
00012 "to generate a table of contents and load the table of contents instead.\n");
00013 }
00014
00015 int mpeg3video_drop_frames(mpeg3video_t *video, long frames, int cache_it)
00016 {
00017 int result = 0;
00018 long frame_number = video->framenum + frames;
00019 mpeg3_vtrack_t *track = video->track;
00020
00021 int drop_count = 3;
00022
00023
00024 while(!result && frame_number > video->framenum)
00025 {
00026 if(cache_it)
00027 {
00028 result = mpeg3video_read_frame_backend(video, 0);
00029 if(video->output_src[0] && drop_count--)
00030 {
00031 mpeg3_cache_put_frame(track->frame_cache,
00032 video->framenum - 1,
00033 video->output_src[0],
00034 video->output_src[1],
00035 video->output_src[2],
00036 video->coded_picture_width * video->coded_picture_height,
00037 video->chrom_width * video->chrom_height,
00038 video->chrom_width * video->chrom_height);
00039
00040 }
00041 }
00042 else
00043 {
00044 result = mpeg3video_read_frame_backend(video, frame_number - video->framenum);
00045 }
00046 }
00047
00048 return result;
00049 }
00050
00051 unsigned int mpeg3bits_next_startcode(mpeg3_bits_t* stream)
00052 {
00053
00054 mpeg3bits_byte_align(stream);
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 while(1)
00072 {
00073 unsigned int code = mpeg3bits_showbits32_noptr(stream);
00074
00075 if((code >> 8) == MPEG3_PACKET_START_CODE_PREFIX) break;
00076 if(mpeg3bits_eof(stream)) break;
00077
00078
00079 mpeg3bits_getbyte_noptr(stream);
00080
00081
00082
00083
00084
00085
00086
00087
00088 }
00089
00090
00091
00092 return mpeg3bits_showbits32_noptr(stream);
00093 }
00094
00095
00096 int mpeg3video_next_code(mpeg3_bits_t* stream, unsigned int code)
00097 {
00098 while(!mpeg3bits_eof(stream) &&
00099 mpeg3bits_showbits32_noptr(stream) != code)
00100 {
00101 mpeg3bits_getbyte_noptr(stream);
00102 }
00103 return mpeg3bits_eof(stream);
00104 }
00105
00106
00107 int mpeg3video_prev_code(mpeg3_demuxer_t *demuxer, unsigned int code)
00108 {
00109 uint32_t current_code = 0;
00110
00111 #define PREV_CODE_MACRO \
00112 { \
00113 current_code >>= 8; \
00114 current_code |= ((uint32_t)mpeg3demux_read_prev_char(demuxer)) << 24; \
00115 }
00116
00117 PREV_CODE_MACRO
00118 PREV_CODE_MACRO
00119 PREV_CODE_MACRO
00120 PREV_CODE_MACRO
00121
00122 while(!mpeg3demux_bof(demuxer) && current_code != code)
00123 {
00124 PREV_CODE_MACRO
00125 }
00126 return mpeg3demux_bof(demuxer);
00127 }
00128
00129 long mpeg3video_goptimecode_to_frame(mpeg3video_t *video)
00130 {
00131
00132
00133 return (long)(video->gop_timecode.hour * 3600 * video->frame_rate +
00134 video->gop_timecode.minute * 60 * video->frame_rate +
00135 video->gop_timecode.second * video->frame_rate +
00136 video->gop_timecode.frame) - 1 - video->first_frame;
00137 }
00138
00139 int mpeg3video_match_refframes(mpeg3video_t *video)
00140 {
00141 unsigned char *dst, *src;
00142 int i, j, size;
00143
00144 for(i = 0; i < 3; i++)
00145 {
00146 if(video->newframe[i])
00147 {
00148 if(video->newframe[i] == video->refframe[i])
00149 {
00150 src = video->refframe[i];
00151 dst = video->oldrefframe[i];
00152 }
00153 else
00154 {
00155 src = video->oldrefframe[i];
00156 dst = video->refframe[i];
00157 }
00158
00159 if(i == 0)
00160 size = video->coded_picture_width * video->coded_picture_height + 32 * video->coded_picture_width;
00161 else
00162 size = video->chrom_width * video->chrom_height + 32 * video->chrom_width;
00163
00164 memcpy(dst, src, size);
00165 }
00166 }
00167 return 0;
00168 }
00169
00170 int mpeg3video_seek_byte(mpeg3video_t *video, int64_t byte)
00171 {
00172 mpeg3_t *file = video->file;
00173 mpeg3_bits_t *vstream = video->vstream;
00174 mpeg3_demuxer_t *demuxer = vstream->demuxer;
00175
00176 video->byte_seek = byte;
00177
00178
00179
00180
00181 mpeg3bits_seek_byte(vstream, byte);
00182
00183 return 0;
00184 }
00185
00186 int mpeg3video_seek_frame(mpeg3video_t *video, long frame)
00187 {
00188 video->frame_seek = frame;
00189 return 0;
00190 }
00191
00192 int mpeg3_rewind_video(mpeg3video_t *video)
00193 {
00194 mpeg3_vtrack_t *track = video->track;
00195 mpeg3_bits_t *vstream = video->vstream;
00196
00197 if(track->frame_offsets)
00198 mpeg3bits_seek_byte(vstream, track->frame_offsets[0]);
00199 else
00200 mpeg3bits_seek_byte(vstream, 0);
00201
00202 return 0;
00203 }
00204
00205 int mpeg3video_seek(mpeg3video_t *video)
00206 {
00207 long this_gop_start;
00208 int result = 0;
00209 int back_step;
00210 int attempts;
00211 mpeg3_t *file = video->file;
00212 mpeg3_bits_t *vstream = video->vstream;
00213 mpeg3_vtrack_t *track = video->track;
00214 mpeg3_demuxer_t *demuxer = vstream->demuxer;
00215 int64_t byte;
00216 long frame_number;
00217 int match_refframes = 1;
00218
00219
00220
00221
00222
00223
00224 if(video->byte_seek >= 0)
00225 {
00226 byte = video->byte_seek;
00227 video->byte_seek = -1;
00228 mpeg3demux_seek_byte(demuxer, byte);
00229
00230
00231
00232 mpeg3_reset_subtitles(file);
00233
00234
00235
00236 if(byte > 0)
00237 {
00238
00239 mpeg3demux_start_reverse(demuxer);
00240
00241
00242 if(!result)
00243 {
00244 if(video->has_gops)
00245 result = mpeg3video_prev_code(demuxer, MPEG3_GOP_START_CODE);
00246 else
00247 result = mpeg3video_prev_code(demuxer, MPEG3_SEQUENCE_START_CODE);
00248 }
00249
00250
00251 if(!result)
00252 {
00253 if(video->has_gops)
00254 result = mpeg3video_prev_code(demuxer, MPEG3_GOP_START_CODE);
00255 else
00256 result = mpeg3video_prev_code(demuxer, MPEG3_SEQUENCE_START_CODE);
00257 }
00258
00259
00260
00261
00262
00263 mpeg3demux_start_forward(demuxer);
00264 }
00265 else
00266 {
00267
00268 video->repeat_count = 0;
00269 mpeg3bits_reset(vstream);
00270 mpeg3video_read_frame_backend(video, 0);
00271 mpeg3_rewind_video(video);
00272 video->repeat_count = 0;
00273 }
00274
00275
00276 mpeg3bits_reset(vstream);
00277
00278
00279
00280 result = 0;
00281 video->repeat_count = 0;
00282 while(!result &&
00283 !mpeg3demux_eof(demuxer) &&
00284 mpeg3demux_tell_byte(demuxer) < byte)
00285 {
00286 result = mpeg3video_read_frame_backend(video, 0);
00287 }
00288
00289
00290
00291
00292
00293
00294 mpeg3demux_reset_pts(demuxer);
00295
00296
00297
00298 }
00299 else
00300
00301 if(video->frame_seek >= 0)
00302 {
00303
00304 mpeg3_reset_subtitles(file);
00305
00306
00307 frame_number = video->frame_seek;
00308 video->frame_seek = -1;
00309 if(frame_number < 0) frame_number = 0;
00310 if(frame_number > video->maxframe) frame_number = video->maxframe;
00311
00312
00313
00314
00315
00316
00317 if(track->frame_offsets)
00318 {
00319 mpeg3_reset_cache(track->frame_cache);
00320
00321 if((frame_number < video->framenum ||
00322 frame_number - video->framenum > MPEG3_SEEK_THRESHOLD))
00323 {
00324 int i;
00325 for(i = track->total_keyframe_numbers - 1; i >= 0; i--)
00326 {
00327 if(track->keyframe_numbers[i] <= frame_number)
00328 {
00329 int frame;
00330 int64_t byte;
00331
00332
00333 if(i > 0) i--;
00334
00335 frame = track->keyframe_numbers[i];
00336 if(frame == 0)
00337 byte = track->frame_offsets[0];
00338 else
00339 byte = track->frame_offsets[frame];
00340 video->framenum = track->keyframe_numbers[i];
00341
00342 mpeg3bits_seek_byte(vstream, byte);
00343
00344
00345
00346 if(byte == 0)
00347 {
00348 mpeg3video_get_firstframe(video);
00349 mpeg3video_read_frame_backend(video, 0);
00350 }
00351
00352
00353
00354 video->repeat_count = 0;
00355
00356
00357 mpeg3video_drop_frames(video, frame_number - video->framenum, 0);
00358 break;
00359 }
00360 }
00361 }
00362 else
00363 {
00364 video->repeat_count = 0;
00365 mpeg3video_drop_frames(video, frame_number - video->framenum, 0);
00366 }
00367 }
00368 else
00369
00370 {
00371 mpeg3video_toc_error();
00372 }
00373
00374
00375
00376 mpeg3demux_reset_pts(demuxer);
00377 }
00378
00379 return result;
00380 }
00381
00382 int mpeg3video_previous_frame(mpeg3video_t *video)
00383 {
00384 mpeg3_bits_t *bitstream = video->vstream;
00385 mpeg3_demuxer_t *demuxer = bitstream->demuxer;
00386 int result = 0;
00387 int64_t target_byte = 0;
00388
00389 if(mpeg3demux_tell_byte(demuxer) <= 0) return 1;
00390
00391
00392 mpeg3demux_start_reverse(demuxer);
00393 result = mpeg3video_prev_code(demuxer, MPEG3_PICTURE_START_CODE);
00394 if(!result) result = mpeg3video_prev_code(demuxer, MPEG3_PICTURE_START_CODE);
00395 if(!result) result = mpeg3video_prev_code(demuxer, MPEG3_PICTURE_START_CODE);
00396 if(!result) target_byte = mpeg3demux_tell_byte(demuxer);
00397
00398
00399
00400 if(!result)
00401 {
00402 if(video->has_gops)
00403 result = mpeg3video_prev_code(demuxer, MPEG3_GOP_START_CODE);
00404 else
00405 result = mpeg3video_prev_code(demuxer, MPEG3_SEQUENCE_START_CODE);
00406 }
00407
00408 if(!result)
00409 {
00410 if(video->has_gops)
00411 result = mpeg3video_prev_code(demuxer, MPEG3_GOP_START_CODE);
00412 else
00413 result = mpeg3video_prev_code(demuxer, MPEG3_SEQUENCE_START_CODE);
00414 }
00415
00416 mpeg3demux_start_forward(demuxer);
00417 mpeg3bits_reset(bitstream);
00418
00419
00420 result = 0;
00421 video->repeat_count = 0;
00422 while(!result &&
00423 !mpeg3demux_eof(demuxer) &&
00424 mpeg3demux_tell_byte(demuxer) < target_byte)
00425 {
00426 result = mpeg3video_read_frame_backend(video, 0);
00427 }
00428
00429 video->repeat_count = 0;
00430 return 0;
00431 }