mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
per context frame_rate_base, this should finally fix frame_rate related av sync issues
Originally committed as revision 1666 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
586bc7553c
commit
14bea432f1
40
ffmpeg.c
40
ffmpeg.c
@ -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,
|
i, (float)enc->frame_rate / enc->frame_rate_base,
|
||||||
(float)rfps / 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++;
|
||||||
|
17
ffserver.c
17
ffserver.c
@ -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)
|
if (av->frame_rate == 0){
|
||||||
av->frame_rate = 5 * FRAME_RATE_BASE;
|
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) /
|
put_bits(&s->pb, 8, (((int64_t)s->picture_number * 30 * s->avctx->frame_rate_base) /
|
||||||
s->frame_rate) & 0xff);
|
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);
|
int dummy;
|
||||||
if(s->time_increment_resolution>=256*256) s->time_increment_resolution= 256*128;
|
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++) {
|
for(i=1;i<14;i++) {
|
||||||
d = abs(s->frame_rate - frame_rate_tab[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)
|
av_reduce(
|
||||||
s->frame_rate = (s->frame_rate * frame_rate_ext_n) / frame_rate_ext_d;
|
&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) {
|
av_reduce(
|
||||||
/* at least give a valid frame rate (some old mpeg1 have this) */
|
&avctx->frame_rate,
|
||||||
avctx->frame_rate = 25 * FRAME_RATE_BASE;
|
&avctx->frame_rate_base,
|
||||||
} else {
|
frame_rate_tab[s->frame_rate_index],
|
||||||
avctx->frame_rate = frame_rate_tab[s->frame_rate_index];
|
MPEG1_FRAME_RATE_BASE, //FIXME store in allready reduced form
|
||||||
}
|
1<<30
|
||||||
s->frame_rate = avctx->frame_rate;
|
);
|
||||||
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] = {
|
#define MPEG1_FRAME_RATE_BASE 1001
|
||||||
0,
|
|
||||||
24000 * FRAME_RATE_BASE / 1001,
|
static const int frame_rate_tab[16] = {
|
||||||
24000 * FRAME_RATE_BASE / 1000,
|
0,
|
||||||
25000 * FRAME_RATE_BASE / 1000,
|
24000,
|
||||||
30000 * FRAME_RATE_BASE / 1001,
|
24024,
|
||||||
30000 * FRAME_RATE_BASE / 1000,
|
25025,
|
||||||
50000 * FRAME_RATE_BASE / 1000,
|
30000,
|
||||||
60000 * FRAME_RATE_BASE / 1001,
|
30030,
|
||||||
60000 * FRAME_RATE_BASE / 1000,
|
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 *
|
duration = av_rescale(codec->frame_number * codec->frame_rate_base, 10000000, codec->frame_rate);
|
||||||
((int64_t_C(10000000) * FRAME_RATE_BASE) / 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)
|
if(scale && rate){
|
||||||
st->codec.frame_rate= (rate * (uint64_t)FRAME_RATE_BASE + scale/2) / scale;
|
st->codec.frame_rate = rate;
|
||||||
else if(frame_period)
|
st->codec.frame_rate_base= scale;
|
||||||
st->codec.frame_rate = (1000000LL * FRAME_RATE_BASE + frame_period/2) / frame_period;
|
}else if(frame_period){
|
||||||
else
|
st->codec.frame_rate = 1000000;
|
||||||
st->codec.frame_rate = 25 * FRAME_RATE_BASE;
|
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, stream->frame_rate_base); /* scale */
|
||||||
|
put_le32(pb, stream->frame_rate); /* rate */
|
||||||
put_le32(pb, FRAME_RATE_BASE / gcd); /* scale */
|
|
||||||
put_le32(pb, stream->frame_rate / gcd); /* 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, codec->frame_rate_base);
|
||||||
put_be32(pb, FRAME_RATE_BASE / gcd);
|
put_be32(pb, codec->frame_rate);
|
||||||
put_be32(pb, codec->frame_rate / gcd);
|
|
||||||
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);
|
codec->frame_rate_base = get_be32(pb);
|
||||||
rate= get_be32(pb);
|
codec->frame_rate = get_be32(pb);
|
||||||
codec->frame_rate = (rate * (int64_t)FRAME_RATE_BASE) / scale;
|
|
||||||
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)
|
if (!ap || !ap->frame_rate){
|
||||||
st->codec.frame_rate = 25 * FRAME_RATE_BASE;
|
st->codec.frame_rate = 25;
|
||||||
else
|
st->codec.frame_rate_base = 1;
|
||||||
st->codec.frame_rate = ap->frame_rate;
|
}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;
|
st->codec.frame_rate_base = sample_duration ? sample_duration : 1;
|
||||||
if (sample_duration)
|
st->codec.frame_rate = c->streams[c->total_streams]->time_scale;
|
||||||
st->codec.frame_rate /= sample_duration;
|
|
||||||
#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 *
|
av_reduce(
|
||||||
st->codec_info_nb_real_frames) /
|
&st->r_frame_rate,
|
||||||
(st->codec_info_nb_real_frames +
|
&st->r_frame_rate_base,
|
||||||
(st->codec_info_nb_repeat_frames >> 1));
|
(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)
|
if (!st->r_frame_rate){
|
||||||
st->r_frame_rate = st->codec.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 */
|
raten = st->codec.frame_rate; /* this setting should work, but often doesn't */
|
||||||
rated = 1000;
|
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",
|
||||||
|
Loading…
Reference in New Issue
Block a user