[vlc-commits] [Git][videolan/vlc][3.0.x] 4 commits: demux: avi: add QNap fourcc defines

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Sat May 13 10:24:02 UTC 2023



Jean-Baptiste Kempf pushed to branch 3.0.x at VideoLAN / VLC


Commits:
a7205f08 by Francois Cartegnie at 2023-05-13T09:47:23+00:00
demux: avi: add QNap fourcc defines

(cherry picked from commit 13e48e51a475a22b7845ba25921bce628cc6250b)

- - - - -
bb8a4cf3 by Francois Cartegnie at 2023-05-13T09:47:23+00:00
demux: avi: fix peek beyond QNap header

(cherry picked from commit 6853c770a818b9dde42b0ca3632af087e105f0dc)

- - - - -
cee5fdbd by Francois Cartegnie at 2023-05-13T09:47:23+00:00
demux: avi: extract meta from QNap header

(cherry picked from commit 3471073604ebd12875572e4840dae66ee7bad4be)

- - - - -
3bb42991 by Francois Cartegnie at 2023-05-13T09:47:23+00:00
demux: avi: fix unmatched video codec

Parsing bitmapinfoheader resets to MS fourcc.
Demuxer's codec conditionals cannot match.

(cherry picked from commit 9bb482ba20ce157202ca7de3dc7b7ac140103058)

- - - - -


2 changed files:

- modules/demux/avi/avi.c
- modules/demux/avi/libavi.h


Changes:

=====================================
modules/demux/avi/avi.c
=====================================
@@ -150,6 +150,7 @@ typedef struct
 
     unsigned int    i_width_bytes;
     bool            b_flipped;
+    bool            is_qnap;
 
     es_format_t     fmt;
     es_out_id_t     *p_es;
@@ -194,6 +195,7 @@ struct demux_sys_t
 
     /* meta */
     vlc_meta_t  *meta;
+    unsigned int updates;
 
     unsigned int       i_attachment;
     input_attachment_t **attachment;
@@ -215,7 +217,7 @@ static int AVI_StreamChunkSet ( demux_t *, avi_track_t *, unsigned int i_ck );
 static int AVI_StreamBytesSet ( demux_t *, avi_track_t *, uint64_t i_byte );
 
 vlc_fourcc_t AVI_FourccGetCodec( unsigned int i_cat, vlc_fourcc_t );
-static int   AVI_GetKeyFlag    ( vlc_fourcc_t , uint8_t * );
+static int   AVI_GetKeyFlag    ( const avi_track_t *, const uint8_t * );
 
 static int AVI_PacketGetHeader( demux_t *, avi_packet_t *p_pk );
 static int AVI_PacketNext     ( demux_t * );
@@ -247,20 +249,21 @@ static int        AVI_TrackStopFinishedStreams( demux_t *);
  - to complete....
  */
 
