deps-libff: Add frame dropping
This, if set, instructs the decoders to drop frames if a specific timing window is not met.
This commit is contained in:
parent
6b36d39345
commit
3628d3402d
13
deps/libff/libff/ff-audio-decoder.c
vendored
13
deps/libff/libff/ff-audio-decoder.c
vendored
@ -55,6 +55,17 @@ static bool handle_reset_packet(struct ff_decoder *decoder,
|
||||
return true;
|
||||
}
|
||||
|
||||
static void drop_late_packets(struct ff_decoder *decoder,
|
||||
struct ff_packet *packet)
|
||||
{
|
||||
int64_t start_time = ff_clock_start_time(decoder->clock);
|
||||
if (start_time != AV_NOPTS_VALUE) {
|
||||
if (ff_decoder_set_frame_drop_state(decoder, start_time,
|
||||
packet->base.pts))
|
||||
shrink_packet(packet, packet->base.size);
|
||||
}
|
||||
}
|
||||
|
||||
static int decode_frame(struct ff_decoder *decoder,
|
||||
struct ff_packet *packet, AVFrame *frame, bool *frame_complete)
|
||||
{
|
||||
@ -65,6 +76,8 @@ static int decode_frame(struct ff_decoder *decoder,
|
||||
while (packet->base.size > 0) {
|
||||
int complete;
|
||||
|
||||
drop_late_packets(decoder, packet);
|
||||
|
||||
packet_length = avcodec_decode_audio4(decoder->codec,
|
||||
frame, &complete,
|
||||
&packet->base);
|
||||
|
27
deps/libff/libff/ff-decoder.c
vendored
27
deps/libff/libff/ff-decoder.c
vendored
@ -320,3 +320,30 @@ double ff_decoder_get_best_effort_pts(struct ff_decoder *decoder,
|
||||
|
||||
return d_pts;
|
||||
}
|
||||
|
||||
bool ff_decoder_set_frame_drop_state(struct ff_decoder *decoder,
|
||||
int64_t start_time, int64_t pts)
|
||||
{
|
||||
if (pts != AV_NOPTS_VALUE) {
|
||||
int64_t rescaled_pts = av_rescale_q(pts,
|
||||
decoder->stream->time_base, AV_TIME_BASE_Q);
|
||||
int64_t master_clock = av_gettime() -
|
||||
start_time;
|
||||
|
||||
int64_t diff = master_clock - rescaled_pts;
|
||||
|
||||
if (diff > (AV_TIME_BASE / 2)) {
|
||||
decoder->codec->skip_frame = decoder->frame_drop;
|
||||
decoder->codec->skip_idct = decoder->frame_drop;
|
||||
decoder->codec->skip_loop_filter = decoder->frame_drop;
|
||||
return true;
|
||||
} else {
|
||||
decoder->codec->skip_frame = AVDISCARD_DEFAULT;
|
||||
decoder->codec->skip_idct = AVDISCARD_DEFAULT;
|
||||
decoder->codec->skip_loop_filter = AVDISCARD_DEFAULT;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
4
deps/libff/libff/ff-decoder.h
vendored
4
deps/libff/libff/ff-decoder.h
vendored
@ -44,6 +44,7 @@ struct ff_decoder {
|
||||
int64_t current_pts_time; // clock time when current_pts was set
|
||||
|
||||
bool hwaccel_decoder;
|
||||
enum AVDiscard frame_drop;
|
||||
struct ff_clock *clock;
|
||||
enum ff_av_sync_type natural_sync_clock;
|
||||
|
||||
@ -69,3 +70,6 @@ void ff_decoder_refresh(void *opaque);
|
||||
|
||||
double ff_decoder_get_best_effort_pts(struct ff_decoder *decoder,
|
||||
AVFrame *frame);
|
||||
|
||||
bool ff_decoder_set_frame_drop_state(struct ff_decoder *decoder,
|
||||
int64_t start_time, int64_t pts);
|
||||
|
4
deps/libff/libff/ff-demuxer.c
vendored
4
deps/libff/libff/ff-demuxer.c
vendored
@ -194,6 +194,8 @@ static bool initialize_decoder(struct ff_demuxer *demuxer,
|
||||
demuxer->options.audio_frame_queue_size);
|
||||
|
||||
demuxer->audio_decoder->hwaccel_decoder = hwaccel_decoder;
|
||||
demuxer->audio_decoder->frame_drop =
|
||||
demuxer->options.frame_drop;
|
||||
demuxer->audio_decoder->natural_sync_clock =
|
||||
AV_SYNC_AUDIO_MASTER;
|
||||
demuxer->audio_decoder->callbacks = &demuxer->audio_callbacks;
|
||||
@ -215,6 +217,8 @@ static bool initialize_decoder(struct ff_demuxer *demuxer,
|
||||
demuxer->options.video_frame_queue_size);
|
||||
|
||||
demuxer->video_decoder->hwaccel_decoder = hwaccel_decoder;
|
||||
demuxer->video_decoder->frame_drop =
|
||||
demuxer->options.frame_drop;
|
||||
demuxer->video_decoder->natural_sync_clock =
|
||||
AV_SYNC_VIDEO_MASTER;
|
||||
demuxer->video_decoder->callbacks = &demuxer->video_callbacks;
|
||||
|
1
deps/libff/libff/ff-demuxer.h
vendored
1
deps/libff/libff/ff-demuxer.h
vendored
@ -35,6 +35,7 @@ struct ff_demuxer_options
|
||||
int video_frame_queue_size;
|
||||
bool is_hw_decoding;
|
||||
bool is_looping;
|
||||
enum AVDiscard frame_drop;
|
||||
};
|
||||
|
||||
typedef struct ff_demuxer_options ff_demuxer_options_t;
|
||||
|
15
deps/libff/libff/ff-video-decoder.c
vendored
15
deps/libff/libff/ff-video-decoder.c
vendored
@ -73,6 +73,7 @@ void *ff_video_decoder_thread(void *opaque_video_decoder)
|
||||
int complete;
|
||||
AVFrame *frame = av_frame_alloc();
|
||||
int ret;
|
||||
bool key_frame;
|
||||
|
||||
while (!decoder->abort) {
|
||||
ret = packet_queue_get(&decoder->packet_queue, &packet, 1);
|
||||
@ -95,6 +96,20 @@ void *ff_video_decoder_thread(void *opaque_video_decoder)
|
||||
continue;
|
||||
}
|
||||
|
||||
int64_t start_time = ff_clock_start_time(decoder->clock);
|
||||
key_frame = packet.base.flags & AV_PKT_FLAG_KEY;
|
||||
|
||||
// We can only make decisions on keyframes for
|
||||
// hw decoders (maybe just OSX?)
|
||||
// For now, always make drop decisions on keyframes
|
||||
bool frame_drop_check = key_frame;
|
||||
// Must have a proper packet pts to drop frames here
|
||||
frame_drop_check &= start_time != AV_NOPTS_VALUE;
|
||||
|
||||
if (frame_drop_check)
|
||||
ff_decoder_set_frame_drop_state(decoder,
|
||||
start_time, packet.base.pts);
|
||||
|
||||
avcodec_decode_video2(decoder->codec, frame,
|
||||
&complete, &packet.base);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user