[vlc-commits] videotoolbox: restart in case of flush
Thomas Guillem
git at videolan.org
Fri Jan 20 11:22:11 CET 2017
vlc | branch: master | Thomas Guillem <thomas at gllm.fr> | Thu Jan 19 19:23:41 2017 +0100| [f69cec6730939364a8346326f34599253f5bf3aa] | committer: Thomas Guillem
videotoolbox: restart in case of flush
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=f69cec6730939364a8346326f34599253f5bf3aa
---
modules/codec/videotoolbox.m | 48 ++++++++++++++++++++++++++++----------------
1 file changed, 31 insertions(+), 17 deletions(-)
diff --git a/modules/codec/videotoolbox.m b/modules/codec/videotoolbox.m
index f71c50b..0ac487c 100644
--- a/modules/codec/videotoolbox.m
+++ b/modules/codec/videotoolbox.m
@@ -114,6 +114,8 @@ struct decoder_sys_t
CMVideoCodecType codec;
uint8_t i_nal_length_size;
+ bool b_vt_feed;
+ bool b_vt_flush;
bool b_is_avcc;
VTDecompressionSessionRef session;
CMVideoFormatDescriptionRef videoFormatDescription;
@@ -632,24 +634,27 @@ static int StartVideoToolbox(decoder_t *p_dec, block_t *p_block)
return VLC_SUCCESS;
}
-static void StopVideoToolboxSession(decoder_t *p_dec)
+static void StopVideoToolboxSession(decoder_t *p_dec, bool b_reset_format)
{
decoder_sys_t *p_sys = p_dec->p_sys;
VTDecompressionSessionInvalidate(p_sys->session);
CFRelease(p_sys->session);
p_sys->session = nil;
- p_sys->b_format_propagated = false;
+ if (b_reset_format)
+ p_sys->b_format_propagated = false;
+
+ vlc_mutex_lock(&p_sys->lock);
+ PicReorder_flush(p_dec);
+ vlc_mutex_unlock(&p_sys->lock);
}
static void StopVideoToolbox(decoder_t *p_dec)
{
decoder_sys_t *p_sys = p_dec->p_sys;
- if (p_sys->session != nil) {
- Flush(p_dec);
- StopVideoToolboxSession(p_dec);
- }
+ if (p_sys->session != nil)
+ StopVideoToolboxSession(p_dec, true);
if (p_sys->videoFormatDescription != nil) {
CFRelease(p_sys->videoFormatDescription);
@@ -665,16 +670,14 @@ static void StopVideoToolbox(decoder_t *p_dec)
}
}
-static void RestartVideoToolbox(decoder_t *p_dec)
+static void RestartVideoToolbox(decoder_t *p_dec, bool b_reset_format)
{
decoder_sys_t *p_sys = p_dec->p_sys;
msg_Dbg(p_dec, "Restarting decoder session");
if (p_sys->session != nil)
- StopVideoToolboxSession(p_dec);
-
- Flush(p_dec);
+ StopVideoToolboxSession(p_dec, b_reset_format);
if (StartVideoToolboxSession(p_dec) != VLC_SUCCESS) {
msg_Warn(p_dec, "Decoder session restart failed");
@@ -712,6 +715,8 @@ static int OpenDecoder(vlc_object_t *p_this)
return VLC_ENOMEM;
p_dec->p_sys = p_sys;
p_sys->session = nil;
+ p_sys->b_vt_feed = false;
+ p_sys->b_vt_flush = false;
p_sys->b_is_avcc = false;
p_sys->codec = codec;
p_sys->videoFormatDescription = nil;
@@ -1014,9 +1019,10 @@ static void Flush(decoder_t *p_dec)
{
decoder_sys_t *p_sys = p_dec->p_sys;
- vlc_mutex_lock(&p_sys->lock);
- PicReorder_flush(p_dec);
- vlc_mutex_unlock(&p_sys->lock);
+ /* There is no Flush in VT api, ask to restart VT from next DecodeBlock if
+ * we already feed some input blocks (it's better to not restart here in
+ * order to avoid useless restart just before a close). */
+ p_sys->b_vt_flush = p_sys->b_vt_feed;
}
static picture_t *DecodeBlock(decoder_t *p_dec, block_t **pp_block)
@@ -1028,6 +1034,11 @@ static picture_t *DecodeBlock(decoder_t *p_dec, block_t **pp_block)
OSStatus status;
int i_ret = 0;
+ if (p_sys->b_vt_flush) {
+ RestartVideoToolbox(p_dec, false);
+ p_sys->b_vt_flush = false;
+ }
+
if (!pp_block)
{
/* draining: return last pictures of the reordered queue */
@@ -1044,7 +1055,8 @@ static picture_t *DecodeBlock(decoder_t *p_dec, block_t **pp_block)
if (likely(p_block != NULL)) {
if (unlikely(p_block->i_flags&(BLOCK_FLAG_CORRUPTED)))
{
- Flush(p_dec);
+ if (p_sys->b_vt_feed)
+ RestartVideoToolbox(p_dec, false);
block_Release(p_block);
goto skip;
}
@@ -1090,7 +1102,9 @@ static picture_t *DecodeBlock(decoder_t *p_dec, block_t **pp_block)
decoderFlags,
NULL, // sourceFrameRefCon
&flagOut); // infoFlagsOut
- if (status != noErr) {
+ if (status == noErr)
+ p_sys->b_vt_feed = true;
+ else {
if (status == kCVReturnInvalidSize)
msg_Err(p_dec, "decoder failure: invalid block size");
else if (status == -666)
@@ -1103,10 +1117,10 @@ static picture_t *DecodeBlock(decoder_t *p_dec, block_t **pp_block)
StopVideoToolbox(p_dec);
} else if (status == -8960 || status == -12911) {
msg_Err(p_dec, "decoder failure: internal malfunction (%i)", status);
- RestartVideoToolbox(p_dec);
+ RestartVideoToolbox(p_dec, true);
} else if (status == -12903) {
msg_Warn(p_dec, "decoder failure: session invalid");
- RestartVideoToolbox(p_dec);
+ RestartVideoToolbox(p_dec, true);
} else
msg_Dbg(p_dec, "decoding frame failed (%i)", status);
}
More information about the vlc-commits
mailing list