Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc
Commits
ed686b09
Commit
ed686b09
authored
Feb 22, 2014
by
Denis Charmet
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Allow hevc muxing in mp4
parent
52a59eb4
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
327 additions
and
75 deletions
+327
-75
modules/demux/Makefile.am
modules/demux/Makefile.am
+1
-1
modules/demux/mpeg/hevc.c
modules/demux/mpeg/hevc.c
+13
-65
modules/demux/mpeg/mpeg_parser_helpers.h
modules/demux/mpeg/mpeg_parser_helpers.h
+81
-0
modules/mux/Modules.am
modules/mux/Modules.am
+1
-1
modules/mux/mp4.c
modules/mux/mp4.c
+229
-6
modules/packetizer/hevc.c
modules/packetizer/hevc.c
+2
-2
No files found.
modules/demux/Makefile.am
View file @
ed686b09
...
...
@@ -162,7 +162,7 @@ demux_LTLIBRARIES += libes_plugin.la
libh264_plugin_la_SOURCES
=
demux/mpeg/h264.c
demux_LTLIBRARIES
+=
libh264_plugin.la
libhevc_plugin_la_SOURCES
=
demux/mpeg/hevc.c
libhevc_plugin_la_SOURCES
=
demux/mpeg/hevc.c
demux/mpeg/mpeg_parser_helpers.h
demux_LTLIBRARIES
+=
libhevc_plugin.la
libmkv_plugin_la_SOURCES
=
\
...
...
modules/demux/mpeg/hevc.c
View file @
ed686b09
...
...
@@ -35,6 +35,7 @@
#include <vlc_codec.h>
#include <vlc_bits.h>
#include "mpeg_parser_helpers.h"
/*****************************************************************************
* Module descriptor
...
...
@@ -108,7 +109,7 @@ static int Open( vlc_object_t * p_this )
return
VLC_ENOMEM
;
p_sys
->
p_es
=
NULL
;
p_sys
->
i_dts
=
0
;
p_sys
->
i_dts
=
VLC_TS_
0
;
p_sys
->
f_force_fps
=
var_CreateGetFloat
(
p_demux
,
"hevc-force-fps"
);
if
(
p_sys
->
f_force_fps
!=
0
.
0
f
)
{
...
...
@@ -181,11 +182,13 @@ static int Demux( demux_t *p_demux)
p_block_out
->
p_next
=
NULL
;
p_block_out
->
i_dts
=
VLC_TS_0
+
p_sys
->
i_dts
;
p_block_out
->
i_dts
=
p_sys
->
i_dts
;
p_block_out
->
i_pts
=
VLC_TS_INVALID
;
uint8_t
nal_type
=
p_block_out
->
p_buffer
[
4
]
&
0x7E
;
/*Get fps from vps if available and not already forced*/
if
(
p_sys
->
f_fps
==
0
.
0
f
&&
(
p_block_out
->
p_buffer
[
3
]
&
0x7E
)
==
0x40
)
if
(
p_sys
->
f_fps
==
0
.
0
f
&&
nal_type
==
0x40
)
{
if
(
getFPS
(
p_demux
,
p_block_out
)
)
{
...
...
@@ -195,7 +198,7 @@ static int Demux( demux_t *p_demux)
}
/* Update DTS only on VCL NAL*/
if
(
(
p_block_out
->
p_buffer
[
3
]
&
0x7E
)
<
0x40
&&
p_sys
->
f_fps
)
if
(
nal_type
<
0x40
&&
p_sys
->
f_fps
)
{
es_out_Control
(
p_demux
->
out
,
ES_OUT_SET_PCR
,
p_sys
->
i_dts
);
p_sys
->
i_dts
+=
(
int64_t
)((
double
)
1000000
.
0
/
p_sys
->
f_fps
);
...
...
@@ -221,70 +224,15 @@ static int Control( demux_t *p_demux, int i_query, va_list args )
}
static
void
CreateDecodedNAL
(
uint8_t
**
pp_ret
,
int
*
pi_ret
,
static
uint8_t
*
CreateDecodedNAL
(
int
*
pi_ret
,
const
uint8_t
*
src
,
int
i_src
)
{
const
uint8_t
*
end
=
&
src
[
i_src
];
uint8_t
*
dst
=
malloc
(
i_src
);
if
(
!
dst
)
return
;
*
pp_ret
=
dst
;
if
(
dst
)
{
while
(
src
<
end
)
{
if
(
src
<
end
-
3
&&
src
[
0
]
==
0x00
&&
src
[
1
]
==
0x00
&&
src
[
2
]
==
0x03
)
{
*
dst
++
=
0x00
;
*
dst
++
=
0x00
;
src
+=
3
;
continue
;
}
*
dst
++
=
*
src
++
;
}
}
*
pi_ret
=
dst
-
*
pp_ret
;
}
static
void
skipProfileTiersLevel
(
bs_t
*
bs
,
int32_t
max_sub_layer_minus1
)
{
uint8_t
sub_layer_profile_present_flag
[
8
];
uint8_t
sub_layer_level_present_flag
[
8
];
/* skipping useless fields of the VPS see https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-H.265-201304-I!!PDF-E&type=item */
bs_skip
(
bs
,
2
+
1
+
5
+
32
+
1
+
1
+
1
+
1
+
44
+
8
);
for
(
int32_t
i
=
0
;
i
<
max_sub_layer_minus1
;
i
++
)
{
sub_layer_profile_present_flag
[
i
]
=
bs_read1
(
bs
);
sub_layer_level_present_flag
[
i
]
=
bs_read1
(
bs
);
}
if
(
max_sub_layer_minus1
>
0
)
bs_skip
(
bs
,
(
8
-
max_sub_layer_minus1
)
*
2
);
for
(
int32_t
i
=
0
;
i
<
max_sub_layer_minus1
;
i
++
)
{
if
(
sub_layer_profile_present_flag
[
i
]
)
bs_skip
(
bs
,
2
+
1
+
5
+
32
+
1
+
1
+
1
+
1
+
44
);
if
(
sub_layer_level_present_flag
[
i
]
)
bs_skip
(
bs
,
8
);
}
}
static
uint32_t
read_ue
(
bs_t
*
bs
)
{
int32_t
i
=
0
;
while
(
bs_read1
(
bs
)
==
0
&&
bs
->
p
<
bs
->
p_end
&&
i
<
32
)
i
++
;
return
(
1
<<
i
)
-
1
+
bs_read
(
bs
,
i
);
*
pi_ret
=
nal_decode
(
src
,
dst
,
i_src
);
return
dst
;
}
static
int32_t
getFPS
(
demux_t
*
p_demux
,
block_t
*
p_block
)
...
...
@@ -298,8 +246,8 @@ static int32_t getFPS( demux_t *p_demux, block_t * p_block )
if
(
p_block
->
i_buffer
<
5
)
return
-
1
;
CreateDecodedNAL
(
&
p_decoded_nal
,
&
i_decoded_nal
,
p_block
->
p_buffer
+
3
,
p_block
->
i_buffer
-
3
);
p_decoded_nal
=
CreateDecodedNAL
(
&
i_decoded_nal
,
p_block
->
p_buffer
+
4
,
p_block
->
i_buffer
-
4
);
if
(
!
p_decoded_nal
)
return
-
1
;
...
...
@@ -309,7 +257,7 @@ static int32_t getFPS( demux_t *p_demux, block_t * p_block )
int32_t
max_sub_layer_minus1
=
bs_read
(
&
bs
,
3
);
bs_skip
(
&
bs
,
17
);
skipProfileTiersL
evel
(
&
bs
,
max_sub_layer_minus1
);
hevc_skip_profile_tiers_l
evel
(
&
bs
,
max_sub_layer_minus1
);
int32_t
vps_sub_layer_ordering_info_present_flag
=
bs_read1
(
&
bs
);
int32_t
i
=
vps_sub_layer_ordering_info_present_flag
?
0
:
max_sub_layer_minus1
;
...
...
modules/demux/mpeg/mpeg_parser_helpers.h
0 → 100644
View file @
ed686b09
/*****************************************************************************
* packetizer_helper.h: Packetizer helpers
*****************************************************************************
* Copyright (C) 2014 VLC authors and VideoLAN
* $Id$
*
* Authors: Denis Charmet <typx@videolan.org>
*
* 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.
*****************************************************************************/
#ifndef MPEG_PARSER_HELPERS_H
#define MPEG_PARSER_HELPERS_H
#include <stdint.h>
#include <vlc_bits.h>
static
inline
void
hevc_skip_profile_tiers_level
(
bs_t
*
bs
,
int32_t
max_sub_layer_minus1
)
{
uint8_t
sub_layer_profile_present_flag
[
8
];
uint8_t
sub_layer_level_present_flag
[
8
];
/* skipping useless fields of the VPS see https://www.itu.int/rec/dologin_pub.asp?lang=e&id=T-REC-H.265-201304-I!!PDF-E&type=item */
bs_skip
(
bs
,
2
+
1
+
5
+
32
+
1
+
1
+
1
+
1
+
44
+
8
);
for
(
int32_t
i
=
0
;
i
<
max_sub_layer_minus1
;
i
++
)
{
sub_layer_profile_present_flag
[
i
]
=
bs_read1
(
bs
);
sub_layer_level_present_flag
[
i
]
=
bs_read1
(
bs
);
}
if
(
max_sub_layer_minus1
>
0
)
bs_skip
(
bs
,
(
8
-
max_sub_layer_minus1
)
*
2
);
for
(
int32_t
i
=
0
;
i
<
max_sub_layer_minus1
;
i
++
)
{
if
(
sub_layer_profile_present_flag
[
i
]
)
bs_skip
(
bs
,
2
+
1
+
5
+
32
+
1
+
1
+
1
+
1
+
44
);
if
(
sub_layer_level_present_flag
[
i
]
)
bs_skip
(
bs
,
8
);
}
}
static
inline
uint32_t
read_ue
(
bs_t
*
bs
)
{
int32_t
i
=
0
;
while
(
bs_read1
(
bs
)
==
0
&&
bs
->
p
<
bs
->
p_end
&&
i
<
32
)
i
++
;
return
(
1
<<
i
)
-
1
+
bs_read
(
bs
,
i
);
}
static
inline
size_t
nal_decode
(
uint8_t
*
p_src
,
uint8_t
*
p_dst
,
size_t
i_size
)
{
size_t
j
=
0
;
for
(
size_t
i
=
0
;
i
<
i_size
;
i
++
)
{
if
(
i
<
i_size
-
3
&&
p_src
[
i
]
==
0
&&
p_src
[
i
+
1
]
==
0
&&
p_src
[
i
+
2
]
==
3
)
{
p_dst
[
j
++
]
=
0
;
p_dst
[
j
++
]
=
0
;
i
+=
2
;
continue
;
}
p_dst
[
j
++
]
=
p_src
[
i
];
}
return
j
;
}
#endif
/*MPEG_PARSER_HELPERS_H*/
modules/mux/Modules.am
View file @
ed686b09
SOURCES_mux_dummy = dummy.c
SOURCES_mux_avi = avi.c
SOURCES_mux_ogg = ogg.c
SOURCES_mux_mp4 = mp4.c
SOURCES_mux_mp4 = mp4.c
../demux/mpeg/mpeg_parser_helpers.h
SOURCES_mux_asf = asf.c ../demux/asf/libasf_guid.h
SOURCES_mux_wav = wav.c
SOURCES_mux_mpjpeg = mpjpeg.c
...
...
modules/mux/mp4.c
View file @
ed686b09
...
...
@@ -40,6 +40,8 @@
#include <vlc_iso_lang.h>
#include <vlc_meta.h>
#include "../demux/mpeg/mpeg_parser_helpers.h"
/*****************************************************************************
* Module descriptor
*****************************************************************************/
...
...
@@ -162,7 +164,7 @@ static void box_send(sout_mux_t *p_mux, bo_t *box);
static
bo_t
*
GetMoovBox
(
sout_mux_t
*
p_mux
);
static
block_t
*
ConvertSUBT
(
block_t
*
);
static
block_t
*
Convert
AVC1
(
block_t
*
);
static
block_t
*
Convert
FromAnnexB
(
block_t
*
);
static
const
char
avc1_start_code
[
4
]
=
{
0
,
0
,
0
,
1
};
...
...
@@ -448,8 +450,9 @@ static int Mux(sout_mux_t *p_mux)
block_t
*
p_data
;
do
{
p_data
=
block_FifoGet
(
p_input
->
p_fifo
);
if
(
p_stream
->
fmt
.
i_codec
==
VLC_CODEC_H264
)
p_data
=
ConvertAVC1
(
p_data
);
if
(
p_stream
->
fmt
.
i_codec
==
VLC_CODEC_H264
||
p_stream
->
fmt
.
i_codec
==
VLC_CODEC_HEVC
)
p_data
=
ConvertFromAnnexB
(
p_data
);
else
if
(
p_stream
->
fmt
.
i_codec
==
VLC_CODEC_SUBT
)
p_data
=
ConvertSUBT
(
p_data
);
}
while
(
!
p_data
);
...
...
@@ -580,7 +583,7 @@ static block_t *ConvertSUBT(block_t *p_block)
return
p_block
;
}
static
block_t
*
Convert
AVC1
(
block_t
*
p_block
)
static
block_t
*
Convert
FromAnnexB
(
block_t
*
p_block
)
{
uint8_t
*
last
=
p_block
->
p_buffer
;
/* Assume it starts with 0x00000001 */
uint8_t
*
dat
=
&
p_block
->
p_buffer
[
4
];
...
...
@@ -759,13 +762,233 @@ static bo_t *GetD263Tag(void)
return
d263
;
}
static
void
hevcParseVPS
(
uint8_t
*
p_buffer
,
size_t
i_buffer
,
uint8_t
*
general
,
uint8_t
*
numTemporalLayer
,
bool
*
temporalIdNested
)
{
const
size_t
i_decoded_nal_size
=
512
;
uint8_t
p_dec_nal
[
i_decoded_nal_size
];
size_t
i_size
=
(
i_buffer
<
i_decoded_nal_size
)
?
i_buffer
:
i_decoded_nal_size
;
nal_decode
(
p_buffer
,
p_dec_nal
,
i_size
);
/* first two bytes are the NAL header, 3rd and 4th are:
vps_video_parameter_set_id(4)
vps_reserved_3_2bis(2)
vps_max_layers_minus1(6)
vps_max_sub_layers_minus1(3)
vps_temporal_id_nesting_flags
*/
*
numTemporalLayer
=
((
p_dec_nal
[
3
]
&
0x0E
)
>>
1
)
+
1
;
*
temporalIdNested
=
(
bool
)(
p_dec_nal
[
3
]
&
0x01
);
/* 5th & 6th are reserved 0xffff */
/* copy the first 12 bytes of profile tier */
memcpy
(
general
,
&
p_dec_nal
[
6
],
12
);
}
static
void
hevcParseSPS
(
uint8_t
*
p_buffer
,
size_t
i_buffer
,
uint8_t
*
chroma_idc
,
uint8_t
*
bit_depth_luma_minus8
,
uint8_t
*
bit_depth_chroma_minus8
)
{
const
size_t
i_decoded_nal_size
=
512
;
uint8_t
p_dec_nal
[
i_decoded_nal_size
];
size_t
i_size
=
(
i_buffer
<
i_decoded_nal_size
)
?
i_buffer
-
2
:
i_decoded_nal_size
;
nal_decode
(
p_buffer
+
2
,
p_dec_nal
,
i_size
);
bs_t
bs
;
bs_init
(
&
bs
,
p_dec_nal
,
i_size
);
/* skip vps id */
bs_skip
(
&
bs
,
4
);
uint32_t
sps_max_sublayer_minus1
=
bs_read
(
&
bs
,
3
);
/* skip nesting flag */
bs_skip
(
&
bs
,
1
);
hevc_skip_profile_tiers_level
(
&
bs
,
sps_max_sublayer_minus1
);
/* skip sps id */
(
void
)
read_ue
(
&
bs
);
*
chroma_idc
=
read_ue
(
&
bs
);
if
(
*
chroma_idc
==
3
)
bs_skip
(
&
bs
,
1
);
/* skip width and heigh */
(
void
)
read_ue
(
&
bs
);
(
void
)
read_ue
(
&
bs
);
uint32_t
conformance_window_flag
=
bs_read1
(
&
bs
);
if
(
conformance_window_flag
)
{
/* skip offsets*/
(
void
)
read_ue
(
&
bs
);
(
void
)
read_ue
(
&
bs
);
(
void
)
read_ue
(
&
bs
);
(
void
)
read_ue
(
&
bs
);
}
*
bit_depth_luma_minus8
=
read_ue
(
&
bs
);
*
bit_depth_chroma_minus8
=
read_ue
(
&
bs
);
}
static
bo_t
*
GetHvcCTag
(
mp4_stream_t
*
p_stream
)
{
/* Generate hvcC box matching iso/iec 14496-15 3rd edition */
bo_t
*
hvcC
=
box_new
(
"hvcC"
);
if
(
!
p_stream
->
fmt
.
i_extra
)
return
hvcC
;
struct
nal
{
size_t
i_buffer
;
uint8_t
*
p_buffer
;
};
/* According to the specification HEVC stream can have
* 16 vps id and an "unlimited" number of sps and pps id using ue(v) id*/
struct
nal
p_vps
[
16
],
*
p_sps
=
NULL
,
*
p_pps
=
NULL
,
*
p_sei
=
NULL
,
*
p_nal
=
NULL
;
size_t
i_vps
=
0
,
i_sps
=
0
,
i_pps
=
0
,
i_sei
=
0
;
uint8_t
i_num_arrays
=
0
;
uint8_t
*
p_buffer
=
p_stream
->
fmt
.
p_extra
;
size_t
i_buffer
=
p_stream
->
fmt
.
i_extra
;
uint8_t
general_configuration
[
12
]
=
{
0
};
uint8_t
i_numTemporalLayer
;
uint8_t
i_chroma_idc
=
1
;
uint8_t
i_bit_depth_luma_minus8
=
0
;
uint8_t
i_bit_depth_chroma_minus8
=
0
;
bool
b_temporalIdNested
;
uint32_t
cmp
=
0xFFFFFFFF
;
while
(
i_buffer
)
{
/* look for start code 0X0000001 */
while
(
i_buffer
)
{
cmp
=
(
cmp
<<
8
)
|
*
p_buffer
;
if
((
cmp
^
UINT32_C
(
0x100
))
<=
UINT32_C
(
0xFF
))
break
;
p_buffer
++
;
i_buffer
--
;
}
if
(
p_nal
)
p_nal
->
i_buffer
=
p_buffer
-
p_nal
->
p_buffer
-
((
i_buffer
)
?
3
:
0
);
switch
(
*
p_buffer
&
0x72
)
{
/* VPS */
case
0x40
:
p_nal
=
&
p_vps
[
i_vps
++
];
p_nal
->
p_buffer
=
p_buffer
;
/* Only keep the general profile from the first VPS
* if there are several (this shouldn't happen so soon) */
if
(
i_vps
==
1
)
{
hevcParseVPS
(
p_buffer
,
i_buffer
,
general_configuration
,
&
i_numTemporalLayer
,
&
b_temporalIdNested
);
i_num_arrays
++
;
}
break
;
/* SPS */
case
0x42
:
{
struct
nal
*
p_tmp
=
realloc
(
p_sps
,
sizeof
(
struct
nal
)
*
(
i_sps
+
1
));
if
(
!
p_tmp
)
break
;
p_sps
=
p_tmp
;
p_nal
=
&
p_sps
[
i_sps
++
];
p_nal
->
p_buffer
=
p_buffer
;
if
(
i_sps
==
1
&&
i_buffer
>
15
)
{
/* Get Chroma_idc and bitdepths */
hevcParseSPS
(
p_buffer
,
i_buffer
,
&
i_chroma_idc
,
&
i_bit_depth_luma_minus8
,
&
i_bit_depth_chroma_minus8
);
i_num_arrays
++
;
}
break
;
}
/* PPS */
case
0x44
:
{
struct
nal
*
p_tmp
=
realloc
(
p_pps
,
sizeof
(
struct
nal
)
*
(
i_pps
+
1
));
if
(
!
p_tmp
)
break
;
p_pps
=
p_tmp
;
p_nal
=
&
p_pps
[
i_pps
++
];
p_nal
->
p_buffer
=
p_buffer
;
if
(
i_pps
==
1
)
i_num_arrays
++
;
break
;
}
/* SEI */
case
0x4E
:
case
0x50
:
{
struct
nal
*
p_tmp
=
realloc
(
p_sei
,
sizeof
(
struct
nal
)
*
(
i_sei
+
1
));
if
(
!
p_tmp
)
break
;
p_sei
=
p_tmp
;
p_nal
=
&
p_sei
[
i_sei
++
];
p_nal
->
p_buffer
=
p_buffer
;
if
(
i_sei
==
1
)
i_num_arrays
++
;
break
;
}
default:
p_nal
=
NULL
;
break
;
}
}
bo_add_8
(
hvcC
,
0x01
);
bo_add_mem
(
hvcC
,
12
,
general_configuration
);
/* Don't set min spatial segmentation */
bo_add_16be
(
hvcC
,
0xF000
);
/* Don't set parallelism type since segmentation isn't set */
bo_add_8
(
hvcC
,
0xFC
);
bo_add_8
(
hvcC
,
(
0xFC
|
(
i_chroma_idc
&
0x03
)));
bo_add_8
(
hvcC
,
(
0xF8
|
(
i_bit_depth_luma_minus8
&
0x07
)));
bo_add_8
(
hvcC
,
(
0xF8
|
(
i_bit_depth_chroma_minus8
&
0x07
)));
/* Don't set framerate */
bo_add_16be
(
hvcC
,
0x0000
);
/* Force NAL size of 4 bytes that replace the startcode */
bo_add_8
(
hvcC
,
(((
i_numTemporalLayer
&
0x07
)
<<
3
)
|
(
b_temporalIdNested
<<
2
)
|
0x03
));
bo_add_8
(
hvcC
,
i_num_arrays
);
if
(
i_vps
)
{
/* Write VPS without forcing array_completeness */
bo_add_8
(
hvcC
,
32
);
bo_add_16be
(
hvcC
,
i_vps
);
for
(
size_t
i
=
0
;
i
<
i_vps
;
i
++
)
{
p_nal
=
&
p_vps
[
i
];
bo_add_16be
(
hvcC
,
p_nal
->
i_buffer
);
bo_add_mem
(
hvcC
,
p_nal
->
i_buffer
,
p_nal
->
p_buffer
);
}
}
if
(
i_sps
)
{
/* Write SPS without forcing array_completeness */
bo_add_8
(
hvcC
,
33
);
bo_add_16be
(
hvcC
,
i_sps
);
for
(
size_t
i
=
0
;
i
<
i_sps
;
i
++
)
{
p_nal
=
&
p_sps
[
i
];
bo_add_16be
(
hvcC
,
p_nal
->
i_buffer
);
bo_add_mem
(
hvcC
,
p_nal
->
i_buffer
,
p_nal
->
p_buffer
);
}
}
if
(
p_stream
->
fmt
.
i_extra
>
0
)
bo_add_mem
(
hvcC
,
p_stream
->
fmt
.
i_extra
,
p_stream
->
fmt
.
p_extra
);
if
(
i_pps
)
{
/* Write PPS without forcing array_completeness */
bo_add_8
(
hvcC
,
34
);
bo_add_16be
(
hvcC
,
i_pps
);
for
(
size_t
i
=
0
;
i
<
i_pps
;
i
++
)
{
p_nal
=
&
p_pps
[
i
];
bo_add_16be
(
hvcC
,
p_nal
->
i_buffer
);
bo_add_mem
(
hvcC
,
p_nal
->
i_buffer
,
p_nal
->
p_buffer
);
}
}
if
(
i_sei
)
{
/* Write SEI without forcing array_completeness */
bo_add_8
(
hvcC
,
39
);
bo_add_16be
(
hvcC
,
i_sei
);
for
(
size_t
i
=
0
;
i
<
i_sei
;
i
++
)
{
p_nal
=
&
p_sei
[
i
];
bo_add_16be
(
hvcC
,
p_nal
->
i_buffer
);
bo_add_mem
(
hvcC
,
p_nal
->
i_buffer
,
p_nal
->
p_buffer
);
}
}
return
hvcC
;
}
...
...
modules/packetizer/hevc.c
View file @
ed686b09
...
...
@@ -124,7 +124,7 @@ static int Open(vlc_object_t *p_this)
packetizer_Init
(
&
p_dec
->
p_sys
->
packetizer
,
p_hevc_startcode
,
sizeof
(
p_hevc_startcode
),
NULL
,
0
,
0
,
p_hevc_startcode
,
1
,
5
,
PacketizeReset
,
PacketizeParse
,
PacketizeValidate
,
p_dec
);
/* Copy properties */
...
...
@@ -185,7 +185,7 @@ static block_t *PacketizeParse(void *p_private, bool *pb_ts_used, block_t *p_blo
p_block
->
i_buffer
--
;
bs_t
bs
;
bs_init
(
&
bs
,
p_block
->
p_buffer
+
3
,
p_block
->
i_buffer
-
3
);
bs_init
(
&
bs
,
p_block
->
p_buffer
+
4
,
p_block
->
i_buffer
-
4
);
/* Get NALU type */
uint32_t
forbidden_zero_bit
=
bs_read1
(
&
bs
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment