[vlc-commits] demux: avi: handle uncompressed frames flip

Francois Cartegnie git at videolan.org
Fri Apr 18 17:46:25 CEST 2014


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Fri Apr 18 17:37:30 2014 +0200| [ac18c8a35cdab17ad5270d3ec4926ff585b8db3c] | committer: Francois Cartegnie

demux: avi: handle uncompressed frames flip

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=ac18c8a35cdab17ad5270d3ec4926ff585b8db3c
---

 modules/demux/avi/avi.c |   88 ++++++++++++++++++++++++++++++++++-------------
 1 file changed, 65 insertions(+), 23 deletions(-)

diff --git a/modules/demux/avi/avi.c b/modules/demux/avi/avi.c
index e8e2a4d..4f7fbd8 100644
--- a/modules/demux/avi/avi.c
+++ b/modules/demux/avi/avi.c
@@ -805,24 +805,75 @@ static void Close ( vlc_object_t * p_this )
 
 block_t * ReadFrame( demux_t *p_demux, const avi_track_t *tk, const int i_size )
 {
-    block_t *p_frame = stream_Block( p_demux->s, i_size );
-    if ( !p_frame || !tk->i_width_bytes ) /* There's no stride */
+    block_t *p_frame = stream_Block( p_demux->s, __EVEN( i_size ) );
+    if ( !p_frame ) return p_frame;
+
+    const uint8_t i_header = ( tk->i_idxposb == 0 ) ? 8 : 0;
+
+    if( i_size % 2 )    /* read was padded on word boundary */
+    {
+        p_frame->i_buffer--;
+    }
+
+    /* skip header */
+    if( tk->i_idxposb == 0 )
+    {
+        p_frame->p_buffer += i_header;
+        p_frame->i_buffer -= i_header;
+    }
+
+    if ( !tk->i_width_bytes )
         return p_frame;
 
     const unsigned int i_stride_bytes = ((( (tk->i_width_bytes << 3) + 31) & ~31) >> 3);
-    const uint8_t *p_end = p_frame->p_buffer + p_frame->i_buffer;
-    const uint8_t *p_src = p_frame->p_buffer + i_stride_bytes;
-    uint8_t *p_dst = p_frame->p_buffer + tk->i_width_bytes;
 
-    p_frame->i_buffer = tk->i_width_bytes;
-    if ( tk->i_idxposb == 0 ) p_frame->i_buffer += 8;
+    if ( p_frame->i_buffer < i_stride_bytes )
+    {
+        p_frame->i_buffer = 0;
+        return p_frame;
+    }
+
+    if( !tk->b_flipped )
+    {
+        const uint8_t *p_src = p_frame->p_buffer + i_stride_bytes;
+        const uint8_t *p_end = p_frame->p_buffer + p_frame->i_buffer;
+        uint8_t *p_dst = p_frame->p_buffer + tk->i_width_bytes;
+
+        p_frame->i_buffer = tk->i_width_bytes;
 
-    while ( p_src + i_stride_bytes < p_end )
+        while ( p_src + i_stride_bytes <= p_end )
+        {
+            memmove( p_dst, p_src, tk->i_width_bytes );
+            p_src += i_stride_bytes;
+            p_dst += tk->i_width_bytes;
+            p_frame->i_buffer += tk->i_width_bytes;
+        }
+    }
+    else
     {
-        memmove( p_dst, p_src, tk->i_width_bytes );
-        p_src += i_stride_bytes;
-        p_dst += tk->i_width_bytes;
-        p_frame->i_buffer += tk->i_width_bytes;
+        block_t *p_flippedframe = block_Alloc( p_frame->i_buffer );
+        if ( !p_flippedframe )
+        {
+            block_Release( p_frame );
+            return NULL;
+        }
+
+        unsigned int i_lines = p_frame->i_buffer / i_stride_bytes;
+        const uint8_t *p_src = p_frame->p_buffer + i_lines * i_stride_bytes;
+        uint8_t *p_dst = p_flippedframe->p_buffer;
+
+        p_flippedframe->i_buffer = 0;
+
+        while ( i_lines-- > 0 )
+        {
+            p_src -= i_stride_bytes;
+            memcpy( p_dst, p_src, tk->i_width_bytes );
+            p_dst += tk->i_width_bytes;
+            p_flippedframe->i_buffer += tk->i_width_bytes;
+        }
+
+        block_Release( p_frame );
+        p_frame = p_flippedframe;
     }
 
     return p_frame;
@@ -1111,23 +1162,14 @@ static int Demux_Seekable( demux_t *p_demux )
             i_size += 8; /* need to read and skip header */
         }
 
-        if( ( p_frame = ReadFrame( p_demux, tk, __EVEN( i_size ) ) )==NULL )
+        if( ( p_frame = ReadFrame( p_demux, tk, i_size ) )==NULL )
         {
             msg_Warn( p_demux, "failed reading data" );
             tk->b_eof = false;
             toread[i_track].b_ok = false;
             continue;
         }
-        if( i_size % 2 )    /* read was padded on word boundary */
-        {
-            p_frame->i_buffer--;
-        }
-        /* skip header */
-        if( tk->i_idxposb == 0 )
-        {
-            p_frame->p_buffer += 8;
-            p_frame->i_buffer -= 8;
-        }
+
         p_frame->i_pts = AVI_GetPTS( tk ) + 1;
         if( tk->idx.p_entry[tk->i_idxposc].i_flags&AVIIF_KEYFRAME )
         {



More information about the vlc-commits mailing list