[vlc-devel] [PATCH 1/2] packetizer: add rv34_parser

Zhao Zhili quinkblack at foxmail.com
Wed May 30 14:13:40 CEST 2018


It's used to fix the timestamp issue of RV30 and RV40.
Ported from libavcodec/rv34_parser.c. It's author is Kostya Shishkov.
---
Add original author in commit message.

  modules/packetizer/Makefile.am   |   2 +
  modules/packetizer/rv34_parser.c | 135 
+++++++++++++++++++++++++++++++++++++++
  2 files changed, 137 insertions(+)
  create mode 100644 modules/packetizer/rv34_parser.c

diff --git a/modules/packetizer/Makefile.am b/modules/packetizer/Makefile.am
index 3176023..a360db3 100644
--- a/modules/packetizer/Makefile.am
+++ b/modules/packetizer/Makefile.am
@@ -24,6 +24,7 @@ libpacketizer_hevc_plugin_la_SOURCES = packetizer/hevc.c \
  libpacketizer_a52_plugin_la_SOURCES = packetizer/a52.c packetizer/a52.h
  libpacketizer_dts_plugin_la_SOURCES = packetizer/dts.c \
      packetizer/dts_header.c packetizer/dts_header.h
+libpacketizer_rv34_plugin_la_SOURCES = packetizer/rv34_parser.c

  libpacketizer_avparser_plugin_la_SOURCES = packetizer/avparser.c \
      packetizer/avparser.h \
@@ -46,6 +47,7 @@ packetizer_LTLIBRARIES = \
      libpacketizer_copy_plugin.la \
      libpacketizer_a52_plugin.la \
      libpacketizer_dts_plugin.la \
+    libpacketizer_rv34_plugin.la \
      $(NULL)

  if HAVE_AVCODEC
diff --git a/modules/packetizer/rv34_parser.c 
b/modules/packetizer/rv34_parser.c
new file mode 100644
index 0000000..a89bdd9
--- /dev/null
+++ b/modules/packetizer/rv34_parser.c
@@ -0,0 +1,135 @@
+/*****************************************************************************
+ * rv34_parser.c
+ 
*****************************************************************************
+ * Copyright (C) 2018 VLC authors and VideoLAN
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ 
*****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_codec.h>
+#include <vlc_block.h>
+
+static int  Open ( vlc_object_t * );
+static void Close( vlc_object_t * );
+
+vlc_module_begin ()
+    set_category( CAT_SOUT )
+    set_subcategory( SUBCAT_SOUT_PACKETIZER )
+    set_description( N_("RV30/RV40 packetizer") )
+    set_capability( "packetizer", 50 )
+    set_callbacks( Open, Close )
+vlc_module_end ()
+
+typedef struct
+{
+    mtime_t key_dts;
+    int key_pts;
+} decoder_sys_t;
+
+static block_t *Packetize( decoder_t *p_dec, block_t **pp_block )
+{
+    static const uint32_t rv_to_vlc_frame_type[4] = {
+        BLOCK_FLAG_TYPE_I, BLOCK_FLAG_TYPE_I,
+        BLOCK_FLAG_TYPE_P, BLOCK_FLAG_TYPE_B
+    };
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
+    if( pp_block == NULL || *pp_block == NULL )
+        return NULL;
+
+    block_t *p_block = *pp_block;
+    *pp_block = NULL;
+
+    if( p_block->i_buffer == 0 ||
+        p_block->i_buffer < (size_t)(13 + p_block->p_buffer[0] * 8) )
+        return p_block;
+
+    uint32_t type, hdr;
+    int i_pts;
+
+    hdr = GetDWBE(p_block->p_buffer + 9 + p_block->p_buffer[0] * 8);
+    if( p_dec->fmt_in.i_codec == VLC_CODEC_RV30 )
+    {
+        type = (hdr >> 27) & 3;
+        i_pts = (hdr >> 7) & 0x1FFF;
+    }
+    else
+    {
+        type = (hdr >> 29) & 3;
+        i_pts = (hdr >> 6) & 0x1FFF;
+    }
+
+    if( type != 3 && p_block->i_pts != VLC_TS_INVALID )
+    {
+        /* key_dts and key_pts are in millisecond */
+        p_sys->key_dts = p_block->i_pts * 1000 / CLOCK_FREQ;
+        p_sys->key_pts = i_pts;
+    }
+    else
+    {
+        if( type != 3 )
+            p_block->i_pts = p_sys->key_dts + ((i_pts - p_sys->key_pts) 
& 0x1FFF);
+        else
+            p_block->i_pts = p_sys->key_dts - ((p_sys->key_pts - i_pts) 
& 0x1FFF);
+        p_block->i_pts *= CLOCK_FREQ / 1000;
+    }
+
+    p_block->i_flags |= rv_to_vlc_frame_type[type];
+
+    return p_block;
+}
+
+static void FlushPacketizer( decoder_t *p_dec )
+{
+    decoder_sys_t *p_sys = p_dec->p_sys;
+
+    p_sys->key_dts = VLC_TS_0;
+    p_sys->key_pts = 0;
+}
+
+static int Open( vlc_object_t *p_this )
+{
+    decoder_t *p_dec = (decoder_t *)p_this;
+    decoder_sys_t *p_sys;
+
+    if( p_dec->fmt_in.i_codec != VLC_CODEC_RV30 &&
+            p_dec->fmt_in.i_codec != VLC_CODEC_RV40 )
+        return VLC_EGENERIC;
+
+    p_sys = malloc(sizeof(*p_sys));
+    if( unlikely(p_sys == NULL) )
+        return VLC_ENOMEM;
+
+    p_sys->key_dts = VLC_TS_0;
+    p_sys->key_pts = 0;
+    p_dec->p_sys = p_sys;
+    p_dec->pf_packetize = Packetize;
+    p_dec->pf_flush = FlushPacketizer;
+    es_format_Copy( &p_dec->fmt_out, &p_dec->fmt_in );
+
+    return VLC_SUCCESS;
+}
+
+static void Close( vlc_object_t *p_this )
+{
+    decoder_t *p_dec = (decoder_t *)p_this;
+    free(p_dec->p_sys);
+}
-- 
2.9.5

-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-packetizer-add-rv34_parser.patch
Type: text/x-patch
Size: 5558 bytes
Desc: not available
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20180530/d42d1719/attachment.bin>


More information about the vlc-devel mailing list