vlc | branch: master | Denis Charmet <[email protected]> | Thu Feb 26 17:32:29 2015 +0100| [17e07afce4d26cfecf6ab5252c738cd8a0e9756a] | committer: Jean-Baptiste Kempf
Add avparser packetizer for VP9 handling Fix #12944 Signed-off-by: Jean-Baptiste Kempf <[email protected]> > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=17e07afce4d26cfecf6ab5252c738cd8a0e9756a --- modules/MODULES_LIST | 1 + modules/codec/avcodec/video.c | 4 + modules/demux/mkv/matroska_segment_parse.cpp | 1 + modules/packetizer/Makefile.am | 13 ++ modules/packetizer/avparser.c | 188 ++++++++++++++++++++++++++ po/POTFILES.in | 1 + 6 files changed, 208 insertions(+) diff --git a/modules/MODULES_LIST b/modules/MODULES_LIST index 68bf31f..a48f2c2 100644 --- a/modules/MODULES_LIST +++ b/modules/MODULES_LIST @@ -262,6 +262,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 5ba6e2e..381fe62 100644 --- a/modules/codec/avcodec/video.c +++ b/modules/codec/avcodec/video.c @@ -454,6 +454,10 @@ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context, } p_dec->pf_decode_video = DecodeVideo; + + 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 7f3bcb2..ff47a2b5 100644 --- a/modules/demux/mkv/matroska_segment_parse.cpp +++ b/modules/demux/mkv/matroska_segment_parse.cpp @@ -1370,6 +1370,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/Makefile.am b/modules/packetizer/Makefile.am index ff28b08..ce71ce2 100644 --- a/modules/packetizer/Makefile.am +++ b/modules/packetizer/Makefile.am @@ -13,6 +13,14 @@ libpacketizer_dirac_plugin_la_SOURCES = packetizer/dirac.c libpacketizer_flac_plugin_la_SOURCES = packetizer/flac.c libpacketizer_hevc_plugin_la_SOURCES = packetizer/hevc.c +libpacketizer_avparser_plugin_la_SOURCES = packetizer/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/packetizer_helper.h packetizer_LTLIBRARIES = \ @@ -29,3 +37,8 @@ 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 <[email protected]> + * + * 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 03880df..b679347 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -998,6 +998,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 _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
