[vlc-devel] [PATCH] Use avcodec's vp9 parser to packetize the superframes before decoding

Denis Charmet typx at dinauz.org
Wed Feb 4 00:39:18 CET 2015


For some reasons ffmpeg's avcodec vp9 decoder expect superframes to be splitted into subframes before injection.

Fix #12944
---
 modules/codec/avcodec/video.c | 36 ++++++++++++++++++++++++++++++++----
 1 file changed, 32 insertions(+), 4 deletions(-)

diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c
index 5ba6e2e..1a22ccf 100644
--- a/modules/codec/avcodec/video.c
+++ b/modules/codec/avcodec/video.c
@@ -81,6 +81,9 @@ struct decoder_sys_t
     /* VA API */
     vlc_va_t *p_va;
 
+    /* Avparser */
+    AVCodecParserContext * p_parser;
+
     vlc_sem_t sem_mt;
 };
 
@@ -248,6 +251,13 @@ static int OpenVideoCodec( decoder_t *p_dec )
             break;
     }
 #endif
+    if( p_sys->p_codec->id == AV_CODEC_ID_VP9 )
+    {
+        p_sys->p_parser = av_parser_init( p_sys->p_codec->id );
+        msg_Dbg( p_dec, "Using vp9 parser" );
+        if( !p_sys->p_parser )
+          msg_Warn( p_dec, "Couldn't initialize vp9 parser, trying anyway");
+    }
     return VLC_SUCCESS;
 }
 
@@ -599,7 +609,7 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
 
     while( !p_block || p_block->i_buffer > 0 || p_sys->b_flush )
     {
-        int i_used, b_gotpicture;
+        int i_used, b_gotpicture, len = -1;
         picture_t *p_pic;
         AVPacket pkt;
 
@@ -608,10 +618,20 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
         av_init_packet( &pkt );
         if( p_block )
         {
-            pkt.data = p_block->p_buffer;
-            pkt.size = p_block->i_buffer;
             pkt.pts = p_block->i_pts;
             pkt.dts = p_block->i_dts;
+            if( p_sys->p_parser )
+            {
+                len = av_parser_parse2( p_sys->p_parser, p_sys->p_codec,
+                                  &pkt.data, &pkt.size,
+                                  p_block->p_buffer, p_block->i_buffer,
+                                  pkt.pts, pkt.dts, -1 );
+            }
+            else
+            {
+                pkt.data = p_block->p_buffer;
+                pkt.size = p_block->i_buffer;
+            }
         }
         else
         {
@@ -658,10 +678,15 @@ static picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block )
                 block_Release( p_block );
                 return NULL;
             }
+            else if( len > i_used )
+                i_used = len;
             else if( (unsigned)i_used > p_block->i_buffer ||
                     p_context->thread_count > 1 )
             {
-                i_used = p_block->i_buffer;
+                if( len > 0)
+                    i_used = len;
+                else
+                    i_used = p_block->i_buffer;
             }
 
             /* Consumed bytes */
@@ -822,6 +847,9 @@ void EndVideoDec( decoder_t *p_dec )
 
     ffmpeg_CloseCodec( p_dec );
 
+    if( p_sys->p_parser )
+        av_parser_close( p_sys->p_parser );
+
     if( p_sys->p_ff_pic )
         avcodec_free_frame( &p_sys->p_ff_pic );
 
-- 
2.1.4




More information about the vlc-devel mailing list