packetizer: hevc: add poc debug
[vlc.git] / modules / packetizer / avparser.c
blobf7792bfaf818b235764e80bc8275c906dbf91b4f
1 /*****************************************************************************
2 * avparser.c
3 *****************************************************************************
4 * Copyright (C) 2015 VLC authors and VideoLAN
5 * $Id$
7 * Authors: Denis Charmet <typx@videolan.org>
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU Lesser General Public License as published by
11 * the Free Software Foundation; either version 2.1 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program; if not, write to the Free Software Foundation,
21 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
25 * Preamble
26 *****************************************************************************/
28 #ifdef HAVE_CONFIG_H
29 # include "config.h"
30 #endif
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_codec.h>
35 #include <vlc_block.h>
37 #include "../codec/avcodec/avcodec.h"
38 #include "../codec/avcodec/avcommon.h"
40 #include "avparser.h"
41 /*****************************************************************************
42 * Module descriptor
43 *****************************************************************************/
44 #ifndef MERGE_FFMPEG
45 vlc_module_begin ()
46 AVPARSER_MODULE
47 vlc_module_end ()
48 #endif
50 /*****************************************************************************
51 * Local prototypes
52 *****************************************************************************/
53 struct decoder_sys_t
55 AVCodecParserContext * p_parser_ctx;
56 AVCodecContext * p_codec_ctx;
57 int i_offset;
60 static block_t * Packetize( decoder_t *, block_t ** );
61 static block_t * PacketizeClosed( decoder_t *, block_t ** );
63 /*****************************************************************************
64 * FlushPacketizer: reopen as there's no clean way to flush avparser
65 *****************************************************************************/
66 static void FlushPacketizer( decoder_t *p_dec )
68 ClosePacketizer( VLC_OBJECT( p_dec ) );
69 p_dec->p_sys = NULL;
70 int res = OpenPacketizer( VLC_OBJECT( p_dec ) );
71 if ( res != VLC_SUCCESS )
73 msg_Err( p_dec, "failed to flush with error %d", res );
74 p_dec->pf_packetize = PacketizeClosed;
78 /*****************************************************************************
79 * OpenPacketizer: probe the packetizer and return score
80 *****************************************************************************
81 * Tries to launch a decoder and return score so that the interface is able
82 * to choose.
83 *****************************************************************************/
84 int OpenPacketizer( vlc_object_t *p_this )
86 decoder_t *p_dec = (decoder_t*)p_this;
87 decoder_sys_t *p_sys;
89 /* Restrict to VP9 for now */
90 if( p_dec->fmt_in.i_codec != VLC_CODEC_VP9 )
91 return VLC_EGENERIC;
93 unsigned i_avcodec_id;
95 if( !GetFfmpegCodec( p_dec->fmt_in.i_cat, p_dec->fmt_in.i_codec,
96 &i_avcodec_id, NULL ) )
97 return VLC_EGENERIC;
99 /* init avcodec */
100 vlc_init_avcodec(p_this);
102 /* It is less likely to have a parser than a codec, start by that */
103 AVCodecParserContext * p_ctx = av_parser_init( i_avcodec_id );
104 if( !p_ctx )
105 return VLC_EGENERIC;
107 AVCodec * p_codec = avcodec_find_decoder( i_avcodec_id );
108 if( unlikely( !p_codec ) )
110 av_parser_close( p_ctx );
111 return VLC_EGENERIC;
114 AVCodecContext * p_codec_ctx = avcodec_alloc_context3( p_codec );
115 if( unlikely( !p_codec_ctx ) )
117 av_parser_close( p_ctx );
118 return VLC_ENOMEM;
121 p_dec->p_sys = p_sys = malloc( sizeof(*p_sys) );
123 if( unlikely( !p_sys ) )
125 avcodec_free_context( &p_codec_ctx );
126 av_parser_close( p_ctx );
127 return VLC_ENOMEM;
129 p_dec->pf_packetize = Packetize;
130 p_dec->pf_flush = FlushPacketizer;
131 p_sys->p_parser_ctx = p_ctx;
132 p_sys->p_codec_ctx = p_codec_ctx;
133 p_sys->i_offset = 0;
134 es_format_Copy( &p_dec->fmt_out, &p_dec->fmt_in );
136 return VLC_SUCCESS;
139 /*****************************************************************************
140 * ClosePacketizer:
141 *****************************************************************************/
142 void ClosePacketizer( vlc_object_t *p_this )
144 decoder_t *p_dec = (decoder_t*)p_this;
145 if (likely( p_dec->p_sys != NULL ))
147 avcodec_free_context( &p_dec->p_sys->p_codec_ctx );
148 av_parser_close( p_dec->p_sys->p_parser_ctx );
149 free( p_dec->p_sys );
153 /*****************************************************************************
154 * Packetize: packetize a frame
155 *****************************************************************************/
156 static block_t *Packetize ( decoder_t *p_dec, block_t **pp_block )
158 decoder_sys_t *p_sys = p_dec->p_sys;
160 if( pp_block == NULL || *pp_block == NULL )
161 return NULL;
162 if( (*pp_block)->i_flags&(BLOCK_FLAG_CORRUPTED) )
164 block_Release( *pp_block );
165 return NULL;
168 block_t * p_block = *pp_block;
170 uint8_t * p_indata = p_block->p_buffer + p_sys->i_offset;
171 int i_inlen = p_block->i_buffer - p_sys->i_offset;
172 uint8_t * p_outdata;
173 int i_outlen;
175 if( p_sys->i_offset == i_inlen )
176 goto out;
178 p_sys->i_offset += av_parser_parse2( p_sys->p_parser_ctx, p_sys->p_codec_ctx,
179 &p_outdata, &i_outlen, p_indata, i_inlen,
180 p_block->i_pts, p_block->i_dts, -1);
182 if( unlikely( i_outlen <= 0 || !p_outdata ) )
183 goto out;
185 block_t * p_ret = block_Alloc( i_outlen );
187 if( unlikely ( !p_ret ) )
188 goto out;
190 memcpy( p_ret->p_buffer, p_outdata, i_outlen );
191 p_ret->i_pts = p_block->i_pts;
192 p_ret->i_dts = p_block->i_dts;
194 p_block->i_pts = p_block->i_dts = VLC_TS_INVALID;
196 return p_ret;
198 out:
199 p_sys->i_offset = 0;
200 block_Release( *pp_block );
201 *pp_block = NULL;
202 return NULL;
205 /*****************************************************************************
206 * PacketizeClosed: packetizer called after a flush failed
207 *****************************************************************************/
208 static block_t *PacketizeClosed ( decoder_t *p_dec, block_t **pp_block )
210 (void) p_dec;
211 if( pp_block != NULL && *pp_block != NULL )
212 block_Release( *pp_block );
213 return NULL;