Browse Source

deps/media-playback: Always check for new frame first

Fixes potential decoding errors with FFmpeg's new decode API.  Because
avcodec_send_packet may process multiple packets, you must call
avcodec_receive_frame continually until no more frames are left.
jp9000 8 years ago
parent
commit
4aea3ce7da
1 changed files with 21 additions and 8 deletions
  1. 21 8
      deps/media-playback/media-playback/decode.c

+ 21 - 8
deps/media-playback/media-playback/decode.c

@@ -210,22 +210,35 @@ static int decode_packet(struct mp_decode *d, int *got_frame)
 	*got_frame = 0;
 
 #ifdef USE_NEW_FFMPEG_DECODE_API
-	ret = avcodec_send_packet(d->decoder, &d->pkt);
+	ret = avcodec_receive_frame(d->decoder, d->frame);
 	if (ret != 0 && ret != AVERROR(EAGAIN)) {
 		if (ret == AVERROR_EOF)
 			ret = 0;
 		return ret;
 	}
 
-	ret = avcodec_receive_frame(d->decoder, d->frame);
-	if (ret != 0 && ret != AVERROR(EAGAIN)) {
-		if (ret == AVERROR_EOF)
-			ret = 0;
-		return ret;
+	if (ret != 0) {
+		ret = avcodec_send_packet(d->decoder, &d->pkt);
+		if (ret != 0 && ret != AVERROR(EAGAIN)) {
+			if (ret == AVERROR_EOF)
+				ret = 0;
+			return ret;
+		}
+
+		ret = avcodec_receive_frame(d->decoder, d->frame);
+		if (ret != 0 && ret != AVERROR(EAGAIN)) {
+			if (ret == AVERROR_EOF)
+				ret = 0;
+			return ret;
+		}
+
+		*got_frame = (ret == 0);
+		ret = d->pkt.size;
+	} else {
+		ret = 0;
+		*got_frame = 1;
 	}
 
-	*got_frame = (ret == 0);
-	ret = d->pkt.size;
 #else
 	if (d->audio) {
 		ret = avcodec_decode_audio4(d->decoder,