---
The previous patch had a bug. At the end of playback it wouldn't
allow seeking.
This updated patch is a little simpler and has better behavior. First of
all, it checks for CODEC_CAP_DELAY so that it doesn't send any empty
packets at EOF if that capability flag is not set. For decoders that do
set CODEC_CAP_DELAY, at the end of playback avplay will loop putting an
empty packet in the queue then reading it from the queue. The empty
packets will only be sent to the decoder if it still has more samples to
send back.
avplay.c | 29 +++++++++++++++++++++++------
1 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/avplay.c b/avplay.c
index 198dce1..5ae38e0 100644
--- a/avplay.c
+++ b/avplay.c
@@ -2008,10 +2008,15 @@ static int audio_decode_frame(VideoState *is, double
*pts_ptr)
AVCodecContext *dec= is->audio_st->codec;
int n, len1, data_size;
double pts;
+ int new_packet = 0;
+ int flush_complete = 0;
for(;;) {
/* NOTE: the audio packet can contain several frames */
- while (pkt_temp->size > 0) {
+ while (pkt_temp->size > 0 || (!pkt_temp->data && new_packet)) {
+ if (flush_complete)
+ break;
+ new_packet = 0;
data_size = sizeof(is->audio_buf1);
len1 = avcodec_decode_audio3(dec,
(int16_t *)is->audio_buf1, &data_size,
@@ -2024,8 +2029,13 @@ static int audio_decode_frame(VideoState *is, double
*pts_ptr)
pkt_temp->data += len1;
pkt_temp->size -= len1;
- if (data_size <= 0)
+
+ if (data_size <= 0) {
+ /* stop sending empty packets if the decoder is finished */
+ if (pkt_temp->size <= 0 && dec->codec->capabilities &
CODEC_CAP_DELAY)
+ flush_complete = 1;
continue;
+ }
if (dec->sample_fmt != is->audio_src_fmt) {
if (is->reformat_ctx)
@@ -2086,12 +2096,11 @@ static int audio_decode_frame(VideoState *is, double
*pts_ptr)
}
/* read next packet */
- if (packet_queue_get(&is->audioq, pkt, 1) < 0)
+ if ((new_packet = packet_queue_get(&is->audioq, pkt, 1)) < 0)
return -1;
- if(pkt->data == flush_pkt.data){
+
+ if (pkt->data == flush_pkt.data)
avcodec_flush_buffers(dec);
- continue;
- }
pkt_temp->data = pkt->data;
pkt_temp->size = pkt->size;
@@ -2508,6 +2517,14 @@ static int decode_thread(void *arg)
pkt->stream_index= is->video_stream;
packet_queue_put(&is->videoq, pkt);
}
+ if (is->audio_stream >= 0 &&
+ is->audio_st->codec->codec->capabilities & CODEC_CAP_DELAY) {
+ av_init_packet(pkt);
+ pkt->data = NULL;
+ pkt->size = 0;
+ pkt->stream_index = is->audio_stream;
+ packet_queue_put(&is->audioq, pkt);
+ }
SDL_Delay(10);
if(is->audioq.size + is->videoq.size + is->subtitleq.size ==0){
if(loop!=1 && (!loop || --loop)){
--
1.7.1
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel