From: Aman Gupta <a...@tmm1.net>

Previously the codec kept an entire copy of the SPS, and restarted the VT 
decoder
session whenever it changed. This fixed decoding errors in [1], as
described in 9519983c. On further inspection, that sample features an SPS change
from High/4.0 to High/3.2 while moving from one scene to another.

Yesterday I received [2], which contains minor SPS changes where the
profile and level do not change. These occur frequently and are not associated 
with
scene changes. After 9519983c, the VT decoder session is recreated 
unnecessarily when
these are encountered causing visual glitches.

This commit simplifies the state kept in the VTContext to include just the 
first three
bytes of the SPS, containing the profile and level details. This is populated 
initially
when the VT decoder session is created, and used to detect changes and force a 
restart.

This means minor SPS changes are fed directly into the existing decoder, whereas
profile/level changes force the decoder session to be recreated with the new 
parameters.

After this commit, both samples [1] and [2] playback as expected.

[1] https://s3.amazonaws.com/tmm1/videotoolbox/spschange.ts
[2] https://s3.amazonaws.com/tmm1/videotoolbox/spschange2.ts

Signed-off-by: Aman Gupta <a...@tmm1.net>
---
 libavcodec/videotoolbox.c | 15 ++++++++-------
 libavcodec/vt_internal.h  |  4 +---
 2 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/libavcodec/videotoolbox.c b/libavcodec/videotoolbox.c
index 9eeada30ba..d29607363c 100644
--- a/libavcodec/videotoolbox.c
+++ b/libavcodec/videotoolbox.c
@@ -90,6 +90,7 @@ int ff_videotoolbox_alloc_frame(AVCodecContext *avctx, 
AVFrame *frame)
 
 CFDataRef ff_videotoolbox_avcc_extradata_create(AVCodecContext *avctx)
 {
+    VTContext *vtctx = avctx->internal->hwaccel_priv_data;
     H264Context *h = avctx->priv_data;
     CFDataRef data = NULL;
     uint8_t *p;
@@ -116,6 +117,10 @@ CFDataRef 
ff_videotoolbox_avcc_extradata_create(AVCodecContext *avctx)
     p += 3 + h->ps.pps->data_size;
     av_assert0(p - vt_extradata == vt_extradata_size);
 
+    // save sps header (profile/level) used to create decoder session,
+    // so we can detect changes and recreate it.
+    memcpy(vtctx->sps, h->ps.sps->data + 1, 3);
+
     data = CFDataCreate(kCFAllocatorDefault, vt_extradata, vt_extradata_size);
     av_free(vt_extradata);
     return data;
@@ -320,16 +325,13 @@ static int videotoolbox_h264_decode_params(AVCodecContext 
*avctx,
     VTContext *vtctx = avctx->internal->hwaccel_priv_data;
 
     if (type == H264_NAL_SPS) {
-        if (!vtctx->sps || vtctx->sps_len != size || memcmp(buffer, 
vtctx->sps, size) != 0) {
-            vtctx->sps = av_fast_realloc(vtctx->sps, &vtctx->sps_capa, size);
-            if (vtctx->sps)
-                memcpy(vtctx->sps, buffer, size);
+        if (size > 4 && memcmp(vtctx->sps, buffer + 1, 3) != 0) {
             vtctx->reconfig_needed = true;
-            vtctx->sps_len = size;
+            memcpy(vtctx->sps, buffer + 1, 3);
         }
     }
 
-    // pass-through new PPS to the decoder
+    // pass-through SPS/PPS changes to the decoder
     return ff_videotoolbox_h264_decode_slice(avctx, buffer, size);
 }
 
@@ -365,7 +367,6 @@ int ff_videotoolbox_uninit(AVCodecContext *avctx)
     VTContext *vtctx = avctx->internal->hwaccel_priv_data;
     if (vtctx) {
         av_freep(&vtctx->bitstream);
-        av_freep(&vtctx->sps);
         if (vtctx->frame)
             CVPixelBufferRelease(vtctx->frame);
     }
diff --git a/libavcodec/vt_internal.h b/libavcodec/vt_internal.h
index fc27dad9f9..929fe423fc 100644
--- a/libavcodec/vt_internal.h
+++ b/libavcodec/vt_internal.h
@@ -40,9 +40,7 @@ typedef struct VTContext {
     struct AVVideotoolboxContext *vt_ctx;
 
     // Current H264 parameters (used to trigger decoder restart on SPS 
changes).
-    uint8_t                     *sps;
-    uint32_t                    sps_len;
-    unsigned int                sps_capa;
+    uint8_t                     sps[3];
     bool                        reconfig_needed;
 } VTContext;
 
-- 
2.14.2

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

Reply via email to