-#define QNAP_HEADER_SIZE 56
-static bool IsQNAPCodec(vlc_fourcc_t codec)
+#define QNAP_VIDEO_HEADER_SIZE 56
+/* https://github.com/qnap-dev/qnap-qiot-sdks/blob/master/doc/QVRPro/live_stream_parser.cpp#L90 */
+static bool IsQNAPCodec(uint32_t biCompression)
 {
-    switch (codec)
-    {
-        case VLC_FOURCC('w', '2', '6', '4'):
-        case VLC_FOURCC('q', '2', '6', '4'):
-        case VLC_FOURCC('Q', '2', '6', '4'):
-        case VLC_FOURCC('w', 'M', 'P', '4'):
-        case VLC_FOURCC('q', 'M', 'P', '4'):
-        case VLC_FOURCC('Q', 'M', 'P', '4'):
-        case VLC_FOURCC('w', 'I', 'V', 'G'):
-        case VLC_FOURCC('q', 'I', 'V', 'G'):
-        case VLC_FOURCC('Q', 'I', 'V', 'G'):
+    switch (biCompression)
+    {
+        case QNAP_FCC_w264:
+        case QNAP_FCC_q264:
+        case QNAP_FCC_Q264:
+        case QNAP_FCC_wMP4:
+        case QNAP_FCC_qMP4:
+        case QNAP_FCC_QMP4:
+        case QNAP_FCC_wIVG:
+        case QNAP_FCC_qIVG:
+        case QNAP_FCC_QIVG:
             return true;
         default:
             return false;
@@ -651,8 +654,7 @@ static int Open( vlc_object_t * p_this )
                    break;
                 }
 
-                es_format_Init( &tk->fmt, VIDEO_ES,
-                        AVI_FourccGetCodec( VIDEO_ES, p_bih->biCompression ) );
+                es_format_Init( &tk->fmt, VIDEO_ES, 0 );
 
                 if( p_bih->biCompression == BI_RGB )
                 {
@@ -723,8 +725,11 @@ static int Open( vlc_object_t * p_this )
                     Set_BMP_RGB_Masks( &tk->fmt );
                 }
 
-                if( IsQNAPCodec( tk->fmt.i_codec ) )
+                if( IsQNAPCodec( p_bih->biCompression ) )
+                {
+                    tk->is_qnap = true;
                     tk->fmt.b_packetized = false;
+                }
 
                 tk->i_samplesize = 0;
 
@@ -1078,6 +1083,8 @@ static block_t * ReadFrame( demux_t *p_demux, const avi_track_t *tk,
  *****************************************************************************/
 static void AVI_SendFrame( demux_t *p_demux, avi_track_t *tk, block_t *p_frame )
 {
+    demux_sys_t *p_sys = p_demux->p_sys;
+
     if( tk->fmt.i_cat != VIDEO_ES )
         p_frame->i_dts = p_frame->i_pts;
     else
@@ -1089,17 +1096,32 @@ static void AVI_SendFrame( demux_t *p_demux, avi_track_t *tk, block_t *p_frame )
     if( tk->i_dv_audio_rate )
         AVI_DvHandleAudio( p_demux, tk, p_frame );
 
-    /* Strip QNAP header */
-    if( IsQNAPCodec( tk->fmt.i_codec ) )
+    /* Strip 3rd party header */
+    if( tk->is_qnap )
     {
-        if( p_frame->i_buffer <= QNAP_HEADER_SIZE )
+        if( p_frame->i_buffer >= QNAP_VIDEO_HEADER_SIZE )
         {
-            block_Release( p_frame );
-            return;
+            const uint8_t *p = p_frame->p_buffer;
+            /* Check header is really there */
+            vlc_fourcc_t fcc = VLC_FOURCC(p[0],p[1],p[2],p[3]);
+            /* Parse QNAP header */
+            if( IsQNAPCodec(fcc) && p_sys->meta )
+            {
+                const char *psz_title = vlc_meta_Get( p_sys->meta, vlc_meta_Title );
+                char *psz_osd = (char *) &p_frame->p_buffer[24];
+                if( *psz_osd != 0 )
+                {
+                    psz_osd[23] = 0;
+                    if( !psz_title || strncmp( psz_osd, psz_title, 24 ) )
+                    {
+                        vlc_meta_Set( p_sys->meta, vlc_meta_Title, psz_osd );
+                        p_sys->updates |= INPUT_UPDATE_META;
+                    }
+                }
+            }
+            p_frame->i_buffer -= QNAP_VIDEO_HEADER_SIZE;
+            p_frame->p_buffer += QNAP_VIDEO_HEADER_SIZE;
         }
-
-        p_frame->i_buffer -= QNAP_HEADER_SIZE;
-        p_frame->p_buffer += QNAP_HEADER_SIZE;
     }
 
     if( tk->i_next_block_flags )
@@ -1336,7 +1358,7 @@ static int Demux_Seekable( demux_t *p_demux )
                     /* add this chunk to the index */
                     avi_entry_t index;
                     index.i_id     = avi_pk.i_fourcc;
-                    index.i_flags  = AVI_GetKeyFlag(tk->fmt.i_codec, avi_pk.i_peek);
+                    index.i_flags  = AVI_GetKeyFlag(tk, avi_pk.i_peek);
                     index.i_pos    = avi_pk.i_pos;
                     index.i_length = avi_pk.i_size;
                     index.i_lengthtotal = index.i_length;
@@ -1882,6 +1904,14 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
             return VLC_EGENERIC;
         }
 
+        case DEMUX_TEST_AND_CLEAR_FLAGS:
+        {
+            unsigned *restrict flags = va_arg( args, unsigned * );
+            *flags &= p_sys->updates;
+            p_sys->updates &= ~*flags;
+            return VLC_SUCCESS;
+        }
+
         default:
             return VLC_EGENERIC;
     }
@@ -2025,7 +2055,7 @@ static int AVI_StreamChunkFind( demux_t *p_demux, avi_track_t *tk )
             /* add this chunk to the index */
             avi_entry_t index;
             index.i_id     = avi_pk.i_fourcc;
-            index.i_flags  = AVI_GetKeyFlag(tk_pk->fmt.i_codec, avi_pk.i_peek);
+            index.i_flags  = AVI_GetKeyFlag(tk_pk, avi_pk.i_peek);
             index.i_pos    = avi_pk.i_pos;
             index.i_length = avi_pk.i_size;
             index.i_lengthtotal = index.i_length;
@@ -2208,9 +2238,16 @@ static int AVI_TrackSeek( demux_t *p_demux,
 /****************************************************************************
  * Return true if it's a key frame
  ****************************************************************************/
-static int AVI_GetKeyFlag( vlc_fourcc_t i_fourcc, uint8_t *p_byte )
+static int AVI_GetKeyFlag( const avi_track_t *tk, const uint8_t *p_byte )
 {
-    switch( i_fourcc )
+    if( tk->is_qnap )
+    {
+        const uint8_t *p = p_byte;
+        if( IsQNAPCodec(VLC_FOURCC(p[0],p[1],p[2],p[3])) )
+            return p[4] & 0x01 ? AVIIF_KEYFRAME : 0;
+    }
+
+    switch( tk->fmt.i_codec )
     {
         case VLC_CODEC_DIV1:
             /* we have:
@@ -2820,7 +2857,7 @@ static void AVI_IndexCreate( demux_t *p_demux )
 
             avi_entry_t index;
             index.i_id      = pk.i_fourcc;
-            index.i_flags   = AVI_GetKeyFlag(tk->fmt.i_codec, pk.i_peek);
+            index.i_flags   = AVI_GetKeyFlag(tk, pk.i_peek);
             index.i_pos     = pk.i_pos;
             index.i_length  = pk.i_size;
             index.i_lengthtotal = pk.i_size;


=====================================
modules/demux/avi/libavi.h
=====================================
@@ -366,3 +366,14 @@ int     AVI_ChunkFetchIndexes( stream_t *, avi_chunk_t *p_riff );
 #define FOURCC_dvsl         VLC_FOURCC('d','v','s','l')
 #define FOURCC_dv25         VLC_FOURCC('d','v','2','5')
 #define FOURCC_dv50         VLC_FOURCC('d','v','5','0')
+
+/* QNap */
+#define QNAP_FCC_w264       VLC_FOURCC('w','2','6','4')
+#define QNAP_FCC_q264       VLC_FOURCC('q','2','6','4')
+#define QNAP_FCC_Q264       VLC_FOURCC('Q','2','6','4')
+#define QNAP_FCC_wMP4       VLC_FOURCC('w','M','P','4')
+#define QNAP_FCC_qMP4       VLC_FOURCC('q','M','P','4')
+#define QNAP_FCC_QMP4       VLC_FOURCC('Q','M','P','4')
+#define QNAP_FCC_wIVG       VLC_FOURCC('w','I','V','G')
+#define QNAP_FCC_qIVG       VLC_FOURCC('q','I','V','G')
+#define QNAP_FCC_QIVG       VLC_FOURCC('Q','I','V','G')



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/e8751a5436acafff0e77056489dfdd3c87170658...3bb4299198c0a498bfe3f941b35964f5788095c7

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/e8751a5436acafff0e77056489dfdd3c87170658...3bb4299198c0a498bfe3f941b35964f5788095c7
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list