Originally committed as revision 1666 to svn://svn.ffmpeg.org/ffmpeg/trunktags/v0.5
| @@ -90,7 +90,8 @@ static int frame_topBand = 0; | |||||
| static int frame_bottomBand = 0; | static int frame_bottomBand = 0; | ||||
| static int frame_leftBand = 0; | static int frame_leftBand = 0; | ||||
| static int frame_rightBand = 0; | static int frame_rightBand = 0; | ||||
| static int frame_rate = 25 * FRAME_RATE_BASE; | |||||
| static int frame_rate = 25; | |||||
| static int frame_rate_base = 1; | |||||
| static int video_bit_rate = 200*1000; | static int video_bit_rate = 200*1000; | ||||
| static int video_bit_rate_tolerance = 4000*1000; | static int video_bit_rate_tolerance = 4000*1000; | ||||
| static int video_qscale = 0; | static int video_qscale = 0; | ||||
| @@ -746,7 +747,7 @@ static void do_video_stats(AVFormatContext *os, AVOutputStream *ost, | |||||
| if (ti1 < 0.01) | if (ti1 < 0.01) | ||||
| ti1 = 0.01; | ti1 = 0.01; | ||||
| bitrate = (double)(frame_size * 8) * enc->frame_rate / FRAME_RATE_BASE / 1000.0; | |||||
| bitrate = (double)(frame_size * 8) * enc->frame_rate / enc->frame_rate_base / 1000.0; | |||||
| avg_bitrate = (double)(total_size * 8) / ti1 / 1000.0; | avg_bitrate = (double)(total_size * 8) / ti1 / 1000.0; | ||||
| fprintf(fvstats, "s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s ", | fprintf(fvstats, "s_size= %8.0fkB time= %0.3f br= %7.1fkbits/s avg_br= %7.1fkbits/s ", | ||||
| (double)total_size / 1024, ti1, bitrate, avg_bitrate); | (double)total_size / 1024, ti1, bitrate, avg_bitrate); | ||||
| @@ -974,6 +975,7 @@ static int av_encode(AVFormatContext **output_files, | |||||
| break; | break; | ||||
| case CODEC_TYPE_VIDEO: | case CODEC_TYPE_VIDEO: | ||||
| codec->frame_rate = icodec->frame_rate; | codec->frame_rate = icodec->frame_rate; | ||||
| codec->frame_rate_base = icodec->frame_rate_base; | |||||
| codec->width = icodec->width; | codec->width = icodec->width; | ||||
| codec->height = icodec->height; | codec->height = icodec->height; | ||||
| break; | break; | ||||
| @@ -1361,7 +1363,7 @@ static int av_encode(AVFormatContext **output_files, | |||||
| /* frame rate emulation */ | /* frame rate emulation */ | ||||
| if (ist->st->codec.rate_emu) { | if (ist->st->codec.rate_emu) { | ||||
| int64_t pts = ((int64_t) ist->frame * FRAME_RATE_BASE * 1000000) / (ist->st->codec.frame_rate); | |||||
| int64_t pts = av_rescale((int64_t) ist->frame * ist->st->codec.frame_rate_base, 1000000, ist->st->codec.frame_rate); | |||||
| int64_t now = av_gettime() - ist->start; | int64_t now = av_gettime() - ist->start; | ||||
| if (pts > now) | if (pts > now) | ||||
| usleep(pts - now); | usleep(pts - now); | ||||
| @@ -1673,7 +1675,9 @@ static void opt_debug(const char *arg) | |||||
| static void opt_frame_rate(const char *arg) | static void opt_frame_rate(const char *arg) | ||||
| { | { | ||||
| frame_rate = (int)(strtod(arg, 0) * FRAME_RATE_BASE); | |||||
| frame_rate_base = DEFAULT_FRAME_RATE_BASE; //FIXME not optimal | |||||
| frame_rate = (int)(strtod(arg, 0) * frame_rate_base + 0.5); | |||||
| //FIXME parse fractions | |||||
| } | } | ||||
| @@ -2051,7 +2055,7 @@ static void opt_input_file(const char *filename) | |||||
| { | { | ||||
| AVFormatContext *ic; | AVFormatContext *ic; | ||||
| AVFormatParameters params, *ap = ¶ms; | AVFormatParameters params, *ap = ¶ms; | ||||
| int err, i, ret, rfps; | |||||
| int err, i, ret, rfps, rfps_base; | |||||
| if (!strcmp(filename, "-")) | if (!strcmp(filename, "-")) | ||||
| filename = "pipe:"; | filename = "pipe:"; | ||||
| @@ -2061,6 +2065,7 @@ static void opt_input_file(const char *filename) | |||||
| ap->sample_rate = audio_sample_rate; | ap->sample_rate = audio_sample_rate; | ||||
| ap->channels = audio_channels; | ap->channels = audio_channels; | ||||
| ap->frame_rate = frame_rate; | ap->frame_rate = frame_rate; | ||||
| ap->frame_rate_base = frame_rate_base; | |||||
| ap->width = frame_width; | ap->width = frame_width; | ||||
| ap->height = frame_height; | ap->height = frame_height; | ||||
| ap->image_format = image_format; | ap->image_format = image_format; | ||||
| @@ -2092,7 +2097,8 @@ static void opt_input_file(const char *filename) | |||||
| case CODEC_TYPE_VIDEO: | case CODEC_TYPE_VIDEO: | ||||
| frame_height = enc->height; | frame_height = enc->height; | ||||
| frame_width = enc->width; | frame_width = enc->width; | ||||
| rfps = ic->streams[i]->r_frame_rate; | |||||
| rfps = ic->streams[i]->r_frame_rate; | |||||
| rfps_base = ic->streams[i]->r_frame_rate_base; | |||||
| enc->workaround_bugs = workaround_bugs; | enc->workaround_bugs = workaround_bugs; | ||||
| enc->error_resilience = error_resilience; | enc->error_resilience = error_resilience; | ||||
| enc->error_concealment = error_concealment; | enc->error_concealment = error_concealment; | ||||
| @@ -2106,13 +2112,15 @@ static void opt_input_file(const char *filename) | |||||
| if(bitexact) | if(bitexact) | ||||
| enc->flags|= CODEC_FLAG_BITEXACT; | enc->flags|= CODEC_FLAG_BITEXACT; | ||||
| if (enc->frame_rate != rfps) { | |||||
| assert(enc->frame_rate_base == rfps_base); // should be true for now | |||||
| if (enc->frame_rate != rfps) { | |||||
| fprintf(stderr,"\nSeems that stream %d comes from film source: %2.2f->%2.2f\n", | fprintf(stderr,"\nSeems that stream %d comes from film source: %2.2f->%2.2f\n", | ||||
| i, (float)enc->frame_rate / FRAME_RATE_BASE, | |||||
| (float)rfps / FRAME_RATE_BASE); | |||||
| i, (float)enc->frame_rate / enc->frame_rate_base, | |||||
| (float)rfps / rfps_base); | |||||
| } | } | ||||
| /* update the current frame rate to match the stream frame rate */ | /* update the current frame rate to match the stream frame rate */ | ||||
| frame_rate = rfps; | |||||
| frame_rate = rfps; | |||||
| frame_rate_base = rfps_base; | |||||
| enc->rate_emu = rate_emu; | enc->rate_emu = rate_emu; | ||||
| break; | break; | ||||
| @@ -2241,6 +2249,7 @@ static void opt_output_file(const char *filename) | |||||
| video_enc->bit_rate = video_bit_rate; | video_enc->bit_rate = video_bit_rate; | ||||
| video_enc->bit_rate_tolerance = video_bit_rate_tolerance; | video_enc->bit_rate_tolerance = video_bit_rate_tolerance; | ||||
| video_enc->frame_rate = frame_rate; | video_enc->frame_rate = frame_rate; | ||||
| video_enc->frame_rate_base = frame_rate_base; | |||||
| video_enc->width = frame_width; | video_enc->width = frame_width; | ||||
| video_enc->height = frame_height; | video_enc->height = frame_height; | ||||
| @@ -2492,8 +2501,12 @@ static void prepare_grab(void) | |||||
| vp->width = enc->width; | vp->width = enc->width; | ||||
| if (enc->height > vp->height) | if (enc->height > vp->height) | ||||
| vp->height = enc->height; | vp->height = enc->height; | ||||
| if (enc->frame_rate > vp->frame_rate) | |||||
| vp->frame_rate = enc->frame_rate; | |||||
| assert(enc->frame_rate_base == DEFAULT_FRAME_RATE_BASE); | |||||
| if (enc->frame_rate > vp->frame_rate){ | |||||
| vp->frame_rate = enc->frame_rate; | |||||
| vp->frame_rate_base = enc->frame_rate_base; | |||||
| } | |||||
| has_video = 1; | has_video = 1; | ||||
| break; | break; | ||||
| default: | default: | ||||
| @@ -2517,7 +2530,8 @@ static void prepare_grab(void) | |||||
| exit(1); | exit(1); | ||||
| } | } | ||||
| /* by now video grab has one stream */ | /* by now video grab has one stream */ | ||||
| ic->streams[0]->r_frame_rate = vp->frame_rate; | |||||
| ic->streams[0]->r_frame_rate = vp->frame_rate; | |||||
| ic->streams[0]->r_frame_rate_base = vp->frame_rate_base; | |||||
| input_files[nb_input_files] = ic; | input_files[nb_input_files] = ic; | ||||
| dump_format(ic, nb_input_files, "", 0); | dump_format(ic, nb_input_files, "", 0); | ||||
| nb_input_files++; | nb_input_files++; | ||||
| @@ -1725,7 +1725,7 @@ static void compute_stats(HTTPContext *c) | |||||
| case CODEC_TYPE_VIDEO: | case CODEC_TYPE_VIDEO: | ||||
| type = "video"; | type = "video"; | ||||
| sprintf(parameters, "%dx%d, q=%d-%d, fps=%d", st->codec.width, st->codec.height, | sprintf(parameters, "%dx%d, q=%d-%d, fps=%d", st->codec.width, st->codec.height, | ||||
| st->codec.qmin, st->codec.qmax, st->codec.frame_rate / FRAME_RATE_BASE); | |||||
| st->codec.qmin, st->codec.qmax, st->codec.frame_rate / st->codec.frame_rate_base); | |||||
| break; | break; | ||||
| default: | default: | ||||
| av_abort(); | av_abort(); | ||||
| @@ -1950,7 +1950,7 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt) | |||||
| (int64_t)s->pts_num * st->codec.sample_rate); | (int64_t)s->pts_num * st->codec.sample_rate); | ||||
| break; | break; | ||||
| case CODEC_TYPE_VIDEO: | case CODEC_TYPE_VIDEO: | ||||
| st->pts_incr = (int64_t)s->pts_den * FRAME_RATE_BASE; | |||||
| st->pts_incr = (int64_t)s->pts_den * st->codec.frame_rate_base; | |||||
| av_frac_init(&st->pts, st->pts.val, 0, | av_frac_init(&st->pts, st->pts.val, 0, | ||||
| (int64_t)s->pts_num * st->codec.frame_rate); | (int64_t)s->pts_num * st->codec.frame_rate); | ||||
| break; | break; | ||||
| @@ -2018,7 +2018,7 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt) | |||||
| (int64_t)s->pts_num * st->codec.sample_rate); | (int64_t)s->pts_num * st->codec.sample_rate); | ||||
| break; | break; | ||||
| case CODEC_TYPE_VIDEO: | case CODEC_TYPE_VIDEO: | ||||
| st->pts_incr = (int64_t)s->pts_den * FRAME_RATE_BASE; | |||||
| st->pts_incr = (int64_t)s->pts_den * st->codec.frame_rate_base; | |||||
| av_frac_init(&st->pts, st->pts.val, 0, | av_frac_init(&st->pts, st->pts.val, 0, | ||||
| (int64_t)s->pts_num * st->codec.frame_rate); | (int64_t)s->pts_num * st->codec.frame_rate); | ||||
| break; | break; | ||||
| @@ -3219,6 +3219,7 @@ static int add_av_stream(FFStream *feed, AVStream *st) | |||||
| if (av1->width == av->width && | if (av1->width == av->width && | ||||
| av1->height == av->height && | av1->height == av->height && | ||||
| av1->frame_rate == av->frame_rate && | av1->frame_rate == av->frame_rate && | ||||
| av1->frame_rate_base == av->frame_rate_base && | |||||
| av1->gop_size == av->gop_size) | av1->gop_size == av->gop_size) | ||||
| goto found; | goto found; | ||||
| break; | break; | ||||
| @@ -3406,6 +3407,7 @@ static void build_feed_streams(void) | |||||
| matches = 0; | matches = 0; | ||||
| } else if (ccf->codec_type == CODEC_TYPE_VIDEO) { | } else if (ccf->codec_type == CODEC_TYPE_VIDEO) { | ||||
| if (CHECK_CODEC(frame_rate) || | if (CHECK_CODEC(frame_rate) || | ||||
| CHECK_CODEC(frame_rate_base) || | |||||
| CHECK_CODEC(width) || | CHECK_CODEC(width) || | ||||
| CHECK_CODEC(height)) { | CHECK_CODEC(height)) { | ||||
| printf("Codec width, height and framerate do not match for stream %d\n", i); | printf("Codec width, height and framerate do not match for stream %d\n", i); | ||||
| @@ -3553,8 +3555,10 @@ static void add_codec(FFStream *stream, AVCodecContext *av) | |||||
| case CODEC_TYPE_VIDEO: | case CODEC_TYPE_VIDEO: | ||||
| if (av->bit_rate == 0) | if (av->bit_rate == 0) | ||||
| av->bit_rate = 64000; | av->bit_rate = 64000; | ||||
| if (av->frame_rate == 0) | |||||
| av->frame_rate = 5 * FRAME_RATE_BASE; | |||||
| if (av->frame_rate == 0){ | |||||
| av->frame_rate = 5; | |||||
| av->frame_rate_base = 1; | |||||
| } | |||||
| if (av->width == 0 || av->height == 0) { | if (av->width == 0 || av->height == 0) { | ||||
| av->width = 160; | av->width = 160; | ||||
| av->height = 128; | av->height = 128; | ||||
| @@ -4017,7 +4021,8 @@ static int parse_ffconfig(const char *filename) | |||||
| } else if (!strcasecmp(cmd, "VideoFrameRate")) { | } else if (!strcasecmp(cmd, "VideoFrameRate")) { | ||||
| get_arg(arg, sizeof(arg), &p); | get_arg(arg, sizeof(arg), &p); | ||||
| if (stream) { | if (stream) { | ||||
| video_enc.frame_rate = (int)(strtod(arg, NULL) * FRAME_RATE_BASE); | |||||
| video_enc.frame_rate_base= DEFAULT_FRAME_RATE_BASE; | |||||
| video_enc.frame_rate = (int)(strtod(arg, NULL) * video_enc.frame_rate_base); | |||||
| } | } | ||||
| } else if (!strcasecmp(cmd, "VideoGopSize")) { | } else if (!strcasecmp(cmd, "VideoGopSize")) { | ||||
| get_arg(arg, sizeof(arg), &p); | get_arg(arg, sizeof(arg), &p); | ||||
| @@ -192,7 +192,8 @@ void video_encode_example(const char *filename) | |||||
| c->width = 352; | c->width = 352; | ||||
| c->height = 288; | c->height = 288; | ||||
| /* frames per second */ | /* frames per second */ | ||||
| c->frame_rate = 25 * FRAME_RATE_BASE; | |||||
| c->frame_rate = 25; | |||||
| c->frame_rate_base= 1; | |||||
| c->gop_size = 10; /* emit one intra frame every ten frames */ | c->gop_size = 10; /* emit one intra frame every ten frames */ | ||||
| /* open it */ | /* open it */ | ||||
| @@ -186,8 +186,6 @@ static const int Motion_Est_QTab[] = { ME_ZERO, ME_PHODS, ME_LOG, | |||||
| #define CODEC_CAP_PARSE_ONLY 0x0004 | #define CODEC_CAP_PARSE_ONLY 0x0004 | ||||
| #define CODEC_CAP_TRUNCATED 0x0008 | #define CODEC_CAP_TRUNCATED 0x0008 | ||||
| #define FRAME_RATE_BASE 10010 | |||||
| #define FF_COMMON_FRAME \ | #define FF_COMMON_FRAME \ | ||||
| uint8_t *data[4];\ | uint8_t *data[4];\ | ||||
| int linesize[4];\ | int linesize[4];\ | ||||
| @@ -321,6 +319,7 @@ typedef struct AVFrame { | |||||
| FF_COMMON_FRAME | FF_COMMON_FRAME | ||||
| } AVFrame; | } AVFrame; | ||||
| #define DEFAULT_FRAME_RATE_BASE 1001000 | |||||
| /** | /** | ||||
| * main external api structure. | * main external api structure. | ||||
| @@ -375,13 +374,21 @@ typedef struct AVCodecContext { | |||||
| /* video only */ | /* video only */ | ||||
| /** | /** | ||||
| * frames per sec multiplied by FRAME_RATE_BASE. | |||||
| * frames per sec multiplied by frame_rate_base. | |||||
| * for variable fps this is the precission, so if the timestamps | * for variable fps this is the precission, so if the timestamps | ||||
| * can be specified in msec precssion then this is 1000*FRAME_RATE_BASE | |||||
| * can be specified in msec precssion then this is 1000*frame_rate_base | |||||
| * - encoding: MUST be set by user | * - encoding: MUST be set by user | ||||
| * - decoding: set by lavc. 0 or the frame_rate if available | * - decoding: set by lavc. 0 or the frame_rate if available | ||||
| */ | */ | ||||
| int frame_rate; | int frame_rate; | ||||
| /** | |||||
| * frame_rate_base. | |||||
| * for variable fps this is 1 | |||||
| * - encoding: set by user. | |||||
| * - decoding: set by lavc. | |||||
| */ | |||||
| int frame_rate_base; | |||||
| /** | /** | ||||
| * width / height. | * width / height. | ||||
| @@ -1258,6 +1265,20 @@ void avcodec_register_all(void); | |||||
| void avcodec_flush_buffers(AVCodecContext *avctx); | void avcodec_flush_buffers(AVCodecContext *avctx); | ||||
| /* misc usefull functions */ | |||||
| /** | |||||
| * reduce a fraction. | |||||
| * this is usefull for framerate calculations | |||||
| * @param max the maximum allowed for dst_nom & dst_den | |||||
| * @return 1 if exact, 0 otherwise | |||||
| */ | |||||
| int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max); | |||||
| /** | |||||
| * rescale a 64bit integer. | |||||
| * a simple a*b/c isnt possible as it can overflow | |||||
| */ | |||||
| int64_t av_rescale(int64_t a, int b, int c); | |||||
| /** | /** | ||||
| @@ -341,7 +341,7 @@ void free_vlc(VLC *vlc) | |||||
| av_free(vlc->table); | av_free(vlc->table); | ||||
| } | } | ||||
| int ff_gcd(int a, int b){ | |||||
| int64_t ff_gcd(int64_t a, int64_t b){ | |||||
| if(b) return ff_gcd(b, a%b); | if(b) return ff_gcd(b, a%b); | ||||
| else return a; | else return a; | ||||
| } | } | ||||
| @@ -876,7 +876,7 @@ static inline int clip(int a, int amin, int amax) | |||||
| /* math */ | /* math */ | ||||
| extern const uint8_t ff_sqrt_tab[128]; | extern const uint8_t ff_sqrt_tab[128]; | ||||
| int ff_gcd(int a, int b); | |||||
| int64_t ff_gcd(int64_t a, int64_t b); | |||||
| static inline int ff_sqrt(int a) | static inline int ff_sqrt(int a) | ||||
| { | { | ||||
| @@ -537,16 +537,17 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, | |||||
| /* init size */ | /* init size */ | ||||
| width = 720; | width = 720; | ||||
| if (dsf) { | if (dsf) { | ||||
| avctx->frame_rate = 25 * FRAME_RATE_BASE; | |||||
| avctx->frame_rate = 25; | |||||
| packet_size = PAL_FRAME_SIZE; | packet_size = PAL_FRAME_SIZE; | ||||
| height = 576; | height = 576; | ||||
| nb_dif_segs = 12; | nb_dif_segs = 12; | ||||
| } else { | } else { | ||||
| avctx->frame_rate = 30 * FRAME_RATE_BASE; | |||||
| avctx->frame_rate = 30; | |||||
| packet_size = NTSC_FRAME_SIZE; | packet_size = NTSC_FRAME_SIZE; | ||||
| height = 480; | height = 480; | ||||
| nb_dif_segs = 10; | nb_dif_segs = 10; | ||||
| } | } | ||||
| avctx->frame_rate_base= 1; | |||||
| /* NOTE: we only accept several full frames */ | /* NOTE: we only accept several full frames */ | ||||
| if (buf_size < packet_size) | if (buf_size < packet_size) | ||||
| return -1; | return -1; | ||||
| @@ -164,8 +164,8 @@ void h263_encode_picture_header(MpegEncContext * s, int picture_number) | |||||
| s->gob_number = 0; | s->gob_number = 0; | ||||
| put_bits(&s->pb, 22, 0x20); /* PSC */ | put_bits(&s->pb, 22, 0x20); /* PSC */ | ||||
| put_bits(&s->pb, 8, (((int64_t)s->picture_number * 30 * FRAME_RATE_BASE) / | |||||
| s->frame_rate) & 0xff); | |||||
| put_bits(&s->pb, 8, (((int64_t)s->picture_number * 30 * s->avctx->frame_rate_base) / | |||||
| s->avctx->frame_rate) & 0xff); | |||||
| put_bits(&s->pb, 1, 1); /* marker */ | put_bits(&s->pb, 1, 1); /* marker */ | ||||
| put_bits(&s->pb, 1, 0); /* h263 id */ | put_bits(&s->pb, 1, 0); /* h263 id */ | ||||
| @@ -1587,16 +1587,16 @@ void ff_set_mpeg4_time(MpegEncContext * s, int picture_number){ | |||||
| int time_div, time_mod; | int time_div, time_mod; | ||||
| if(s->pict_type==I_TYPE){ //we will encode a vol header | if(s->pict_type==I_TYPE){ //we will encode a vol header | ||||
| s->time_increment_resolution= s->frame_rate/ff_gcd(s->frame_rate, FRAME_RATE_BASE); | |||||
| if(s->time_increment_resolution>=256*256) s->time_increment_resolution= 256*128; | |||||
| int dummy; | |||||
| av_reduce(&s->time_increment_resolution, &dummy, s->avctx->frame_rate, s->avctx->frame_rate_base, (1<<16)-1); | |||||
| s->time_increment_bits = av_log2(s->time_increment_resolution - 1) + 1; | s->time_increment_bits = av_log2(s->time_increment_resolution - 1) + 1; | ||||
| } | } | ||||
| if(s->current_picture.pts) | if(s->current_picture.pts) | ||||
| s->time= (s->current_picture.pts*s->time_increment_resolution + 500*1000)/(1000*1000); | s->time= (s->current_picture.pts*s->time_increment_resolution + 500*1000)/(1000*1000); | ||||
| else | else | ||||
| s->time= picture_number*(int64_t)FRAME_RATE_BASE*s->time_increment_resolution/s->frame_rate; | |||||
| s->time= av_rescale(picture_number*(int64_t)s->avctx->frame_rate_base, s->time_increment_resolution, s->avctx->frame_rate); | |||||
| time_div= s->time/s->time_increment_resolution; | time_div= s->time/s->time_increment_resolution; | ||||
| time_mod= s->time%s->time_increment_resolution; | time_mod= s->time%s->time_increment_resolution; | ||||
| @@ -203,8 +203,10 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s) | |||||
| int i, dmin, d; | int i, dmin, d; | ||||
| s->frame_rate_index = 0; | s->frame_rate_index = 0; | ||||
| dmin = 0x7fffffff; | dmin = 0x7fffffff; | ||||
| for(i=1;i<9;i++) { | |||||
| d = abs(s->frame_rate - frame_rate_tab[i]); | |||||
| for(i=1;i<14;i++) { | |||||
| if(s->avctx->strict_std_compliance >= 0 && i>=9) break; | |||||
| d = abs(MPEG1_FRAME_RATE_BASE*(int64_t)s->avctx->frame_rate/s->avctx->frame_rate_base - frame_rate_tab[i]); | |||||
| if (d < dmin) { | if (d < dmin) { | ||||
| dmin = d; | dmin = d; | ||||
| s->frame_rate_index = i; | s->frame_rate_index = i; | ||||
| @@ -248,22 +250,22 @@ static void mpeg1_encode_sequence_header(MpegEncContext *s) | |||||
| /* time code : we must convert from the real frame rate to a | /* time code : we must convert from the real frame rate to a | ||||
| fake mpeg frame rate in case of low frame rate */ | fake mpeg frame rate in case of low frame rate */ | ||||
| fps = frame_rate_tab[s->frame_rate_index]; | fps = frame_rate_tab[s->frame_rate_index]; | ||||
| time_code = (int64_t)s->fake_picture_number * FRAME_RATE_BASE; | |||||
| time_code = (int64_t)s->fake_picture_number * MPEG1_FRAME_RATE_BASE; | |||||
| s->gop_picture_number = s->fake_picture_number; | s->gop_picture_number = s->fake_picture_number; | ||||
| put_bits(&s->pb, 5, (uint32_t)((time_code / (fps * 3600)) % 24)); | put_bits(&s->pb, 5, (uint32_t)((time_code / (fps * 3600)) % 24)); | ||||
| put_bits(&s->pb, 6, (uint32_t)((time_code / (fps * 60)) % 60)); | put_bits(&s->pb, 6, (uint32_t)((time_code / (fps * 60)) % 60)); | ||||
| put_bits(&s->pb, 1, 1); | put_bits(&s->pb, 1, 1); | ||||
| put_bits(&s->pb, 6, (uint32_t)((time_code / fps) % 60)); | put_bits(&s->pb, 6, (uint32_t)((time_code / fps) % 60)); | ||||
| put_bits(&s->pb, 6, (uint32_t)((time_code % fps) / FRAME_RATE_BASE)); | |||||
| put_bits(&s->pb, 6, (uint32_t)((time_code % fps) / MPEG1_FRAME_RATE_BASE)); | |||||
| put_bits(&s->pb, 1, 1); /* closed gop */ | put_bits(&s->pb, 1, 1); /* closed gop */ | ||||
| put_bits(&s->pb, 1, 0); /* broken link */ | put_bits(&s->pb, 1, 0); /* broken link */ | ||||
| } | } | ||||
| if (s->frame_rate < (24 * FRAME_RATE_BASE) && s->picture_number > 0) { | |||||
| if (s->avctx->frame_rate < (24 * s->avctx->frame_rate_base) && s->picture_number > 0) { | |||||
| /* insert empty P pictures to slow down to the desired | /* insert empty P pictures to slow down to the desired | ||||
| frame rate. Each fake pictures takes about 20 bytes */ | frame rate. Each fake pictures takes about 20 bytes */ | ||||
| fps = frame_rate_tab[s->frame_rate_index]; | fps = frame_rate_tab[s->frame_rate_index]; | ||||
| n = (((int64_t)s->picture_number * fps) / s->frame_rate) - 1; | |||||
| n = av_rescale((int64_t)s->picture_number * s->avctx->frame_rate_base, fps, s->avctx->frame_rate) / MPEG1_FRAME_RATE_BASE - 1; | |||||
| while (s->fake_picture_number < n) { | while (s->fake_picture_number < n) { | ||||
| mpeg1_skip_picture(s, s->fake_picture_number - | mpeg1_skip_picture(s, s->fake_picture_number - | ||||
| s->gop_picture_number); | s->gop_picture_number); | ||||
| @@ -1638,8 +1640,13 @@ static void mpeg_decode_sequence_extension(MpegEncContext *s) | |||||
| s->low_delay = get_bits1(&s->gb); | s->low_delay = get_bits1(&s->gb); | ||||
| frame_rate_ext_n = get_bits(&s->gb, 2); | frame_rate_ext_n = get_bits(&s->gb, 2); | ||||
| frame_rate_ext_d = get_bits(&s->gb, 5); | frame_rate_ext_d = get_bits(&s->gb, 5); | ||||
| if (frame_rate_ext_d >= 1) | |||||
| s->frame_rate = (s->frame_rate * frame_rate_ext_n) / frame_rate_ext_d; | |||||
| av_reduce( | |||||
| &s->avctx->frame_rate, | |||||
| &s->avctx->frame_rate_base, | |||||
| frame_rate_tab[s->frame_rate_index] * (frame_rate_ext_n+1), | |||||
| MPEG1_FRAME_RATE_BASE * (frame_rate_ext_d+1), | |||||
| 1<<30); | |||||
| dprintf("sequence extension\n"); | dprintf("sequence extension\n"); | ||||
| s->mpeg2 = 1; | s->mpeg2 = 1; | ||||
| s->avctx->sub_id = 2; /* indicates mpeg2 found */ | s->avctx->sub_id = 2; /* indicates mpeg2 found */ | ||||
| @@ -1990,13 +1997,13 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, | |||||
| s->avctx = avctx; | s->avctx = avctx; | ||||
| avctx->width = width; | avctx->width = width; | ||||
| avctx->height = height; | avctx->height = height; | ||||
| if (s->frame_rate_index >= 9) { | |||||
| /* at least give a valid frame rate (some old mpeg1 have this) */ | |||||
| avctx->frame_rate = 25 * FRAME_RATE_BASE; | |||||
| } else { | |||||
| avctx->frame_rate = frame_rate_tab[s->frame_rate_index]; | |||||
| } | |||||
| s->frame_rate = avctx->frame_rate; | |||||
| av_reduce( | |||||
| &avctx->frame_rate, | |||||
| &avctx->frame_rate_base, | |||||
| frame_rate_tab[s->frame_rate_index], | |||||
| MPEG1_FRAME_RATE_BASE, //FIXME store in allready reduced form | |||||
| 1<<30 | |||||
| ); | |||||
| avctx->bit_rate = s->bit_rate; | avctx->bit_rate = s->bit_rate; | ||||
| if (MPV_common_init(s) < 0) | if (MPV_common_init(s) < 0) | ||||
| @@ -385,16 +385,28 @@ static const uint8_t mbMotionVectorTable[17][2] = { | |||||
| { 0xc, 10 }, | { 0xc, 10 }, | ||||
| }; | }; | ||||
| static const int frame_rate_tab[9] = { | |||||
| 0, | |||||
| 24000 * FRAME_RATE_BASE / 1001, | |||||
| 24000 * FRAME_RATE_BASE / 1000, | |||||
| 25000 * FRAME_RATE_BASE / 1000, | |||||
| 30000 * FRAME_RATE_BASE / 1001, | |||||
| 30000 * FRAME_RATE_BASE / 1000, | |||||
| 50000 * FRAME_RATE_BASE / 1000, | |||||
| 60000 * FRAME_RATE_BASE / 1001, | |||||
| 60000 * FRAME_RATE_BASE / 1000, | |||||
| #define MPEG1_FRAME_RATE_BASE 1001 | |||||
| static const int frame_rate_tab[16] = { | |||||
| 0, | |||||
| 24000, | |||||
| 24024, | |||||
| 25025, | |||||
| 30000, | |||||
| 30030, | |||||
| 50050, | |||||
| 60000, | |||||
| 60060, | |||||
| // Xing's 15fps: (9) | |||||
| 15015, | |||||
| // libmpeg3's "Unofficial economy rates": (10-13) | |||||
| 5005, | |||||
| 10010, | |||||
| 12012, | |||||
| 15015, | |||||
| // random, just to avoid segfault !never encode these | |||||
| 25025, | |||||
| 25025, | |||||
| }; | }; | ||||
| static const uint8_t non_linear_qscale[32] = { | static const uint8_t non_linear_qscale[32] = { | ||||
| @@ -504,7 +504,6 @@ int MPV_encode_init(AVCodecContext *avctx) | |||||
| s->bit_rate = avctx->bit_rate; | s->bit_rate = avctx->bit_rate; | ||||
| s->bit_rate_tolerance = avctx->bit_rate_tolerance; | s->bit_rate_tolerance = avctx->bit_rate_tolerance; | ||||
| s->frame_rate = avctx->frame_rate; | |||||
| s->width = avctx->width; | s->width = avctx->width; | ||||
| s->height = avctx->height; | s->height = avctx->height; | ||||
| if(avctx->gop_size > 600){ | if(avctx->gop_size > 600){ | ||||
| @@ -557,7 +556,8 @@ int MPV_encode_init(AVCodecContext *avctx) | |||||
| switch(avctx->codec->id) { | switch(avctx->codec->id) { | ||||
| case CODEC_ID_MPEG1VIDEO: | case CODEC_ID_MPEG1VIDEO: | ||||
| s->out_format = FMT_MPEG1; | s->out_format = FMT_MPEG1; | ||||
| avctx->delay=0; //FIXME not sure, should check the spec | |||||
| s->low_delay= 0; //s->max_b_frames ? 0 : 1; | |||||
| avctx->delay= s->low_delay ? 0 : (s->max_b_frames + 1); | |||||
| break; | break; | ||||
| case CODEC_ID_MJPEG: | case CODEC_ID_MJPEG: | ||||
| s->out_format = FMT_MJPEG; | s->out_format = FMT_MJPEG; | ||||
| @@ -192,7 +192,6 @@ typedef struct MpegEncContext { | |||||
| /* the following parameters must be initialized before encoding */ | /* the following parameters must be initialized before encoding */ | ||||
| int width, height;///< picture size. must be a multiple of 16 | int width, height;///< picture size. must be a multiple of 16 | ||||
| int gop_size; | int gop_size; | ||||
| int frame_rate; ///< number of frames per second | |||||
| int intra_only; ///< if true, only intra pictures are generated | int intra_only; ///< if true, only intra pictures are generated | ||||
| int bit_rate; ///< wanted bit rate | int bit_rate; ///< wanted bit rate | ||||
| int bit_rate_tolerance; ///< amount of +- bits (>0) | int bit_rate_tolerance; ///< amount of +- bits (>0) | ||||
| @@ -435,7 +435,7 @@ void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number) | |||||
| void msmpeg4_encode_ext_header(MpegEncContext * s) | void msmpeg4_encode_ext_header(MpegEncContext * s) | ||||
| { | { | ||||
| put_bits(&s->pb, 5, s->frame_rate / FRAME_RATE_BASE); //yes 29.97 -> 29 | |||||
| put_bits(&s->pb, 5, s->avctx->frame_rate / s->avctx->frame_rate_base); //yes 29.97 -> 29 | |||||
| put_bits(&s->pb, 11, FFMIN(s->bit_rate/1024, 2047)); | put_bits(&s->pb, 11, FFMIN(s->bit_rate/1024, 2047)); | ||||
| @@ -164,7 +164,7 @@ int ff_rate_control_init(MpegEncContext *s) | |||||
| bits= rce.i_tex_bits + rce.p_tex_bits; | bits= rce.i_tex_bits + rce.p_tex_bits; | ||||
| q= get_qscale(s, &rce, rcc->pass1_wanted_bits/rcc->pass1_rc_eq_output_sum, i); | q= get_qscale(s, &rce, rcc->pass1_wanted_bits/rcc->pass1_rc_eq_output_sum, i); | ||||
| rcc->pass1_wanted_bits+= s->bit_rate/(s->frame_rate / (double)FRAME_RATE_BASE); | |||||
| rcc->pass1_wanted_bits+= s->bit_rate/(s->avctx->frame_rate / (double)s->avctx->frame_rate_base); | |||||
| } | } | ||||
| } | } | ||||
| @@ -197,7 +197,7 @@ static inline double bits2qp(RateControlEntry *rce, double bits){ | |||||
| static void update_rc_buffer(MpegEncContext *s, int frame_size){ | static void update_rc_buffer(MpegEncContext *s, int frame_size){ | ||||
| RateControlContext *rcc= &s->rc_context; | RateControlContext *rcc= &s->rc_context; | ||||
| const double fps= (double)s->frame_rate / FRAME_RATE_BASE; | |||||
| const double fps= (double)s->avctx->frame_rate / (double)s->avctx->frame_rate_base; | |||||
| const double buffer_size= s->avctx->rc_buffer_size; | const double buffer_size= s->avctx->rc_buffer_size; | ||||
| const double min_rate= s->avctx->rc_min_rate/fps; | const double min_rate= s->avctx->rc_min_rate/fps; | ||||
| const double max_rate= s->avctx->rc_max_rate/fps; | const double max_rate= s->avctx->rc_max_rate/fps; | ||||
| @@ -571,7 +571,7 @@ float ff_rate_estimate_qscale(MpegEncContext *s) | |||||
| get_qminmax(&qmin, &qmax, s, pict_type); | get_qminmax(&qmin, &qmax, s, pict_type); | ||||
| fps= (double)s->frame_rate / FRAME_RATE_BASE; | |||||
| fps= (double)s->avctx->frame_rate / (double)s->avctx->frame_rate_base; | |||||
| //printf("input_pic_num:%d pic_num:%d frame_rate:%d\n", s->input_picture_number, s->picture_number, s->frame_rate); | //printf("input_pic_num:%d pic_num:%d frame_rate:%d\n", s->input_picture_number, s->picture_number, s->frame_rate); | ||||
| /* update predictors */ | /* update predictors */ | ||||
| if(picture_number>2){ | if(picture_number>2){ | ||||
| @@ -698,7 +698,7 @@ static int init_pass2(MpegEncContext *s) | |||||
| { | { | ||||
| RateControlContext *rcc= &s->rc_context; | RateControlContext *rcc= &s->rc_context; | ||||
| int i; | int i; | ||||
| double fps= (double)s->frame_rate / FRAME_RATE_BASE; | |||||
| double fps= (double)s->avctx->frame_rate / (double)s->avctx->frame_rate_base; | |||||
| double complexity[5]={0,0,0,0,0}; // aproximate bits at quant=1 | double complexity[5]={0,0,0,0,0}; // aproximate bits at quant=1 | ||||
| double avg_quantizer[5]; | double avg_quantizer[5]; | ||||
| uint64_t const_bits[5]={0,0,0,0,0}; // quantizer idependant bits | uint64_t const_bits[5]={0,0,0,0,0}; // quantizer idependant bits | ||||
| @@ -236,7 +236,8 @@ void avcodec_get_context_defaults(AVCodecContext *s){ | |||||
| s->error_concealment= 3; | s->error_concealment= 3; | ||||
| s->error_resilience= 1; | s->error_resilience= 1; | ||||
| s->workaround_bugs= FF_BUG_AUTODETECT; | s->workaround_bugs= FF_BUG_AUTODETECT; | ||||
| s->frame_rate = 25 * FRAME_RATE_BASE; | |||||
| s->frame_rate_base= 1; | |||||
| s->frame_rate = 25; | |||||
| s->gop_size= 50; | s->gop_size= 50; | ||||
| s->me_method= ME_EPZS; | s->me_method= ME_EPZS; | ||||
| s->get_buffer= avcodec_default_get_buffer; | s->get_buffer= avcodec_default_get_buffer; | ||||
| @@ -463,7 +464,7 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) | |||||
| snprintf(buf + strlen(buf), buf_size - strlen(buf), | snprintf(buf + strlen(buf), buf_size - strlen(buf), | ||||
| ", %dx%d, %0.2f fps", | ", %dx%d, %0.2f fps", | ||||
| enc->width, enc->height, | enc->width, enc->height, | ||||
| (float)enc->frame_rate / FRAME_RATE_BASE); | |||||
| (float)enc->frame_rate / enc->frame_rate_base); | |||||
| } | } | ||||
| if (encode) { | if (encode) { | ||||
| snprintf(buf + strlen(buf), buf_size - strlen(buf), | snprintf(buf + strlen(buf), buf_size - strlen(buf), | ||||
| @@ -588,6 +589,65 @@ void avcodec_flush_buffers(AVCodecContext *avctx) | |||||
| } | } | ||||
| } | } | ||||
| int av_reduce(int *dst_nom, int *dst_den, int64_t nom, int64_t den, int64_t max){ | |||||
| int exact=1, sign=0; | |||||
| int64_t gcd, larger; | |||||
| assert(den != 0); | |||||
| if(den < 0){ | |||||
| den= -den; | |||||
| nom= -nom; | |||||
| } | |||||
| if(nom < 0){ | |||||
| nom= -nom; | |||||
| sign= 1; | |||||
| } | |||||
| for(;;){ //note is executed 1 or 2 times | |||||
| gcd = ff_gcd(nom, den); | |||||
| nom /= gcd; | |||||
| den /= gcd; | |||||
| larger= FFMAX(nom, den); | |||||
| if(larger > max){ | |||||
| int64_t div= (larger + max - 1) / max; | |||||
| nom = (nom + div/2)/div; | |||||
| den = (den + div/2)/div; | |||||
| exact=0; | |||||
| }else | |||||
| break; | |||||
| } | |||||
| if(sign) nom= -nom; | |||||
| *dst_nom = nom; | |||||
| *dst_den = den; | |||||
| return exact; | |||||
| } | |||||
| int64_t av_rescale(int64_t a, int b, int c){ | |||||
| uint64_t h, l; | |||||
| assert(c > 0); | |||||
| assert(b >=0); | |||||
| if(a<0) return -av_rescale(-a, b, c); | |||||
| h= a>>32; | |||||
| if(h==0) return a*b/c; | |||||
| l= a&0xFFFFFFFF; | |||||
| l *= b; | |||||
| h *= b; | |||||
| l += (h%c)<<32; | |||||
| return ((h/c)<<32) + l/c; | |||||
| } | |||||
| static int raw_encode_init(AVCodecContext *s) | static int raw_encode_init(AVCodecContext *s) | ||||
| { | { | ||||
| return 0; | return 0; | ||||
| @@ -66,7 +66,7 @@ static int encode_ext_header(Wmv2Context *w){ | |||||
| init_put_bits(&pb, s->avctx->extradata, s->avctx->extradata_size, NULL, NULL); | init_put_bits(&pb, s->avctx->extradata, s->avctx->extradata_size, NULL, NULL); | ||||
| put_bits(&pb, 5, s->frame_rate / FRAME_RATE_BASE); //yes 29.97 -> 29 | |||||
| put_bits(&pb, 5, s->avctx->frame_rate / s->avctx->frame_rate_base); //yes 29.97 -> 29 | |||||
| put_bits(&pb, 11, FFMIN(s->bit_rate/1024, 2047)); | put_bits(&pb, 11, FFMIN(s->bit_rate/1024, 2047)); | ||||
| put_bits(&pb, 1, w->mspel_bit=1); | put_bits(&pb, 1, w->mspel_bit=1); | ||||
| @@ -621,8 +621,7 @@ static int asf_write_packet(AVFormatContext *s, int stream_index, | |||||
| duration = (codec->frame_number * codec->frame_size * int64_t_C(10000000)) / | duration = (codec->frame_number * codec->frame_size * int64_t_C(10000000)) / | ||||
| codec->sample_rate; | codec->sample_rate; | ||||
| } else { | } else { | ||||
| duration = codec->frame_number * | |||||
| ((int64_t_C(10000000) * FRAME_RATE_BASE) / codec->frame_rate); | |||||
| duration = av_rescale(codec->frame_number * codec->frame_rate_base, 10000000, codec->frame_rate); | |||||
| } | } | ||||
| if (duration > asf->duration) | if (duration > asf->duration) | ||||
| asf->duration = duration; | asf->duration = duration; | ||||
| @@ -77,6 +77,7 @@ typedef struct AVProbeData { | |||||
| typedef struct AVFormatParameters { | typedef struct AVFormatParameters { | ||||
| int frame_rate; | int frame_rate; | ||||
| int frame_rate_base; | |||||
| int sample_rate; | int sample_rate; | ||||
| int channels; | int channels; | ||||
| int width; | int width; | ||||
| @@ -159,6 +160,7 @@ typedef struct AVStream { | |||||
| int id; /* format specific stream id */ | int id; /* format specific stream id */ | ||||
| AVCodecContext codec; /* codec context */ | AVCodecContext codec; /* codec context */ | ||||
| int r_frame_rate; /* real frame rate of the stream */ | int r_frame_rate; /* real frame rate of the stream */ | ||||
| int r_frame_rate_base;/* real frame rate base of the stream */ | |||||
| uint64_t time_length; /* real length of the stream in miliseconds */ | uint64_t time_length; /* real length of the stream in miliseconds */ | ||||
| void *priv_data; | void *priv_data; | ||||
| /* internal data used in av_find_stream_info() */ | /* internal data used in av_find_stream_info() */ | ||||
| @@ -332,8 +334,6 @@ extern AVOutputFormat yuv4mpegpipe_oformat; | |||||
| #define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24)) | #define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24)) | ||||
| #define MKBETAG(a,b,c,d) (d | (c << 8) | (b << 16) | (a << 24)) | #define MKBETAG(a,b,c,d) (d | (c << 8) | (b << 16) | (a << 24)) | ||||
| int av_gcd(int a, int b); | |||||
| void av_register_input_format(AVInputFormat *format); | void av_register_input_format(AVInputFormat *format); | ||||
| void av_register_output_format(AVOutputFormat *format); | void av_register_output_format(AVOutputFormat *format); | ||||
| AVOutputFormat *guess_stream_format(const char *short_name, | AVOutputFormat *guess_stream_format(const char *short_name, | ||||
| @@ -133,12 +133,16 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||||
| scale= get_le32(pb); /* scale */ | scale= get_le32(pb); /* scale */ | ||||
| rate= get_le32(pb); /* rate */ | rate= get_le32(pb); /* rate */ | ||||
| if(scale && rate) | |||||
| st->codec.frame_rate= (rate * (uint64_t)FRAME_RATE_BASE + scale/2) / scale; | |||||
| else if(frame_period) | |||||
| st->codec.frame_rate = (1000000LL * FRAME_RATE_BASE + frame_period/2) / frame_period; | |||||
| else | |||||
| st->codec.frame_rate = 25 * FRAME_RATE_BASE; | |||||
| if(scale && rate){ | |||||
| st->codec.frame_rate = rate; | |||||
| st->codec.frame_rate_base= scale; | |||||
| }else if(frame_period){ | |||||
| st->codec.frame_rate = 1000000; | |||||
| st->codec.frame_rate_base= frame_period; | |||||
| }else{ | |||||
| st->codec.frame_rate = 25; | |||||
| st->codec.frame_rate_base = 1; | |||||
| } | |||||
| url_fskip(pb, size - 7 * 4); | url_fskip(pb, size - 7 * 4); | ||||
| break; | break; | ||||
| @@ -218,7 +218,7 @@ static int avi_write_header(AVFormatContext *s) | |||||
| nb_frames = 0; | nb_frames = 0; | ||||
| if(video_enc){ | if(video_enc){ | ||||
| put_le32(pb, (uint32_t)(int64_t_C(1000000) * FRAME_RATE_BASE / video_enc->frame_rate)); | |||||
| put_le32(pb, (uint32_t)(int64_t_C(1000000) * video_enc->frame_rate_base / video_enc->frame_rate)); | |||||
| } else { | } else { | ||||
| put_le32(pb, 0); | put_le32(pb, 0); | ||||
| } | } | ||||
| @@ -244,8 +244,6 @@ static int avi_write_header(AVFormatContext *s) | |||||
| /* stream list */ | /* stream list */ | ||||
| for(i=0;i<n;i++) { | for(i=0;i<n;i++) { | ||||
| int gcd; | |||||
| list2 = start_tag(pb, "LIST"); | list2 = start_tag(pb, "LIST"); | ||||
| put_tag(pb, "strl"); | put_tag(pb, "strl"); | ||||
| @@ -262,10 +260,8 @@ static int avi_write_header(AVFormatContext *s) | |||||
| put_le16(pb, 0); /* language */ | put_le16(pb, 0); /* language */ | ||||
| put_le32(pb, 0); /* initial frame */ | put_le32(pb, 0); /* initial frame */ | ||||
| gcd= av_gcd(stream->frame_rate, FRAME_RATE_BASE); | |||||
| put_le32(pb, FRAME_RATE_BASE / gcd); /* scale */ | |||||
| put_le32(pb, stream->frame_rate / gcd); /* rate */ | |||||
| put_le32(pb, stream->frame_rate_base); /* scale */ | |||||
| put_le32(pb, stream->frame_rate); /* rate */ | |||||
| put_le32(pb, 0); /* start */ | put_le32(pb, 0); /* start */ | ||||
| avi->frames_hdr_strm[i] = url_ftell(pb); /* remember this offset to fill later */ | avi->frames_hdr_strm[i] = url_ftell(pb); /* remember this offset to fill later */ | ||||
| @@ -138,7 +138,8 @@ static int dv1394_read_header(AVFormatContext * context, AVFormatParameters * ap | |||||
| vst->codec.codec_id = CODEC_ID_DVVIDEO; | vst->codec.codec_id = CODEC_ID_DVVIDEO; | ||||
| vst->codec.width = dv->width; | vst->codec.width = dv->width; | ||||
| vst->codec.height = dv->height; | vst->codec.height = dv->height; | ||||
| vst->codec.frame_rate = dv->frame_rate * FRAME_RATE_BASE; | |||||
| vst->codec.frame_rate = dv->frame_rate; | |||||
| vst->codec.frame_rate_base = 1; | |||||
| vst->codec.bit_rate = 25000000; /* Consumer DV is 25Mbps */ | vst->codec.bit_rate = 25000000; /* Consumer DV is 25Mbps */ | ||||
| ast->codec.codec_type = CODEC_TYPE_AUDIO; | ast->codec.codec_type = CODEC_TYPE_AUDIO; | ||||
| @@ -140,8 +140,6 @@ static int ffm_write_header(AVFormatContext *s) | |||||
| /* list of streams */ | /* list of streams */ | ||||
| for(i=0;i<s->nb_streams;i++) { | for(i=0;i<s->nb_streams;i++) { | ||||
| int gcd; | |||||
| st = s->streams[i]; | st = s->streams[i]; | ||||
| fst = av_mallocz(sizeof(FFMStream)); | fst = av_mallocz(sizeof(FFMStream)); | ||||
| if (!fst) | if (!fst) | ||||
| @@ -158,9 +156,8 @@ static int ffm_write_header(AVFormatContext *s) | |||||
| /* specific info */ | /* specific info */ | ||||
| switch(codec->codec_type) { | switch(codec->codec_type) { | ||||
| case CODEC_TYPE_VIDEO: | case CODEC_TYPE_VIDEO: | ||||
| gcd= av_gcd(FRAME_RATE_BASE, codec->frame_rate); | |||||
| put_be32(pb, FRAME_RATE_BASE / gcd); | |||||
| put_be32(pb, codec->frame_rate / gcd); | |||||
| put_be32(pb, codec->frame_rate_base); | |||||
| put_be32(pb, codec->frame_rate); | |||||
| put_be16(pb, codec->width); | put_be16(pb, codec->width); | ||||
| put_be16(pb, codec->height); | put_be16(pb, codec->height); | ||||
| put_be16(pb, codec->gop_size); | put_be16(pb, codec->gop_size); | ||||
| @@ -229,7 +226,7 @@ static int ffm_write_packet(AVFormatContext *s, int stream_index, | |||||
| if (st->codec.codec_type == CODEC_TYPE_AUDIO) { | if (st->codec.codec_type == CODEC_TYPE_AUDIO) { | ||||
| duration = ((float)st->codec.frame_size / st->codec.sample_rate * 1000000.0); | duration = ((float)st->codec.frame_size / st->codec.sample_rate * 1000000.0); | ||||
| } else { | } else { | ||||
| duration = (1000000.0 * FRAME_RATE_BASE / (float)st->codec.frame_rate); | |||||
| duration = (1000000.0 * st->codec.frame_rate_base / (float)st->codec.frame_rate); | |||||
| } | } | ||||
| pts = fst->pts; | pts = fst->pts; | ||||
| @@ -394,7 +391,6 @@ static int ffm_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||||
| /* read each stream */ | /* read each stream */ | ||||
| for(i=0;i<s->nb_streams;i++) { | for(i=0;i<s->nb_streams;i++) { | ||||
| char rc_eq_buf[128]; | char rc_eq_buf[128]; | ||||
| int rate, scale; | |||||
| st = av_mallocz(sizeof(AVStream)); | st = av_mallocz(sizeof(AVStream)); | ||||
| if (!st) | if (!st) | ||||
| @@ -416,9 +412,8 @@ static int ffm_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||||
| /* specific info */ | /* specific info */ | ||||
| switch(codec->codec_type) { | switch(codec->codec_type) { | ||||
| case CODEC_TYPE_VIDEO: | case CODEC_TYPE_VIDEO: | ||||
| scale= get_be32(pb); | |||||
| rate= get_be32(pb); | |||||
| codec->frame_rate = (rate * (int64_t)FRAME_RATE_BASE) / scale; | |||||
| codec->frame_rate_base = get_be32(pb); | |||||
| codec->frame_rate = get_be32(pb); | |||||
| codec->width = get_be16(pb); | codec->width = get_be16(pb); | ||||
| codec->height = get_be16(pb); | codec->height = get_be16(pb); | ||||
| codec->gop_size = get_be16(pb); | codec->gop_size = get_be16(pb); | ||||
| @@ -296,7 +296,7 @@ static int gif_write_header(AVFormatContext *s) | |||||
| GIFContext *gif = s->priv_data; | GIFContext *gif = s->priv_data; | ||||
| ByteIOContext *pb = &s->pb; | ByteIOContext *pb = &s->pb; | ||||
| AVCodecContext *enc, *video_enc; | AVCodecContext *enc, *video_enc; | ||||
| int i, width, height, rate; | |||||
| int i, width, height/*, rate*/; | |||||
| /* XXX: do we reject audio streams or just ignore them ? | /* XXX: do we reject audio streams or just ignore them ? | ||||
| if(s->nb_streams > 1) | if(s->nb_streams > 1) | ||||
| @@ -318,7 +318,7 @@ static int gif_write_header(AVFormatContext *s) | |||||
| } else { | } else { | ||||
| width = video_enc->width; | width = video_enc->width; | ||||
| height = video_enc->height; | height = video_enc->height; | ||||
| rate = video_enc->frame_rate; | |||||
| // rate = video_enc->frame_rate; | |||||
| } | } | ||||
| /* XXX: is it allowed ? seems to work so far... */ | /* XXX: is it allowed ? seems to work so far... */ | ||||
| @@ -351,7 +351,7 @@ static int gif_write_video(AVFormatContext *s, | |||||
| /* XXX: should use delay, in order to be more accurate */ | /* XXX: should use delay, in order to be more accurate */ | ||||
| /* instead of using the same rounded value each time */ | /* instead of using the same rounded value each time */ | ||||
| /* XXX: don't even remember if I really use it for now */ | /* XXX: don't even remember if I really use it for now */ | ||||
| jiffies = (70*FRAME_RATE_BASE/enc->frame_rate) - 1; | |||||
| jiffies = (70*enc->frame_rate_base/enc->frame_rate) - 1; | |||||
| put_le16(pb, jiffies); | put_le16(pb, jiffies); | ||||
| @@ -535,7 +535,8 @@ static int gif_read_header(AVFormatContext * s1, | |||||
| st->codec.codec_type = CODEC_TYPE_VIDEO; | st->codec.codec_type = CODEC_TYPE_VIDEO; | ||||
| st->codec.codec_id = CODEC_ID_RAWVIDEO; | st->codec.codec_id = CODEC_ID_RAWVIDEO; | ||||
| st->codec.frame_rate = 5 * FRAME_RATE_BASE; | |||||
| st->codec.frame_rate = 5; | |||||
| st->codec.frame_rate_base = 1; | |||||
| /* XXX: check if screen size is always valid */ | /* XXX: check if screen size is always valid */ | ||||
| st->codec.width = s->screen_width; | st->codec.width = s->screen_width; | ||||
| st->codec.height = s->screen_height; | st->codec.height = s->screen_height; | ||||
| @@ -31,6 +31,7 @@ typedef struct { | |||||
| int use_mmap; | int use_mmap; | ||||
| int width, height; | int width, height; | ||||
| int frame_rate; | int frame_rate; | ||||
| int frame_rate_base; | |||||
| int64_t time_frame; | int64_t time_frame; | ||||
| int frame_size; | int frame_size; | ||||
| struct video_capability video_cap; | struct video_capability video_cap; | ||||
| @@ -59,7 +60,7 @@ static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap) | |||||
| AVStream *st; | AVStream *st; | ||||
| int width, height; | int width, height; | ||||
| int video_fd, frame_size; | int video_fd, frame_size; | ||||
| int ret, frame_rate; | |||||
| int ret, frame_rate, frame_rate_base; | |||||
| int desired_palette; | int desired_palette; | ||||
| struct video_audio audio; | struct video_audio audio; | ||||
| const char *video_device; | const char *video_device; | ||||
| @@ -69,7 +70,8 @@ static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap) | |||||
| width = ap->width; | width = ap->width; | ||||
| height = ap->height; | height = ap->height; | ||||
| frame_rate = ap->frame_rate; | |||||
| frame_rate = ap->frame_rate; | |||||
| frame_rate_base = ap->frame_rate_base; | |||||
| st = av_new_stream(s1, 0); | st = av_new_stream(s1, 0); | ||||
| if (!st) | if (!st) | ||||
| @@ -77,7 +79,8 @@ static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap) | |||||
| s->width = width; | s->width = width; | ||||
| s->height = height; | s->height = height; | ||||
| s->frame_rate = frame_rate; | |||||
| s->frame_rate = frame_rate; | |||||
| s->frame_rate_base = frame_rate_base; | |||||
| video_device = ap->device; | video_device = ap->device; | ||||
| if (!video_device) | if (!video_device) | ||||
| @@ -240,7 +243,8 @@ static int grab_read_header(AVFormatContext *s1, AVFormatParameters *ap) | |||||
| st->codec.codec_id = CODEC_ID_RAWVIDEO; | st->codec.codec_id = CODEC_ID_RAWVIDEO; | ||||
| st->codec.width = width; | st->codec.width = width; | ||||
| st->codec.height = height; | st->codec.height = height; | ||||
| st->codec.frame_rate = frame_rate; | |||||
| st->codec.frame_rate = frame_rate; | |||||
| st->codec.frame_rate_base = frame_rate_base; | |||||
| av_set_pts_info(s1, 48, 1, 1000000); /* 48 bits pts in us */ | av_set_pts_info(s1, 48, 1, 1000000); /* 48 bits pts in us */ | ||||
| @@ -283,7 +287,7 @@ static int grab_read_packet(AVFormatContext *s1, AVPacket *pkt) | |||||
| VideoData *s = s1->priv_data; | VideoData *s = s1->priv_data; | ||||
| int64_t curtime, delay; | int64_t curtime, delay; | ||||
| struct timespec ts; | struct timespec ts; | ||||
| int64_t per_frame = (int64_t_C(1000000) * FRAME_RATE_BASE) / s->frame_rate; | |||||
| int64_t per_frame = (int64_t_C(1000000) * s->frame_rate_base) / s->frame_rate; | |||||
| /* Calculate the time of the next frame */ | /* Calculate the time of the next frame */ | ||||
| s->time_frame += per_frame; | s->time_frame += per_frame; | ||||
| @@ -124,10 +124,13 @@ static int img_read_header(AVFormatContext *s1, AVFormatParameters *ap) | |||||
| st->codec.pix_fmt = s->pix_fmt; | st->codec.pix_fmt = s->pix_fmt; | ||||
| s->img_size = avpicture_get_size(s->pix_fmt, s->width, s->height); | s->img_size = avpicture_get_size(s->pix_fmt, s->width, s->height); | ||||
| if (!ap || !ap->frame_rate) | |||||
| st->codec.frame_rate = 25 * FRAME_RATE_BASE; | |||||
| else | |||||
| st->codec.frame_rate = ap->frame_rate; | |||||
| if (!ap || !ap->frame_rate){ | |||||
| st->codec.frame_rate = 25; | |||||
| st->codec.frame_rate_base = 1; | |||||
| }else{ | |||||
| st->codec.frame_rate = ap->frame_rate; | |||||
| st->codec.frame_rate_base = ap->frame_rate_base; | |||||
| } | |||||
| return 0; | return 0; | ||||
| fail1: | fail1: | ||||
| @@ -182,7 +185,7 @@ static int img_read_packet(AVFormatContext *s1, AVPacket *pkt) | |||||
| av_free_packet(pkt); | av_free_packet(pkt); | ||||
| return -EIO; /* signal EOF */ | return -EIO; /* signal EOF */ | ||||
| } else { | } else { | ||||
| pkt->pts = ((int64_t)s->img_number * s1->pts_den * FRAME_RATE_BASE) / (s1->streams[0]->codec.frame_rate * s1->pts_num); | |||||
| pkt->pts = av_rescale((int64_t)s->img_number * s1->streams[0]->codec.frame_rate_base, s1->pts_den, s1->streams[0]->codec.frame_rate) / s1->pts_num; | |||||
| s->img_number++; | s->img_number++; | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -686,7 +686,8 @@ static int parse_stsd(const MOVParseTableEntry *parse_table, ByteIOContext *pb, | |||||
| get_be16(pb); /* depth */ | get_be16(pb); /* depth */ | ||||
| get_be16(pb); /* colortable id */ | get_be16(pb); /* colortable id */ | ||||
| st->codec.frame_rate = 25 * FRAME_RATE_BASE; | |||||
| st->codec.frame_rate = 25; | |||||
| st->codec.frame_rate_base = 1; | |||||
| size -= (16+8*4+2+32+2*2); | size -= (16+8*4+2+32+2*2); | ||||
| while (size >= 8) { | while (size >= 8) { | ||||
| @@ -932,9 +933,8 @@ printf("track[%i].stts.entries = %i\n", c->fc->nb_streams-1, entries); | |||||
| sample_duration = get_be32(pb); | sample_duration = get_be32(pb); | ||||
| if (!i && st->codec.codec_type==CODEC_TYPE_VIDEO) { | if (!i && st->codec.codec_type==CODEC_TYPE_VIDEO) { | ||||
| st->codec.frame_rate = FRAME_RATE_BASE * c->streams[c->total_streams]->time_scale; | |||||
| if (sample_duration) | |||||
| st->codec.frame_rate /= sample_duration; | |||||
| st->codec.frame_rate_base = sample_duration ? sample_duration : 1; | |||||
| st->codec.frame_rate = c->streams[c->total_streams]->time_scale; | |||||
| #ifdef DEBUG | #ifdef DEBUG | ||||
| printf("VIDEO FRAME RATE= %i (sd= %i)\n", st->codec.frame_rate, sample_duration); | printf("VIDEO FRAME RATE= %i (sd= %i)\n", st->codec.frame_rate, sample_duration); | ||||
| #endif | #endif | ||||
| @@ -61,7 +61,8 @@ static int raw_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||||
| st->codec.channels = ap->channels; | st->codec.channels = ap->channels; | ||||
| break; | break; | ||||
| case CODEC_TYPE_VIDEO: | case CODEC_TYPE_VIDEO: | ||||
| st->codec.frame_rate = ap->frame_rate; | |||||
| st->codec.frame_rate = ap->frame_rate; | |||||
| st->codec.frame_rate_base = ap->frame_rate_base; | |||||
| st->codec.width = ap->width; | st->codec.width = ap->width; | ||||
| st->codec.height = ap->height; | st->codec.height = ap->height; | ||||
| break; | break; | ||||
| @@ -151,9 +152,11 @@ static int video_read_header(AVFormatContext *s, | |||||
| /* for mpeg4 specify it too (most mpeg4 streams dont have the fixed_vop_rate set ...)*/ | /* for mpeg4 specify it too (most mpeg4 streams dont have the fixed_vop_rate set ...)*/ | ||||
| if (st->codec.codec_id == CODEC_ID_MJPEG || st->codec.codec_id == CODEC_ID_MPEG4) { | if (st->codec.codec_id == CODEC_ID_MJPEG || st->codec.codec_id == CODEC_ID_MPEG4) { | ||||
| if (ap) { | if (ap) { | ||||
| st->codec.frame_rate = ap->frame_rate; | |||||
| st->codec.frame_rate = ap->frame_rate; | |||||
| st->codec.frame_rate_base = ap->frame_rate_base; | |||||
| } else { | } else { | ||||
| st->codec.frame_rate = 25 * FRAME_RATE_BASE; | |||||
| st->codec.frame_rate = 25; | |||||
| st->codec.frame_rate_base = 1; | |||||
| } | } | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| @@ -306,7 +306,7 @@ static int rm_write_header(AVFormatContext *s) | |||||
| break; | break; | ||||
| case CODEC_TYPE_VIDEO: | case CODEC_TYPE_VIDEO: | ||||
| rm->video_stream = stream; | rm->video_stream = stream; | ||||
| stream->frame_rate = (float)codec->frame_rate / (float)FRAME_RATE_BASE; | |||||
| stream->frame_rate = (float)codec->frame_rate / (float)codec->frame_rate_base; | |||||
| /* XXX: dummy values */ | /* XXX: dummy values */ | ||||
| stream->packet_max_size = 4096; | stream->packet_max_size = 4096; | ||||
| stream->nb_packets = 0; | stream->nb_packets = 0; | ||||
| @@ -582,7 +582,8 @@ static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||||
| goto fail1; | goto fail1; | ||||
| st->codec.width = get_be16(pb); | st->codec.width = get_be16(pb); | ||||
| st->codec.height = get_be16(pb); | st->codec.height = get_be16(pb); | ||||
| st->codec.frame_rate = get_be16(pb) * FRAME_RATE_BASE; | |||||
| st->codec.frame_rate_base= 1; | |||||
| st->codec.frame_rate = get_be16(pb) * st->codec.frame_rate_base; | |||||
| st->codec.codec_type = CODEC_TYPE_VIDEO; | st->codec.codec_type = CODEC_TYPE_VIDEO; | ||||
| get_be32(pb); | get_be32(pb); | ||||
| get_be16(pb); | get_be16(pb); | ||||
| @@ -560,9 +560,8 @@ static void rtp_send_mpegvideo(AVFormatContext *s1, | |||||
| q += len; | q += len; | ||||
| /* 90 KHz time stamp */ | /* 90 KHz time stamp */ | ||||
| /* XXX: overflow */ | |||||
| s->timestamp = s->base_timestamp + | s->timestamp = s->base_timestamp + | ||||
| (s->cur_timestamp * 90000LL * FRAME_RATE_BASE) / st->codec.frame_rate; | |||||
| av_rescale((int64_t)s->cur_timestamp * st->codec.frame_rate_base, 90000, st->codec.frame_rate); | |||||
| rtp_send_data(s1, s->buf, q - s->buf); | rtp_send_data(s1, s->buf, q - s->buf); | ||||
| buf1 += len; | buf1 += len; | ||||
| @@ -586,9 +585,8 @@ static void rtp_send_raw(AVFormatContext *s1, | |||||
| len = size; | len = size; | ||||
| /* 90 KHz time stamp */ | /* 90 KHz time stamp */ | ||||
| /* XXX: overflow */ | |||||
| s->timestamp = s->base_timestamp + | s->timestamp = s->base_timestamp + | ||||
| (s->cur_timestamp * 90000LL * FRAME_RATE_BASE) / st->codec.frame_rate; | |||||
| av_rescale((int64_t)s->cur_timestamp * st->codec.frame_rate_base, 90000, st->codec.frame_rate); | |||||
| rtp_send_data(s1, buf1, len); | rtp_send_data(s1, buf1, len); | ||||
| buf1 += len; | buf1 += len; | ||||
| @@ -194,7 +194,7 @@ static int swf_write_header(AVFormatContext *s) | |||||
| AVCodecContext *enc, *audio_enc, *video_enc; | AVCodecContext *enc, *audio_enc, *video_enc; | ||||
| PutBitContext p; | PutBitContext p; | ||||
| uint8_t buf1[256]; | uint8_t buf1[256]; | ||||
| int i, width, height, rate; | |||||
| int i, width, height, rate, rate_base; | |||||
| swf = av_malloc(sizeof(SWFContext)); | swf = av_malloc(sizeof(SWFContext)); | ||||
| if (!swf) | if (!swf) | ||||
| @@ -215,11 +215,13 @@ static int swf_write_header(AVFormatContext *s) | |||||
| /* currenty, cannot work correctly if audio only */ | /* currenty, cannot work correctly if audio only */ | ||||
| width = 320; | width = 320; | ||||
| height = 200; | height = 200; | ||||
| rate = 10 * FRAME_RATE_BASE; | |||||
| rate = 10; | |||||
| rate_base= 1; | |||||
| } else { | } else { | ||||
| width = video_enc->width; | width = video_enc->width; | ||||
| height = video_enc->height; | height = video_enc->height; | ||||
| rate = video_enc->frame_rate; | rate = video_enc->frame_rate; | ||||
| rate_base = video_enc->frame_rate_base; | |||||
| } | } | ||||
| put_tag(pb, "FWS"); | put_tag(pb, "FWS"); | ||||
| @@ -228,9 +230,9 @@ static int swf_write_header(AVFormatContext *s) | |||||
| (will be patched if not streamed) */ | (will be patched if not streamed) */ | ||||
| put_swf_rect(pb, 0, width, 0, height); | put_swf_rect(pb, 0, width, 0, height); | ||||
| put_le16(pb, (rate * 256) / FRAME_RATE_BASE); /* frame rate */ | |||||
| put_le16(pb, (rate * 256) / rate_base); /* frame rate */ | |||||
| swf->duration_pos = url_ftell(pb); | swf->duration_pos = url_ftell(pb); | ||||
| put_le16(pb, (uint16_t)(DUMMY_DURATION * (int64_t)rate / FRAME_RATE_BASE)); /* frame count */ | |||||
| put_le16(pb, (uint16_t)(DUMMY_DURATION * (int64_t)rate / rate_base)); /* frame count */ | |||||
| /* define a shape with the jpeg inside */ | /* define a shape with the jpeg inside */ | ||||
| @@ -305,7 +307,7 @@ static int swf_write_header(AVFormatContext *s) | |||||
| put_swf_tag(s, TAG_STREAMHEAD); | put_swf_tag(s, TAG_STREAMHEAD); | ||||
| put_byte(&s->pb, 0); | put_byte(&s->pb, 0); | ||||
| put_byte(&s->pb, v); | put_byte(&s->pb, v); | ||||
| put_le16(&s->pb, (audio_enc->sample_rate * FRAME_RATE_BASE) / rate); /* avg samples per frame */ | |||||
| put_le16(&s->pb, (audio_enc->sample_rate * rate_base) / rate); /* avg samples per frame */ | |||||
| put_swf_end_tag(s); | put_swf_end_tag(s); | ||||
| @@ -614,10 +614,12 @@ int av_find_stream_info(AVFormatContext *ic) | |||||
| #endif | #endif | ||||
| /* stop after 40 frames */ | /* stop after 40 frames */ | ||||
| if (st->codec_info_nb_real_frames >= 40) { | if (st->codec_info_nb_real_frames >= 40) { | ||||
| st->r_frame_rate = (st->codec.frame_rate * | |||||
| st->codec_info_nb_real_frames) / | |||||
| (st->codec_info_nb_real_frames + | |||||
| (st->codec_info_nb_repeat_frames >> 1)); | |||||
| av_reduce( | |||||
| &st->r_frame_rate, | |||||
| &st->r_frame_rate_base, | |||||
| (int64_t)st->codec.frame_rate * st->codec_info_nb_real_frames, | |||||
| st->codec_info_nb_real_frames + (st->codec_info_nb_repeat_frames >> 1), | |||||
| 1<<30); | |||||
| goto close_codec; | goto close_codec; | ||||
| } | } | ||||
| } else { | } else { | ||||
| @@ -645,8 +647,10 @@ int av_find_stream_info(AVFormatContext *ic) | |||||
| for(i=0;i<ic->nb_streams;i++) { | for(i=0;i<ic->nb_streams;i++) { | ||||
| st = ic->streams[i]; | st = ic->streams[i]; | ||||
| if (st->codec.codec_type == CODEC_TYPE_VIDEO) { | if (st->codec.codec_type == CODEC_TYPE_VIDEO) { | ||||
| if (!st->r_frame_rate) | |||||
| st->r_frame_rate = st->codec.frame_rate; | |||||
| if (!st->r_frame_rate){ | |||||
| st->r_frame_rate = st->codec.frame_rate; | |||||
| st->r_frame_rate_base = st->codec.frame_rate_base; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -820,7 +824,7 @@ int av_write_frame(AVFormatContext *s, int stream_index, const uint8_t *buf, | |||||
| break; | break; | ||||
| case CODEC_TYPE_VIDEO: | case CODEC_TYPE_VIDEO: | ||||
| av_frac_add(&st->pts, | av_frac_add(&st->pts, | ||||
| (int64_t)s->pts_den * FRAME_RATE_BASE); | |||||
| (int64_t)s->pts_den * st->codec.frame_rate_base); | |||||
| break; | break; | ||||
| default: | default: | ||||
| break; | break; | ||||
| @@ -1316,11 +1320,6 @@ void av_frac_add(AVFrac *f, int64_t incr) | |||||
| f->num = num; | f->num = num; | ||||
| } | } | ||||
| int av_gcd(int a, int b){ | |||||
| if(b) return av_gcd(b, a%b); | |||||
| else return a; | |||||
| } | |||||
| /** | /** | ||||
| * register a new image format | * register a new image format | ||||
| * @param img_fmt Image format descriptor | * @param img_fmt Image format descriptor | ||||
| @@ -26,7 +26,7 @@ static int yuv4_write_header(AVFormatContext *s) | |||||
| { | { | ||||
| AVStream *st; | AVStream *st; | ||||
| int width, height; | int width, height; | ||||
| int raten, rated, aspectn, aspectd, fps, fps1, n; | |||||
| int raten, rated, aspectn, aspectd, fps, fps1, n, gcd; | |||||
| char buf[Y4M_LINE_MAX+1]; | char buf[Y4M_LINE_MAX+1]; | ||||
| if (s->nb_streams != 1) | if (s->nb_streams != 1) | ||||
| @@ -35,9 +35,13 @@ static int yuv4_write_header(AVFormatContext *s) | |||||
| st = s->streams[0]; | st = s->streams[0]; | ||||
| width = st->codec.width; | width = st->codec.width; | ||||
| height = st->codec.height; | height = st->codec.height; | ||||
| #if 1 | |||||
| //this is identical to the code below for exact fps | |||||
| av_reduce(&raten, &rated, st->codec.frame_rate, st->codec.frame_rate_base, (1UL<<31)-1); | |||||
| #else | |||||
| fps = st->codec.frame_rate; | fps = st->codec.frame_rate; | ||||
| fps1 = (((float)fps / FRAME_RATE_BASE) * 1000); | |||||
| fps1 = (((float)fps / st->codec.frame_rate_base) * 1000); | |||||
| /* Sorry about this messy code, but mpeg2enc is very picky about | /* Sorry about this messy code, but mpeg2enc is very picky about | ||||
| * the framerates it accepts. */ | * the framerates it accepts. */ | ||||
| @@ -75,13 +79,17 @@ static int yuv4_write_header(AVFormatContext *s) | |||||
| rated = 1; | rated = 1; | ||||
| break; | break; | ||||
| default: | default: | ||||
| raten = fps1; /* this setting should work, but often doesn't */ | |||||
| rated = 1000; | |||||
| raten = st->codec.frame_rate; /* this setting should work, but often doesn't */ | |||||
| rated = st->codec.frame_rate_base; | |||||
| gcd= av_gcd(raten, rated); | |||||
| raten /= gcd; | |||||
| rated /= gcd; | |||||
| break; | break; | ||||
| } | } | ||||
| #endif | |||||
| aspectn = 1; | aspectn = 1; | ||||
| aspectd = 1; /* ffmpeg always uses a 1:1 aspect ratio */ | |||||
| aspectd = 1; /* ffmpeg always uses a 1:1 aspect ratio */ //FIXME not true anymore | |||||
| /* construct stream header, if this is the first frame */ | /* construct stream header, if this is the first frame */ | ||||
| n = snprintf(buf, sizeof(buf), "%s W%d H%d F%d:%d I%s A%d:%d\n", | n = snprintf(buf, sizeof(buf), "%s W%d H%d F%d:%d I%s A%d:%d\n", | ||||