1 /*****************************************************************************
2 * hevc.c : HEVC Video demuxer
3 *****************************************************************************
4 * Copyright (C) 2014 VLC authors and VideoLAN
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 /*****************************************************************************
26 *****************************************************************************/
32 #include <vlc_common.h>
33 #include <vlc_plugin.h>
34 #include <vlc_demux.h>
35 #include <vlc_codec.h>
38 #include "mpeg_parser_helpers.h"
40 /*****************************************************************************
42 *****************************************************************************/
43 static int Open ( vlc_object_t * );
44 static void Close( vlc_object_t * );
46 #define FPS_TEXT N_("Frames per Second")
47 #define FPS_LONGTEXT N_("Desired frame rate for the stream.")
51 set_shortname( "HEVC")
52 set_category( CAT_INPUT )
53 set_subcategory( SUBCAT_INPUT_DEMUX )
54 set_description( N_("HEVC/H.265 video demuxer" ) )
55 set_capability( "demux", 0 )
56 add_float( "hevc-force-fps", 0.0, FPS_TEXT, FPS_LONGTEXT, true )
57 set_callbacks( Open, Close )
58 add_shortcut( "hevc" )
61 /*****************************************************************************
63 *****************************************************************************/
65 static int Demux( demux_t * );
66 static int Control( demux_t *, int, va_list );
67 static int32_t getFPS( demux_t *, block_t * );
76 decoder_t *p_packetizer;
78 #define HEVC_BLOCK_SIZE 2048
80 /*****************************************************************************
81 * Open: initializes demux structures
82 *****************************************************************************/
83 static int Open( vlc_object_t * p_this )
85 demux_t *p_demux = (demux_t*)p_this;
87 const uint8_t *p_peek;
90 if( stream_Peek( p_demux->s, &p_peek, 5 ) < 5 ) return VLC_EGENERIC;
92 if( p_peek[0] != 0x00 || p_peek[1] != 0x00 ||
93 p_peek[2] != 0x00 || p_peek[3] != 0x01 ||
94 (p_peek[4]&0xFE) != 0x40 ) /* VPS & forbidden zero bit*/
96 if( !p_demux->b_force )
98 msg_Warn( p_demux, "hevc module discarded (no startcode)" );
102 msg_Err( p_demux, "this doesn't look like a HEVC ES stream, "
103 "continuing anyway" );
106 p_demux->p_sys = p_sys = malloc( sizeof( demux_sys_t ) );
108 if( !p_demux->p_sys )
112 p_sys->i_dts = VLC_TS_0;
113 p_sys->f_force_fps = var_CreateGetFloat( p_demux, "hevc-force-fps" );
114 if( p_sys->f_force_fps != 0.0f )
116 p_sys->f_fps = ( p_sys->f_force_fps < 0.001f )? 0.001f:
118 msg_Dbg( p_demux, "using %.2f fps", p_sys->f_fps );
123 /* Load the hevc packetizer */
124 es_format_Init( &fmt, VIDEO_ES, VLC_CODEC_HEVC );
125 p_sys->p_packetizer = demux_PacketizerNew( p_demux, &fmt, "hevc" );
126 if( !p_sys->p_packetizer )
132 p_sys->p_packetizer->fmt_out.b_packetized = true;
133 p_sys->p_es = es_out_Add( p_demux->out, &p_sys->p_packetizer->fmt_out);
137 demux_PacketizerDestroy( p_sys->p_packetizer );
141 p_demux->pf_demux = Demux;
142 p_demux->pf_control= Control;
147 /*****************************************************************************
148 * Close: frees unused data
149 *****************************************************************************/
150 static void Close( vlc_object_t * p_this )
152 demux_t *p_demux = (demux_t*)p_this;
153 demux_sys_t *p_sys = p_demux->p_sys;
155 demux_PacketizerDestroy( p_sys->p_packetizer );
159 /*****************************************************************************
160 * Demux: reads and demuxes data packets
161 *****************************************************************************
162 * Returns -1 in case of error, 0 in case of EOF, 1 otherwise
163 *****************************************************************************/
164 static int Demux( demux_t *p_demux)
166 demux_sys_t *p_sys = p_demux->p_sys;
167 block_t *p_block_in, *p_block_out;
169 if( ( p_block_in = stream_Block( p_demux->s, HEVC_BLOCK_SIZE ) ) == NULL )
174 p_block_in->i_dts = VLC_TS_INVALID;
175 p_block_in->i_pts = VLC_TS_INVALID;
177 while( (p_block_out = p_sys->p_packetizer->pf_packetize( p_sys->p_packetizer, &p_block_in )) )
181 block_t *p_next = p_block_out->p_next;
183 p_block_out->p_next = NULL;
185 p_block_out->i_dts = p_sys->i_dts;
186 p_block_out->i_pts = VLC_TS_INVALID;
188 uint8_t nal_type = p_block_out->p_buffer[4] & 0x7E;
190 /*Get fps from vps if available and not already forced*/
191 if( p_sys->f_fps == 0.0f && nal_type == 0x40 )
193 if( getFPS( p_demux, p_block_out) )
195 msg_Err(p_demux,"getFPS failed");
200 /* Update DTS only on VCL NAL*/
201 if( nal_type < 0x40 && p_sys->f_fps )
203 es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_dts );
204 p_sys->i_dts += (int64_t)((double)1000000.0 / p_sys->f_fps);
207 es_out_Send( p_demux->out, p_sys->p_es, p_block_out );
209 p_block_out = p_next;
216 /*****************************************************************************
218 *****************************************************************************/
219 static int Control( demux_t *p_demux, int i_query, va_list args )
221 return demux_vaControlHelper( p_demux->s,
223 0, 1, i_query, args );
227 static uint8_t * CreateDecodedNAL( int *pi_ret,
228 const uint8_t *src, int i_src )
230 uint8_t *dst = malloc( i_src );
234 *pi_ret = nal_decode( src, dst, i_src );
238 static int32_t getFPS( demux_t *p_demux, block_t * p_block )
240 demux_sys_t *p_sys = p_demux->p_sys;
243 uint8_t * p_decoded_nal;
246 if( p_block->i_buffer < 5 )
249 p_decoded_nal = CreateDecodedNAL(&i_decoded_nal,
250 p_block->p_buffer+4, p_block->i_buffer-4);
255 bs_init( &bs, p_decoded_nal, i_decoded_nal );
257 int32_t max_sub_layer_minus1 = bs_read( &bs, 3 );
260 hevc_skip_profile_tiers_level( &bs, max_sub_layer_minus1 );
262 int32_t vps_sub_layer_ordering_info_present_flag = bs_read1( &bs );
263 int32_t i = vps_sub_layer_ordering_info_present_flag? 0 : max_sub_layer_minus1;
264 for( ; i <= max_sub_layer_minus1; i++ )
270 uint32_t vps_max_layer_id = bs_read( &bs, 6);
271 uint32_t vps_num_layer_sets_minus1 = read_ue( &bs );
272 bs_skip( &bs, vps_max_layer_id * vps_num_layer_sets_minus1 );
276 uint32_t num_units_in_tick = bs_read( &bs, 32 );
277 uint32_t time_scale = bs_read( &bs, 32 );
278 if( num_units_in_tick )
280 p_sys->f_fps = ( (float) time_scale )/( (float) num_units_in_tick );
281 msg_Dbg(p_demux,"Using framerate %f fps from VPS", p_sys->f_fps);
285 msg_Err( p_demux, "vps_num_units_in_tick null defaulting to 25 fps");
286 p_sys->f_fps = 25.0f;
291 msg_Err( p_demux, "No timing info in VPS defaulting to 25 fps");
292 p_sys->f_fps = 25.0f;