[vlc-commits] Add avparser packetizer for VP9 handling
Denis Charmet
git at videolan.org
Thu Feb 26 20:43:05 CET 2015
vlc/vlc-2.2 | branch: master | Denis Charmet <typx at dinauz.org> | Thu Feb 26 17:32:29 2015 +0100| [0a1bb10515efaed0cc62dac4b2cf3302f46b1328] | committer: Jean-Baptiste Kempf
Add avparser packetizer for VP9 handling
Fix #12944
Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>
(cherry picked from commit 17e07afce4d26cfecf6ab5252c738cd8a0e9756a)
Signed-off-by: Jean-Baptiste Kempf <jb at videolan.org>
> http://git.videolan.org/gitweb.cgi/vlc/vlc-2.2.git/?a=commit;h=0a1bb10515efaed0cc62dac4b2cf3302f46b1328
---
modules/MODULES_LIST | 1 +
modules/codec/avcodec/video.c | 3 +
modules/demux/mkv/matroska_segment_parse.cpp | 1 +
modules/packetizer/Modules.am | 11 ++
modules/packetizer/avparser.c | 188 ++++++++++++++++++++++++++
po/POTFILES.in | 1 +
6 files changed, 205 insertions(+)
diff --git a/modules/MODULES_LIST b/modules/MODULES_LIST
index db5820e..d43d1f4 100644
--- a/modules/MODULES_LIST
+++ b/modules/MODULES_LIST
@@ -249,6 +249,7 @@ $Id$
* opus: a opus audio decoder/packetizer/encoder using the libopus library
* os2drive: service discovery for OS/2 drives
* oss: audio output module using the OSS /dev/dsp interface
+ * packetizer_avparser: libavcodec packetizer
* packetizer_copy: Simple copy packetizer
* packetizer_dirac: Dirac video packetizer
* packetizer_flac: FLAC audio packetizer
diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c
index ad9be3b..111ba0f 100644
--- a/modules/codec/avcodec/video.c
+++ b/modules/codec/avcodec/video.c
@@ -441,6 +441,9 @@ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context,
return VLC_EGENERIC;
}
+ if ( p_dec->fmt_in.i_codec == VLC_CODEC_VP9 )
+ p_dec->b_need_packetized = true;
+
return VLC_SUCCESS;
}
diff --git a/modules/demux/mkv/matroska_segment_parse.cpp b/modules/demux/mkv/matroska_segment_parse.cpp
index 7792667..845d387 100644
--- a/modules/demux/mkv/matroska_segment_parse.cpp
+++ b/modules/demux/mkv/matroska_segment_parse.cpp
@@ -1369,6 +1369,7 @@ int32_t matroska_segment_c::TrackInit( mkv_track_t * p_tk )
else if( !strncmp( p_tk->psz_codec, "V_VP9", 5 ) )
{
p_tk->fmt.i_codec = VLC_CODEC_VP9;
+ p_tk->fmt.b_packetized = false;
fill_extra_data( p_tk, 0 );
}
else if( !strncmp( p_tk->psz_codec, "V_MPEG4", 7 ) )
diff --git a/modules/packetizer/Modules.am b/modules/packetizer/Modules.am
index 15b1190..e07880b 100644
--- a/modules/packetizer/Modules.am
+++ b/modules/packetizer/Modules.am
@@ -9,6 +9,14 @@ SOURCES_packetizer_dirac = dirac.c
SOURCES_packetizer_flac = flac.c
SOURCES_packetizer_hevc = hevc.c
+libpacketizer_avparser_plugin_la_SOURCES = avparser.c \
+ ../codec/avcodec/avcommon.h \
+ ../codec/avcodec/avcodec.h \
+ ../codec/avcodec/fourcc.c
+
+libpacketizer_avparser_plugin_la_CFLAGS = $(AVCODEC_CFLAGS) $(AVUTIL_CFLAGS) $(AM_CFLAGS)
+libpacketizer_avparser_plugin_la_LIBADD = $(AVCODEC_LIBS) $(AVUTIL_LIBS) $(LIBM)
+
noinst_HEADERS = packetizer_helper.h
packetizer_LTLIBRARIES += \
@@ -25,3 +33,6 @@ packetizer_LTLIBRARIES += \
if ENABLE_SOUT
packetizer_LTLIBRARIES += libpacketizer_copy_plugin.la
endif
+if HAVE_AVCODEC
+packetizer_LTLIBRARIES += libpacketizer_avparser_plugin.la
+endif
diff --git a/modules/packetizer/avparser.c b/modules/packetizer/avparser.c
new file mode 100644
index 0000000..d172462
--- /dev/null
+++ b/modules/packetizer/avparser.c
@@ -0,0 +1,188 @@
+/*****************************************************************************
+ * avparser.c
+ *****************************************************************************
+ * Copyright (C) 2015 VLC authors and VideoLAN
+ * $Id$
+ *
+ * Authors: Denis Charmet <typx at videolan.org>
+ *
+ * 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.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_codec.h>
+#include <vlc_block.h>
+
+#include "../codec/avcodec/avcodec.h"
+#include "../codec/avcodec/avcommon.h"
+
+/*****************************************************************************
+ * Module descriptor
+ *****************************************************************************/
+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_("avparser packetizer") )
+ set_capability( "packetizer", 1 )
+ set_callbacks( Open, Close )
+vlc_module_end ()
+
+/*****************************************************************************
+ * Local prototypes
+ *****************************************************************************/
+struct decoder_sys_t
+{
+ AVCodecParserContext * p_parser_ctx;
+ AVCodecContext * p_codec_ctx;
+ int i_offset;
+};
+
+static block_t * Packetize( decoder_t *, block_t ** );
+
+/*****************************************************************************
+ * Open: probe the packetizer and return score
+ *****************************************************************************
+ * Tries to launch a decoder and return score so that the interface is able
+ * to choose.
+ *****************************************************************************/
+static int Open( vlc_object_t *p_this )
+{
+ decoder_t *p_dec = (decoder_t*)p_this;
+ decoder_sys_t *p_sys;
+
+ /* Restrict to VP9 for now */
+ if( p_dec->fmt_in.i_codec != VLC_CODEC_VP9 )
+ return VLC_EGENERIC;
+
+ unsigned i_avcodec_id;
+
+ if( !GetFfmpegCodec( p_dec->fmt_in.i_codec, NULL, &i_avcodec_id, NULL ) )
+ return VLC_EGENERIC;
+
+ /* init avcodec */
+ vlc_init_avcodec(p_this);
+
+ /* It is less likely to have a parser than a codec, start by that */
+ AVCodecParserContext * p_ctx = av_parser_init( i_avcodec_id );
+ if( !p_ctx )
+ return VLC_EGENERIC;
+
+ AVCodec * p_codec = avcodec_find_decoder( i_avcodec_id );
+ if( unlikely( !p_codec ) )
+ {
+ av_parser_close( p_ctx );
+ return VLC_EGENERIC;
+ }
+
+ AVCodecContext * p_codec_ctx = avcodec_alloc_context3( p_codec );
+ if( unlikely( !p_codec_ctx ) )
+ {
+ av_parser_close( p_ctx );
+ return VLC_ENOMEM;
+ }
+
+ p_dec->p_sys = p_sys = malloc( sizeof(*p_sys) );
+
+ if( unlikely( !p_sys ) )
+ {
+ avcodec_free_context( &p_codec_ctx );
+ av_parser_close( p_ctx );
+ return VLC_ENOMEM;
+ }
+ p_dec->pf_packetize = Packetize;
+ p_sys->p_parser_ctx = p_ctx;
+ p_sys->p_codec_ctx = p_codec_ctx;
+ p_sys->i_offset = 0;
+ es_format_Copy( &p_dec->fmt_out, &p_dec->fmt_in );
+
+ return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * Close:
+ *****************************************************************************/
+static void Close( vlc_object_t *p_this )
+{
+ decoder_t *p_dec = (decoder_t*)p_this;
+ avcodec_free_context( &p_dec->p_sys->p_codec_ctx );
+ av_parser_close( p_dec->p_sys->p_parser_ctx );
+ es_format_Clean( &p_dec->fmt_out );
+ free( p_dec->p_sys );
+}
+
+/*****************************************************************************
+ * Packetize: packetize a frame
+ *****************************************************************************/
+static block_t *Packetize ( decoder_t *p_dec, block_t **pp_block )
+{
+ decoder_sys_t *p_sys = p_dec->p_sys;
+
+ if( pp_block == NULL || *pp_block == NULL )
+ return NULL;
+ if( (*pp_block)->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
+ {
+ block_Release( *pp_block );
+ return NULL;
+ }
+
+ block_t * p_block = *pp_block;
+
+ uint8_t * p_indata = p_block->p_buffer + p_sys->i_offset;
+ int i_inlen = p_block->i_buffer - p_sys->i_offset;
+ uint8_t * p_outdata;
+ int i_outlen;
+
+ if( p_sys->i_offset == i_inlen )
+ goto out;
+
+ p_sys->i_offset += av_parser_parse2( p_sys->p_parser_ctx, p_sys->p_codec_ctx,
+ &p_outdata, &i_outlen, p_indata, i_inlen,
+ p_block->i_pts, p_block->i_dts, -1);
+
+ if( unlikely( i_outlen <= 0 || !p_outdata ) )
+ goto out;
+
+ block_t * p_ret = block_Alloc( i_outlen );
+
+ if( unlikely ( !p_ret ) )
+ goto out;
+
+ memcpy( p_ret->p_buffer, p_outdata, i_outlen );
+ p_ret->i_pts = p_block->i_pts;
+ p_ret->i_dts = p_block->i_dts;
+
+ p_block->i_pts = p_block->i_dts = VLC_TS_INVALID;
+
+ return p_ret;
+
+out:
+ p_sys->i_offset = 0;
+ block_Release( *pp_block );
+ *pp_block == NULL;
+ return NULL;
+}
+
diff --git a/po/POTFILES.in b/po/POTFILES.in
index f6f7e7e..142f928 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -990,6 +990,7 @@ modules/mux/ogg.c
modules/mux/wav.c
modules/notify/growl.m
modules/notify/notify.c
+modules/packetizer/avparser.c
modules/packetizer/copy.c
modules/packetizer/dirac.c
modules/packetizer/flac.c
More information about the vlc-commits
mailing list