1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2015 VLC authors and VideoLAN
6 * Authors: Denis Charmet <typx@videolan.org>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
23 /*****************************************************************************
25 *****************************************************************************/
31 #include <vlc_common.h>
32 #include <vlc_plugin.h>
33 #include <vlc_codec.h>
34 #include <vlc_block.h>
36 #include "../codec/avcodec/avcodec.h"
37 #include "../codec/avcodec/avcommon.h"
40 /*****************************************************************************
42 *****************************************************************************/
49 /*****************************************************************************
51 *****************************************************************************/
54 AVCodecParserContext
* p_parser_ctx
;
55 AVCodecContext
* p_codec_ctx
;
59 static block_t
* Packetize( decoder_t
*, block_t
** );
60 static block_t
* PacketizeClosed( decoder_t
*, block_t
** );
62 /*****************************************************************************
63 * FlushPacketizer: reopen as there's no clean way to flush avparser
64 *****************************************************************************/
65 static void FlushPacketizer( decoder_t
*p_dec
)
67 avparser_ClosePacketizer( VLC_OBJECT( p_dec
) );
69 int res
= avparser_OpenPacketizer( VLC_OBJECT( p_dec
) );
70 if ( res
!= VLC_SUCCESS
)
72 msg_Err( p_dec
, "failed to flush with error %d", res
);
73 p_dec
->pf_packetize
= PacketizeClosed
;
77 /*****************************************************************************
78 * avparser_OpenPacketizer: probe the packetizer and return score
79 *****************************************************************************
80 * Tries to launch a decoder and return score so that the interface is able
82 *****************************************************************************/
83 int avparser_OpenPacketizer( vlc_object_t
*p_this
)
85 decoder_t
*p_dec
= (decoder_t
*)p_this
;
88 /* Restrict to VP9 for now */
89 if( p_dec
->fmt_in
.i_codec
!= VLC_CODEC_VP9
)
92 unsigned i_avcodec_id
;
94 if( !GetFfmpegCodec( p_dec
->fmt_in
.i_cat
, p_dec
->fmt_in
.i_codec
,
95 &i_avcodec_id
, NULL
) )
99 vlc_init_avcodec(p_this
);
101 /* It is less likely to have a parser than a codec, start by that */
102 AVCodecParserContext
* p_ctx
= av_parser_init( i_avcodec_id
);
106 AVCodec
* p_codec
= avcodec_find_decoder( i_avcodec_id
);
107 if( unlikely( !p_codec
) )
109 av_parser_close( p_ctx
);
113 AVCodecContext
* p_codec_ctx
= avcodec_alloc_context3( p_codec
);
114 if( unlikely( !p_codec_ctx
) )
116 av_parser_close( p_ctx
);
120 p_dec
->p_sys
= p_sys
= malloc( sizeof(*p_sys
) );
122 if( unlikely( !p_sys
) )
124 avcodec_free_context( &p_codec_ctx
);
125 av_parser_close( p_ctx
);
128 p_dec
->pf_packetize
= Packetize
;
129 p_dec
->pf_flush
= FlushPacketizer
;
130 p_dec
->pf_get_cc
= NULL
;
131 p_sys
->p_parser_ctx
= p_ctx
;
132 p_sys
->p_codec_ctx
= p_codec_ctx
;
134 es_format_Copy( &p_dec
->fmt_out
, &p_dec
->fmt_in
);
139 /*****************************************************************************
140 * avparser_ClosePacketizer:
141 *****************************************************************************/
142 void avparser_ClosePacketizer( vlc_object_t
*p_this
)
144 decoder_t
*p_dec
= (decoder_t
*)p_this
;
145 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
146 if (likely( p_sys
!= NULL
))
148 avcodec_free_context( &p_sys
->p_codec_ctx
);
149 av_parser_close( p_sys
->p_parser_ctx
);
154 /*****************************************************************************
155 * Packetize: packetize a frame
156 *****************************************************************************/
157 static block_t
*Packetize ( decoder_t
*p_dec
, block_t
**pp_block
)
159 decoder_sys_t
*p_sys
= p_dec
->p_sys
;
161 if( pp_block
== NULL
|| *pp_block
== NULL
)
163 if( (*pp_block
)->i_flags
&(BLOCK_FLAG_CORRUPTED
) )
165 block_Release( *pp_block
);
169 block_t
* p_block
= *pp_block
;
171 uint8_t * p_indata
= p_block
->p_buffer
+ p_sys
->i_offset
;
172 int i_inlen
= p_block
->i_buffer
- p_sys
->i_offset
;
176 if( p_sys
->i_offset
== i_inlen
)
179 p_sys
->i_offset
+= av_parser_parse2( p_sys
->p_parser_ctx
, p_sys
->p_codec_ctx
,
180 &p_outdata
, &i_outlen
, p_indata
, i_inlen
,
181 TO_AV_TS(p_block
->i_pts
), TO_AV_TS(p_block
->i_dts
), -1);
183 if( unlikely( i_outlen
<= 0 || !p_outdata
) )
186 block_t
* p_ret
= block_Alloc( i_outlen
);
188 if( unlikely ( !p_ret
) )
191 p_ret
->i_flags
= p_block
->i_flags
;
193 if( p_block
->i_flags
& BLOCK_FLAG_DISCONTINUITY
)
194 p_block
->i_flags
&= ~BLOCK_FLAG_DISCONTINUITY
;
196 memcpy( p_ret
->p_buffer
, p_outdata
, i_outlen
);
197 p_ret
->i_pts
= p_block
->i_pts
;
198 p_ret
->i_dts
= p_block
->i_dts
;
199 if( p_sys
->p_parser_ctx
->key_frame
== 1 )
200 p_ret
->i_flags
|= BLOCK_FLAG_TYPE_I
;
202 p_block
->i_pts
= p_block
->i_dts
= VLC_TICK_INVALID
;
208 block_Release( *pp_block
);
213 /*****************************************************************************
214 * PacketizeClosed: packetizer called after a flush failed
215 *****************************************************************************/
216 static block_t
*PacketizeClosed ( decoder_t
*p_dec
, block_t
**pp_block
)
219 if( pp_block
!= NULL
&& *pp_block
!= NULL
)
220 block_Release( *pp_block
);