mirror of https://github.com/mpv-player/mpv
encoding -omaxfps: rewrite logic
Now it properly hits the "0 times displayed" case when frames get skipped; this means the candidate frame for the case the next frame is "long" is set properly.
This commit is contained in:
parent
19d80e28e1
commit
3600bf348f
|
@ -48,6 +48,7 @@ struct priv {
|
|||
double lastpts;
|
||||
int64_t lastipts;
|
||||
int64_t lastframeipts;
|
||||
int64_t lastencodedipts;
|
||||
int64_t mindeltapts;
|
||||
double expected_next_pts;
|
||||
mp_image_t *lastimg;
|
||||
|
@ -137,6 +138,7 @@ static int config(struct vo *vo, uint32_t width, uint32_t height,
|
|||
|
||||
vc->lastipts = MP_NOPTS_VALUE;
|
||||
vc->lastframeipts = MP_NOPTS_VALUE;
|
||||
vc->lastencodedipts = MP_NOPTS_VALUE;
|
||||
|
||||
if (pix_fmt == PIX_FMT_NONE)
|
||||
goto error; /* imgfmt2pixfmt already prints something */
|
||||
|
@ -394,19 +396,10 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
|
|||
|
||||
// never-drop mode
|
||||
if (ectx->options->neverdrop && frameipts <= vc->lastipts) {
|
||||
int64_t step = vc->mindeltapts ? vc->mindeltapts : 1;
|
||||
mp_msg(MSGT_ENCODE, MSGL_INFO, "vo-lavc: -oneverdrop increased pts by %d\n",
|
||||
(int) (vc->lastipts - frameipts + 1));
|
||||
frameipts = vc->lastipts + 1;
|
||||
vc->lastpts = frameipts * timeunit - encode_lavc_getoffset(ectx, vc->stream);
|
||||
}
|
||||
|
||||
// lastipts: pts of last vo frame
|
||||
// frameipts: pts of current vo frame
|
||||
// lastframeipts: pts of last ENCODED frame
|
||||
// now we want to go forward in time until at least lastframeipts + mindeltapts
|
||||
// so let's just assume this frame took place at this time or later
|
||||
if (frameipts > vc->lastframeipts && frameipts < vc->lastframeipts + vc->mindeltapts) {
|
||||
frameipts = vc->lastframeipts + vc->mindeltapts;
|
||||
(int) (vc->lastipts - frameipts + step));
|
||||
frameipts = vc->lastipts + step;
|
||||
vc->lastpts = frameipts * timeunit - encode_lavc_getoffset(ectx, vc->stream);
|
||||
}
|
||||
|
||||
|
@ -418,26 +411,36 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
|
|||
int64_t thisduration = vc->harddup ? 1 : (frameipts - vc->lastipts);
|
||||
AVPacket packet;
|
||||
|
||||
avcodec_get_frame_defaults(frame);
|
||||
// we will ONLY encode this frame if it can be encoded at at least
|
||||
// vc->mindeltapts after the last encoded frame!
|
||||
int64_t skipframes =
|
||||
vc->lastencodedipts + vc->mindeltapts - vc->lastipts;
|
||||
if (skipframes < 0)
|
||||
skipframes = 0;
|
||||
|
||||
// this is a nop, unless the worst time base is the STREAM time base
|
||||
frame->pts = av_rescale_q(vc->lastipts, vc->worst_time_base,
|
||||
avc->time_base);
|
||||
if (thisduration > skipframes) {
|
||||
avcodec_get_frame_defaults(frame);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
frame->data[i] = vc->lastimg->planes[i];
|
||||
frame->linesize[i] = vc->lastimg->stride[i];
|
||||
// this is a nop, unless the worst time base is the STREAM time base
|
||||
frame->pts = av_rescale_q(vc->lastipts + skipframes,
|
||||
vc->worst_time_base, avc->time_base);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
frame->data[i] = vc->lastimg->planes[i];
|
||||
frame->linesize[i] = vc->lastimg->stride[i];
|
||||
}
|
||||
frame->quality = avc->global_quality;
|
||||
|
||||
av_init_packet(&packet);
|
||||
packet.data = vc->buffer;
|
||||
packet.size = vc->buffer_size;
|
||||
size = encode_video(vo, frame, &packet);
|
||||
write_packet(vo, size, &packet);
|
||||
++vc->lastdisplaycount;
|
||||
vc->lastencodedipts = vc->lastipts + skipframes;
|
||||
}
|
||||
frame->quality = avc->global_quality;
|
||||
|
||||
av_init_packet(&packet);
|
||||
packet.data = vc->buffer;
|
||||
packet.size = vc->buffer_size;
|
||||
size = encode_video(vo, frame, &packet);
|
||||
write_packet(vo, size, &packet);
|
||||
|
||||
vc->lastipts += thisduration;
|
||||
++vc->lastdisplaycount;
|
||||
}
|
||||
|
||||
avcodec_free_frame(&frame);
|
||||
|
|
Loading…
Reference in New Issue