Always pass 0-sized packets to the decoder, instead of initiating drain
mode.
This fixes behavior with "legitimate" 0-sized packets that appear mid-
stream, and which are _not_ flush packets.
It leaves handling of 0-sized packets loosely defined - this constitutes
an API change, because the user now strictly has to pass NULL to
avcodec_send_packet() to initiate draining correctly.
---
avconv.c | 4 ++--
doc/APIchanges | 4 ++++
libavcodec/avcodec.h | 9 +++++++--
libavcodec/utils.c | 2 +-
4 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/avconv.c b/avconv.c
index 1351cfc..e8f6464 100644
--- a/avconv.c
+++ b/avconv.c
@@ -1118,7 +1118,7 @@ static void do_streamcopy(InputStream *ist, OutputStream
*ost, const AVPacket *p
// This does not quite work like avcodec_decode_audio4/avcodec_decode_video2.
// There is the following difference: if you got a frame, you must call
// it again with pkt=NULL. pkt==NULL is treated differently from pkt.size==0
-// (pkt==NULL means get more output, pkt.size==0 is a flush/drain packet)
+// (pkt==NULL means get more output, pkt.data==NULL is a flush/drain packet)
static int decode(AVCodecContext *avctx, AVFrame *frame, int *got_frame,
AVPacket *pkt)
{
int ret;
@@ -1126,7 +1126,7 @@ static int decode(AVCodecContext *avctx, AVFrame *frame,
int *got_frame, AVPacke
*got_frame = 0;
if (pkt) {
- ret = avcodec_send_packet(avctx, pkt);
+ ret = avcodec_send_packet(avctx, pkt->data ? pkt : NULL);
// In particular, we don't expect AVERROR(EAGAIN), because we read all
// decoded frames with avcodec_receive_frame() until done.
if (ret < 0)
diff --git a/doc/APIchanges b/doc/APIchanges
index c3b81fa..6551522 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -13,6 +13,10 @@ libavutil: 2015-08-28
API changes, most recent first:
+2016-xx-xx - xxxxxxx - lavc 57.xx.0 - avcodec.h
+ Change the semantics of avcodec_send_packet() in cases AVPackets with
+ size=0 are passed to it.
+
2016-xx-xx - xxxxxxx - lavu 55.10.0 - opt.h
Add av_opt_copy().
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 26e6eb3..a10ceaa 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -4222,13 +4222,18 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx,
AVSubtitle *sub,
* and if it contains multiple frames (e.g. some audio
codecs),
* will require you to call avcodec_receive_frame() multiple
* times afterwards before you can send a new packet.
- * It can be NULL (or an AVPacket with data set to NULL and
- * size set to 0); in this case, it is considered a flush
+ * It can be NULL; in this case, it is considered a flush
* packet, which signals the end of the stream. Sending the
* first flush packet will return success. Subsequent ones are
* unnecessary and will return AVERROR_EOF. If the decoder
* still has frames buffered, it will return them after
sending
* a flush packet.
+ * Packets with size set to 0 have loosely defined behavior.
+ * Passing them to this function may or may not result in an
+ * eventual AVERROR_EOF, and (independently from this) may or
+ * may not be interpreted by the decoder as flush packet. You
+ * should avoid trying to send 0-sized packets for flushing;
+ * call the function with a NULL packet instead.
*
* @return 0 on success, otherwise negative error code:
* AVERROR(EAGAIN): input is not accepted right now - the packet must be
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index d42885d..65f601f 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -1727,7 +1727,7 @@ int attribute_align_arg
avcodec_send_packet(AVCodecContext *avctx, const AVPacke
if (avctx->internal->draining)
return AVERROR_EOF;
- if (!avpkt || !avpkt->size) {
+ if (!avpkt) {
avctx->internal->draining = 1;
avpkt = NULL;
--
2.8.1
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel