On Sat, 18 Mar 2017, wal...@free.fr wrote:

The logs:  http://pastebin.com/1duYR0Ui


Log with video only (run ffplay with -an -sn) might show it more clearly, but even from the logs above it looks like the CrystalHD codec is returning EAGAINs at the same time for both receive_frame and send_packet. If it indeed does work in ffmpeg, then I suspect a lot of busy waiting there. Philip, you mind taking a look? :)

Thanks,
Marton


Wallak.


----- Mail original -----
De: "Marton Balint" <c...@passwd.hu>
À: "FFmpeg development discussions and patches" <ffmpeg-devel@ffmpeg.org>
Cc: wal...@free.fr
Envoyé: Vendredi 17 Mars 2017 23:38:31
Objet: Re: [FFmpeg-devel] [PATCH 2/3] ffplay: convert to new decode API



On Fri, 17 Mar 2017, wal...@free.fr wrote:

I tried the patch. Once av_assert0 test is removed, the crystalhd
decoder is running till send_packet triggers AVERROR(EAGAIN), now the
crystalhd buffer is likely overflowed, the video freezes. A few seconds
later the decoder displays a few frames and the cycle goes on.

Im not sure how to properly implement the function to stop or resend
send_packet frames, this is likely the only mechanism missing.

Hmm. Theoretically an assertion at send_packet can only happen, if the
CrystalHD decoder is is returning AVERROR(EAGAIN) for receive_frame
and for send_packet as well, which is forbidden.

Could you add some logging, and log the return values of both send_packet
and receive_frame to make sure that is the case, and the crystalHD decoder
is buggy, not my implementation of the new decode API?

I tested h264_cuvid decoder with ffplay (the only decoder with the new
API), and that worked so I am inclined to think CrystalHD is buggy. And
the behaviour you described looks like once the buffers of CrystalHD
is full, but no decoded frame is available yet, it simply returns
AVERROR(EAGAIN) instead of blocking receive_frame call which it should do.

Thanks,
Marton

Best Regards,
Wallak.



----- Mail original -----
De: "Marton Balint" <c...@passwd.hu>
À: "FFmpeg development discussions and patches" <ffmpeg-devel@ffmpeg.org>
Cc: wal...@free.fr
Envoyé: Jeudi 16 Mars 2017 23:25:18
Objet: Re: [FFmpeg-devel] [PATCH 2/3] ffplay: convert to new decode API



On Wed, 15 Mar 2017, Marton Balint wrote:

Since subtitles are not yet supported with the new API, CODEC_CAP_DELAY
subtitle codecs (only libzvbi so far) may loose the last few buffered frames in
the end of the stream.

The impact of this is so limited, it seemded better to accept it than losing
the simplification benefits of the new API.

Hi Wallak,

Have you had a chance to test this ffplay patch, and see if it fixes
CrystalHD decoding in ffplay or not?

Thanks,
Marton


Signed-off-by: Marton Balint <c...@passwd.hu>
---
ffplay.c | 92 +++++++++++++++++++++++++++++-----------------------------------
1 file changed, 41 insertions(+), 51 deletions(-)

diff --git a/ffplay.c b/ffplay.c
index cf138dc..06d1d22 100644
--- a/ffplay.c
+++ b/ffplay.c
@@ -186,13 +186,10 @@ enum {
};

typedef struct Decoder {
-    AVPacket pkt;
-    AVPacket pkt_temp;
    PacketQueue *queue;
    AVCodecContext *avctx;
    int pkt_serial;
    int finished;
-    int packet_pending;
    SDL_cond *empty_queue_cond;
    int64_t start_pts;
    AVRational start_pts_tb;
@@ -551,40 +548,24 @@ static void decoder_init(Decoder *d, AVCodecContext 
*avctx, PacketQueue *queue,
    d->queue = queue;
    d->empty_queue_cond = empty_queue_cond;
    d->start_pts = AV_NOPTS_VALUE;
+    d->pkt_serial = -1;
}

static int decoder_decode_frame(Decoder *d, AVFrame *frame, AVSubtitle *sub) {
-    int got_frame = 0;
+    int ret = AVERROR(EAGAIN);

-    do {
-        int ret = -1;
+    for (;;) {
+        AVPacket pkt;

+        if (d->queue->serial == d->pkt_serial) {
+        do {
        if (d->queue->abort_request)
            return -1;

-        if (!d->packet_pending || d->queue->serial != d->pkt_serial) {
-            AVPacket pkt;
-            do {
-                if (d->queue->nb_packets == 0)
-                    SDL_CondSignal(d->empty_queue_cond);
-                if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
-                    return -1;
-                if (pkt.data == flush_pkt.data) {
-                    avcodec_flush_buffers(d->avctx);
-                    d->finished = 0;
-                    d->next_pts = d->start_pts;
-                    d->next_pts_tb = d->start_pts_tb;
-                }
-            } while (pkt.data == flush_pkt.data || d->queue->serial != 
d->pkt_serial);
-            av_packet_unref(&d->pkt);
-            d->pkt_temp = d->pkt = pkt;
-            d->packet_pending = 1;
-        }
-
        switch (d->avctx->codec_type) {
            case AVMEDIA_TYPE_VIDEO:
-                ret = avcodec_decode_video2(d->avctx, frame, &got_frame, 
&d->pkt_temp);
-                if (got_frame) {
+                ret = avcodec_receive_frame(d->avctx, frame);
+                if (ret >= 0) {
                    if (decoder_reorder_pts == -1) {
                        frame->pts = av_frame_get_best_effort_timestamp(frame);
                    } else if (!decoder_reorder_pts) {
@@ -593,8 +574,8 @@ static int decoder_decode_frame(Decoder *d, AVFrame *frame, 
AVSubtitle *sub) {
                }
                break;
            case AVMEDIA_TYPE_AUDIO:
-                ret = avcodec_decode_audio4(d->avctx, frame, &got_frame, 
&d->pkt_temp);
-                if (got_frame) {
+                ret = avcodec_receive_frame(d->avctx, frame);
+                if (ret >= 0) {
                    AVRational tb = (AVRational){1, frame->sample_rate};
                    if (frame->pts != AV_NOPTS_VALUE)
                        frame->pts = av_rescale_q(frame->pts, 
av_codec_get_pkt_timebase(d->avctx), tb);
@@ -606,37 +587,46 @@ static int decoder_decode_frame(Decoder *d, AVFrame 
*frame, AVSubtitle *sub) {
                    }
                }
                break;
-            case AVMEDIA_TYPE_SUBTITLE:
-                ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, 
&d->pkt_temp);
-                break;
+        }
+        if (ret == AVERROR_EOF) {
+            d->finished = d->pkt_serial;
+            avcodec_flush_buffers(d->avctx);
+            return 0;
+        }
+        if (ret >= 0)
+            return 1;
+        } while (ret != AVERROR(EAGAIN));
        }

-        if (ret < 0) {
-            d->packet_pending = 0;
+        do {
+            if (d->queue->nb_packets == 0)
+                SDL_CondSignal(d->empty_queue_cond);
+            if (packet_queue_get(d->queue, &pkt, 1, &d->pkt_serial) < 0)
+                return -1;
+        } while (d->queue->serial != d->pkt_serial);
+
+        if (pkt.data == flush_pkt.data) {
+            avcodec_flush_buffers(d->avctx);
+            d->finished = 0;
+            d->next_pts = d->start_pts;
+            d->next_pts_tb = d->start_pts_tb;
        } else {
-            d->pkt_temp.dts =
-            d->pkt_temp.pts = AV_NOPTS_VALUE;
-            if (d->pkt_temp.data) {
-                if (d->avctx->codec_type != AVMEDIA_TYPE_AUDIO)
-                    ret = d->pkt_temp.size;
-                d->pkt_temp.data += ret;
-                d->pkt_temp.size -= ret;
-                if (d->pkt_temp.size <= 0)
-                    d->packet_pending = 0;
+            if (d->avctx->codec_type == AVMEDIA_TYPE_SUBTITLE) {
+                int got_frame = 0;
+                ret = avcodec_decode_subtitle2(d->avctx, sub, &got_frame, 
&pkt);
+                if (ret < 0)
+                    ret = AVERROR(EAGAIN);
+                else
+                    ret = got_frame ? 0 : (pkt.data ? AVERROR(EAGAIN) : 
AVERROR_EOF);
            } else {
-                if (!got_frame) {
-                    d->packet_pending = 0;
-                    d->finished = d->pkt_serial;
-                }
+                av_assert0(avcodec_send_packet(d->avctx, &pkt) != 
AVERROR(EAGAIN));
            }
+            av_packet_unref(&pkt);
        }
-    } while (!got_frame && !d->finished);
-
-    return got_frame;
+    }
}

static void decoder_destroy(Decoder *d) {
-    av_packet_unref(&d->pkt);
    avcodec_free_context(&d->avctx);
}

--
2.10.2

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to