vlc/vlc-2.2 | branch: master | Denis Charmet <[email protected]> | 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 <[email protected]> (cherry picked from commit 17e07afce4d26cfecf6ab5252c738cd8a0e9756a) Signed-off-by: Jean-Baptiste Kempf <[email protected]> > 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 <[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 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 _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
