Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Open sidebar
Steve Lhomme
VLC
Commits
193f466c
Commit
193f466c
authored
Mar 09, 2018
by
François Cartegnie
🤞
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
demux: add support for HEIF
parent
eb2e9471
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
519 additions
and
1 deletion
+519
-1
NEWS
NEWS
+3
-0
modules/demux/Makefile.am
modules/demux/Makefile.am
+2
-1
modules/demux/mp4/heif.c
modules/demux/mp4/heif.c
+458
-0
modules/demux/mp4/heif.h
modules/demux/mp4/heif.h
+24
-0
modules/demux/mp4/libmp4.c
modules/demux/mp4/libmp4.c
+1
-0
modules/demux/mp4/libmp4.h
modules/demux/mp4/libmp4.h
+6
-0
modules/demux/mp4/mp4.c
modules/demux/mp4/mp4.c
+25
-0
No files found.
NEWS
View file @
193f466c
...
...
@@ -9,6 +9,9 @@ Platform support changes:
- Android 4.1.x or later (API-16)
- GCC 5.0 or Clang 3.4 (or equivalent)
Demuxer:
* Support for HEIF format
Codecs:
* Support for experimental AV1 video encoding
* WebVTT encoder
...
...
modules/demux/Makefile.am
View file @
193f466c
...
...
@@ -202,10 +202,11 @@ libmp4_plugin_la_SOURCES = demux/mp4/mp4.c demux/mp4/mp4.h \
demux/mp4/fragments.c demux/mp4/fragments.h
\
demux/mp4/libmp4.c demux/mp4/libmp4.h
\
demux/mp4/languages.h
\
demux/
asf/asfpacket.c demux/asf/asfpacket
.h
\
demux/
mp4/heif.c demux/mp4/heif
.h
\
demux/mp4/avci.h
\
demux/mp4/color_config.h
\
demux/mp4/essetup.c demux/mp4/meta.c
\
demux/asf/asfpacket.c demux/asf/asfpacket.h
\
meta_engine/ID3Genres.h
libmp4_plugin_la_LIBADD
=
$(LIBM)
libmp4_plugin_la_LDFLAGS
=
$(AM_LDFLAGS)
...
...
modules/demux/mp4/heif.c
View file @
193f466c
/*****************************************************************************
* heif.c : ISO/IEC 23008-12 HEIF still picture demuxer
*****************************************************************************
* Copyright (C) 2018 Videolabs, VLC authors and VideoLAN
*
* 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.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <vlc_common.h>
#include <vlc_demux.h>
#include <vlc_input.h>
#include <assert.h>
#include <limits.h>
#include "libmp4.h"
#include "heif.h"
struct
heif_private_t
{
MP4_Box_t
*
p_root
;
es_out_id_t
*
id
;
mtime_t
i_pcr
;
mtime_t
i_end_display_time
;
mtime_t
i_image_duration
;
bool
b_seekpoint_changed
;
uint32_t
i_seekpoint
;
input_title_t
*
p_title
;
struct
{
MP4_Box_t
*
p_infe
;
es_format_t
fmt
;
}
current
;
};
static
MP4_Box_t
*
NextAtom
(
MP4_Box_t
*
p_root
,
vlc_fourcc_t
i_type
,
const
char
*
psz_path
,
MP4_Box_t
*
p_infe
)
{
if
(
p_infe
==
NULL
)
p_infe
=
MP4_BoxGet
(
p_root
,
psz_path
);
else
p_infe
=
p_infe
->
p_next
;
for
(
;
p_infe
;
p_infe
=
p_infe
->
p_next
)
{
if
(
p_infe
->
i_type
==
i_type
)
return
p_infe
;
}
return
NULL
;
}
static
MP4_Box_t
*
GetAtom
(
MP4_Box_t
*
p_root
,
MP4_Box_t
*
p_atom
,
vlc_fourcc_t
i_type
,
const
char
*
psz_path
,
bool
(
*
pf_match
)(
const
MP4_Box_t
*
,
void
*
),
void
*
priv
)
{
while
(
(
p_atom
=
NextAtom
(
p_root
,
i_type
,
psz_path
,
p_atom
))
)
{
if
(
pf_match
(
p_atom
,
priv
)
)
return
p_atom
;
}
return
NULL
;
}
static
bool
MatchInfeID
(
const
MP4_Box_t
*
p_infe
,
void
*
priv
)
{
return
BOXDATA
(
p_infe
)
->
i_item_id
==
*
((
uint32_t
*
)
priv
);
}
static
bool
MatchPureImage
(
const
MP4_Box_t
*
p_infe
,
void
*
priv
)
{
MP4_Box_t
*
p_root
=
priv
;
const
MP4_Box_t
*
p_iref
=
MP4_BoxGet
(
p_root
,
"meta/iref"
);
if
(
!
p_iref
)
return
true
;
for
(
const
MP4_Box_t
*
p_refbox
=
p_iref
->
p_first
;
p_refbox
;
p_refbox
=
p_refbox
->
p_next
)
{
if
(
BOXDATA
(
p_refbox
)
->
i_from_item_id
==
BOXDATA
(
p_infe
)
->
i_item_id
)
return
false
;
}
return
true
;
}
static
void
SeekToPrevImageEnd
(
struct
heif_private_t
*
p_sys
,
int
i_picture
)
{
int
i
=
0
;
MP4_Box_t
*
p_infe
=
NULL
;
while
(
i
<
i_picture
&&
(
p_infe
=
NextAtom
(
p_sys
->
p_root
,
ATOM_infe
,
"meta/iinf/infe"
,
p_infe
))
)
{
if
(
(
BOXDATA
(
p_infe
)
->
i_flags
&
0x01
)
!=
0x00
||
!
MatchPureImage
(
p_infe
,
p_sys
->
p_root
)
)
continue
;
i
++
;
}
p_sys
->
current
.
p_infe
=
p_infe
;
p_sys
->
i_end_display_time
=
0
;
p_sys
->
i_pcr
=
i
*
p_sys
->
i_image_duration
;
}
static
int
ControlHEIF
(
demux_t
*
p_demux
,
int
i_query
,
va_list
args
)
{
struct
heif_private_t
*
p_sys
=
(
void
*
)
p_demux
->
p_sys
;
switch
(
i_query
)
{
case
DEMUX_CAN_SEEK
:
*
va_arg
(
args
,
bool
*
)
=
true
;
return
VLC_SUCCESS
;
case
DEMUX_GET_TITLE_INFO
:
{
input_title_t
***
ppp_title
=
va_arg
(
args
,
input_title_t
***
);
int
*
pi_int
=
va_arg
(
args
,
int
*
);
int
*
pi_title_offset
=
va_arg
(
args
,
int
*
);
int
*
pi_seekpoint_offset
=
va_arg
(
args
,
int
*
);
if
(
!
p_sys
->
p_title
)
return
VLC_EGENERIC
;
*
pi_int
=
1
;
*
ppp_title
=
malloc
(
sizeof
(
input_title_t
*
)
);
(
*
ppp_title
)[
0
]
=
vlc_input_title_Duplicate
(
p_sys
->
p_title
);
*
pi_title_offset
=
0
;
*
pi_seekpoint_offset
=
0
;
return
VLC_SUCCESS
;
}
case
DEMUX_SET_TITLE
:
{
const
int
i_title
=
va_arg
(
args
,
int
);
if
(
!
p_sys
->
p_title
||
i_title
!=
0
)
return
VLC_EGENERIC
;
return
VLC_SUCCESS
;
}
case
DEMUX_GET_SEEKPOINT
:
*
va_arg
(
args
,
int
*
)
=
p_sys
->
i_seekpoint
;
return
VLC_SUCCESS
;
case
DEMUX_SET_SEEKPOINT
:
{
const
int
i_seekpoint
=
va_arg
(
args
,
int
);
if
(
!
p_sys
->
p_title
)
return
VLC_EGENERIC
;
SeekToPrevImageEnd
(
p_sys
,
i_seekpoint
);
return
VLC_SUCCESS
;
}
case
DEMUX_TEST_AND_CLEAR_FLAGS
:
{
unsigned
*
restrict
flags
=
va_arg
(
args
,
unsigned
*
);
if
((
*
flags
&
INPUT_UPDATE_SEEKPOINT
)
&&
p_sys
->
b_seekpoint_changed
)
{
*
flags
=
INPUT_UPDATE_SEEKPOINT
;
p_sys
->
b_seekpoint_changed
=
false
;
}
else
*
flags
=
0
;
return
VLC_SUCCESS
;
}
case
DEMUX_GET_LENGTH
:
*
(
va_arg
(
args
,
int64_t
*
))
=
p_sys
->
p_title
->
i_seekpoint
*
p_sys
->
i_image_duration
;
return
VLC_SUCCESS
;
case
DEMUX_GET_TIME
:
*
(
va_arg
(
args
,
int64_t
*
))
=
p_sys
->
i_pcr
;
return
VLC_SUCCESS
;
case
DEMUX_SET_TIME
:
{
SeekToPrevImageEnd
(
p_sys
,
va_arg
(
args
,
int64_t
)
/
p_sys
->
i_image_duration
);
return
VLC_SUCCESS
;
}
case
DEMUX_GET_POSITION
:
if
(
!
p_sys
->
p_title
->
i_seekpoint
)
return
VLC_EGENERIC
;
*
(
va_arg
(
args
,
double
*
))
=
(
double
)
p_sys
->
i_pcr
/
(
p_sys
->
p_title
->
i_seekpoint
*
p_sys
->
i_image_duration
);
return
VLC_SUCCESS
;
case
DEMUX_SET_POSITION
:
{
SeekToPrevImageEnd
(
p_sys
,
va_arg
(
args
,
double
)
*
p_sys
->
p_title
->
i_seekpoint
);
return
VLC_SUCCESS
;
}
case
DEMUX_CAN_PAUSE
:
case
DEMUX_SET_PAUSE_STATE
:
case
DEMUX_CAN_CONTROL_PACE
:
case
DEMUX_GET_PTS_DELAY
:
return
demux_vaControlHelper
(
p_demux
->
s
,
0
,
-
1
,
0
,
1
,
i_query
,
args
);
default:
return
VLC_EGENERIC
;
}
}
static
int
DemuxHEIF
(
demux_t
*
p_demux
)
{
struct
heif_private_t
*
p_sys
=
(
void
*
)
p_demux
->
p_sys
;
/* Displaying a picture */
if
(
p_sys
->
i_end_display_time
>
0
)
{
bool
b_empty
;
es_out_Control
(
p_demux
->
out
,
ES_OUT_GET_EMPTY
,
&
b_empty
);
if
(
!
b_empty
||
mdate
()
<=
p_sys
->
i_end_display_time
)
{
msleep
(
40
*
1000
);
return
VLC_DEMUXER_SUCCESS
;
}
p_sys
->
i_end_display_time
=
0
;
}
/* First or next picture */
if
(
!
p_sys
->
current
.
p_infe
)
{
MP4_Box_t
*
p_pitm
=
MP4_BoxGet
(
p_sys
->
p_root
,
"meta/pitm"
);
if
(
!
p_pitm
)
return
VLC_DEMUXER_EOF
;
p_sys
->
current
.
p_infe
=
GetAtom
(
p_sys
->
p_root
,
NULL
,
ATOM_infe
,
"meta/iinf/infe"
,
MatchInfeID
,
&
BOXDATA
(
p_pitm
)
->
i_item_id
);
}
else
{
p_sys
->
current
.
p_infe
=
GetAtom
(
p_sys
->
p_root
,
p_sys
->
current
.
p_infe
,
ATOM_infe
,
"meta/iinf/infe"
,
MatchPureImage
,
p_sys
->
p_root
);
}
if
(
!
p_sys
->
current
.
p_infe
)
return
VLC_DEMUXER_EOF
;
const
uint32_t
i_current_item_id
=
p_sys
->
current
.
BOXDATA
(
p_infe
)
->
i_item_id
;
const
MP4_Box_t
*
p_ipco
=
MP4_BoxGet
(
p_sys
->
p_root
,
"meta/iprp/ipco"
);
const
MP4_Box_t
*
p_ipma
=
MP4_BoxGet
(
p_sys
->
p_root
,
"meta/iprp/ipma"
);
if
(
!
p_ipma
||
!
p_ipco
)
return
VLC_DEMUXER_EOF
;
es_format_t
fmt
;
switch
(
p_sys
->
current
.
BOXDATA
(
p_infe
)
->
item_type
)
{
case
VLC_FOURCC
(
'h'
,
'v'
,
'c'
,
'1'
):
es_format_Init
(
&
fmt
,
VIDEO_ES
,
VLC_CODEC_HEVC
);
break
;
default:
/* Unsupported picture, goto next */
return
VLC_DEMUXER_SUCCESS
;
}
/* Load properties */
for
(
uint32_t
i
=
0
;
i
<
BOXDATA
(
p_ipma
)
->
i_entry_count
;
i
++
)
{
if
(
BOXDATA
(
p_ipma
)
->
p_entries
[
i
].
i_item_id
!=
i_current_item_id
)
continue
;
for
(
uint8_t
j
=
0
;
j
<
BOXDATA
(
p_ipma
)
->
p_entries
[
i
].
i_association_count
;
j
++
)
{
if
(
!
BOXDATA
(
p_ipma
)
->
p_entries
[
i
].
p_assocs
[
j
].
i_property_index
)
continue
;
const
MP4_Box_t
*
p_prop
=
MP4_BoxGet
(
p_ipco
,
"./[%u]"
,
BOXDATA
(
p_ipma
)
->
p_entries
[
i
].
p_assocs
[
j
].
i_property_index
-
1
);
if
(
!
p_prop
)
continue
;
switch
(
p_prop
->
i_type
)
{
case
ATOM_hvcC
:
if
(
!
fmt
.
p_extra
&&
fmt
.
i_codec
==
VLC_CODEC_HEVC
)
{
fmt
.
p_extra
=
malloc
(
p_prop
->
data
.
p_binary
->
i_blob
);
if
(
fmt
.
p_extra
)
{
fmt
.
i_extra
=
p_prop
->
data
.
p_binary
->
i_blob
;
memcpy
(
fmt
.
p_extra
,
p_prop
->
data
.
p_binary
->
p_blob
,
fmt
.
i_extra
);
}
}
break
;
case
ATOM_ispe
:
fmt
.
video
.
i_visible_width
=
p_prop
->
data
.
p_ispe
->
i_width
;
fmt
.
video
.
i_visible_height
=
p_prop
->
data
.
p_ispe
->
i_height
;
break
;
case
ATOM_pasp
:
if
(
p_prop
->
data
.
p_pasp
->
i_horizontal_spacing
&&
p_prop
->
data
.
p_pasp
->
i_vertical_spacing
)
{
fmt
.
video
.
i_sar_num
=
p_prop
->
data
.
p_pasp
->
i_horizontal_spacing
;
fmt
.
video
.
i_sar_den
=
p_prop
->
data
.
p_pasp
->
i_vertical_spacing
;
}
break
;
}
}
}
fmt
.
video
.
i_frame_rate
=
1000
;
fmt
.
video
.
i_frame_rate_base
=
p_sys
->
i_image_duration
/
1000
;
es_format_Clean
(
&
p_sys
->
current
.
fmt
);
es_format_Copy
(
&
p_sys
->
current
.
fmt
,
&
fmt
);
es_format_Clean
(
&
fmt
);
if
(
!
p_sys
->
id
)
p_sys
->
id
=
es_out_Add
(
p_demux
->
out
,
&
p_sys
->
current
.
fmt
);
else
es_out_Control
(
p_demux
->
out
,
ES_OUT_RESTART_ES
,
p_sys
->
id
);
if
(
!
p_sys
->
id
)
{
p_sys
->
current
.
p_infe
=
NULL
;
/* Goto next picture */
return
VLC_DEMUXER_SUCCESS
;
}
MP4_Box_t
*
p_iloc
=
MP4_BoxGet
(
p_sys
->
p_root
,
"meta/iloc"
);
if
(
!
p_iloc
)
return
VLC_DEMUXER_EOF
;
block_t
*
p_block
=
NULL
;
for
(
uint32_t
i
=
0
;
i
<
BOXDATA
(
p_iloc
)
->
i_item_count
;
i
++
)
{
if
(
BOXDATA
(
p_iloc
)
->
p_items
[
i
].
i_item_id
!=
i_current_item_id
)
continue
;
block_t
**
pp_append
=
&
p_block
;
for
(
uint16_t
j
=
0
;
j
<
BOXDATA
(
p_iloc
)
->
p_items
[
i
].
i_extent_count
;
j
++
)
{
uint64_t
i_offset
=
BOXDATA
(
p_iloc
)
->
p_items
[
i
].
i_base_offset
+
BOXDATA
(
p_iloc
)
->
p_items
[
i
].
p_extents
[
j
].
i_extent_offset
;
uint64_t
i_length
=
BOXDATA
(
p_iloc
)
->
p_items
[
i
].
p_extents
[
j
].
i_extent_length
;
if
(
vlc_stream_Seek
(
p_demux
->
s
,
i_offset
)
!=
VLC_SUCCESS
)
break
;
*
pp_append
=
vlc_stream_Block
(
p_demux
->
s
,
i_length
);
if
(
*
pp_append
)
pp_append
=
&
((
*
pp_append
)
->
p_next
);
}
break
;
}
if
(
p_block
)
p_block
=
block_ChainGather
(
p_block
);
if
(
!
p_block
)
return
VLC_DEMUXER_SUCCESS
;
/* Goto next picture */
if
(
p_sys
->
i_pcr
==
VLC_TS_INVALID
)
{
p_sys
->
i_pcr
=
VLC_TS_0
;
es_out_SetPCR
(
p_demux
->
out
,
p_sys
->
i_pcr
);
}
p_block
->
i_dts
=
p_block
->
i_pts
=
p_sys
->
i_pcr
;
p_block
->
i_length
=
p_sys
->
i_image_duration
;
p_block
->
i_flags
|=
BLOCK_FLAG_END_OF_SEQUENCE
;
p_sys
->
i_end_display_time
=
mdate
()
+
p_block
->
i_length
;
p_sys
->
b_seekpoint_changed
=
true
;
p_sys
->
i_pcr
=
p_block
->
i_dts
+
p_block
->
i_length
;
es_out_Send
(
p_demux
->
out
,
p_sys
->
id
,
p_block
);
es_out_SetPCR
(
p_demux
->
out
,
p_sys
->
i_pcr
);
return
VLC_DEMUXER_SUCCESS
;
}
int
OpenHEIF
(
vlc_object_t
*
p_this
)
{
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
const
uint8_t
*
p_peek
;
if
(
vlc_stream_Peek
(
p_demux
->
s
,
&
p_peek
,
12
)
<
12
)
return
VLC_EGENERIC
;
if
(
VLC_FOURCC
(
p_peek
[
4
],
p_peek
[
5
],
p_peek
[
6
],
p_peek
[
7
]
)
!=
ATOM_ftyp
)
return
VLC_EGENERIC
;
switch
(
VLC_FOURCC
(
p_peek
[
8
],
p_peek
[
9
],
p_peek
[
10
],
p_peek
[
11
]
)
)
{
case
MAJOR_mif1
:
case
MAJOR_heic
:
case
MAJOR_heix
:
break
;
case
MAJOR_msf1
:
case
MAJOR_hevc
:
case
MAJOR_hevx
:
default:
return
VLC_EGENERIC
;
}
MP4_Box_t
*
p_root
=
MP4_BoxGetRoot
(
p_demux
->
s
);
if
(
!
p_root
)
return
VLC_EGENERIC
;
MP4_BoxDumpStructure
(
p_demux
->
s
,
p_root
);
struct
heif_private_t
*
p_sys
=
calloc
(
1
,
sizeof
(
*
p_sys
)
);
p_demux
->
p_sys
=
(
void
*
)
p_sys
;
p_sys
->
p_root
=
p_root
;
p_sys
->
p_title
=
vlc_input_title_New
();
if
(
!
p_sys
->
p_title
)
{
free
(
p_sys
);
return
VLC_ENOMEM
;
}
p_sys
->
i_image_duration
=
var_InheritFloat
(
p_demux
,
"heif-image-duration"
);
if
(
p_sys
->
i_image_duration
<=
0
)
p_sys
->
i_image_duration
=
HEIF_DEFAULT_DURATION
;
p_sys
->
i_image_duration
*=
CLOCK_FREQ
;
MP4_Box_t
*
p_infe
=
NULL
;
while
(
(
p_infe
=
NextAtom
(
p_root
,
ATOM_infe
,
"meta/iinf/infe"
,
p_infe
))
)
{
if
(
(
BOXDATA
(
p_infe
)
->
i_flags
&
0x01
)
!=
0x00
||
!
MatchPureImage
(
p_infe
,
p_root
)
)
continue
;
seekpoint_t
*
s
=
vlc_seekpoint_New
();
if
(
s
)
{
s
->
i_time_offset
=
p_sys
->
p_title
->
i_seekpoint
*
p_sys
->
i_image_duration
;
if
(
BOXDATA
(
p_infe
)
->
psz_item_name
)
s
->
psz_name
=
strdup
(
BOXDATA
(
p_infe
)
->
psz_item_name
);
TAB_APPEND
(
p_sys
->
p_title
->
i_seekpoint
,
p_sys
->
p_title
->
seekpoint
,
s
);
}
}
es_format_Init
(
&
p_sys
->
current
.
fmt
,
UNKNOWN_ES
,
0
);
p_demux
->
pf_demux
=
DemuxHEIF
;
p_demux
->
pf_control
=
ControlHEIF
;
return
VLC_SUCCESS
;
}
void
CloseHEIF
(
vlc_object_t
*
p_this
)
{
demux_t
*
p_demux
=
(
demux_t
*
)
p_this
;
struct
heif_private_t
*
p_sys
=
(
void
*
)
p_demux
->
p_sys
;
MP4_BoxFree
(
p_sys
->
p_root
);
if
(
p_sys
->
id
)
es_out_Del
(
p_demux
->
out
,
p_sys
->
id
);
es_format_Clean
(
&
p_sys
->
current
.
fmt
);
vlc_input_title_Delete
(
p_sys
->
p_title
);
free
(
p_sys
);
}
modules/demux/mp4/heif.h
0 → 100644
View file @
193f466c
/*****************************************************************************
* heif.h : ISO/IEC 23008-12 HEIF still picture demuxer
*****************************************************************************
* Copyright (C) 2018 Videolabs, VLC authors and VideoLAN
*
* 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.
*****************************************************************************/
#define HEIF_DEFAULT_DURATION 10.0
int
OpenHEIF
(
vlc_object_t
*
);
void
CloseHEIF
(
vlc_object_t
*
);
modules/demux/mp4/libmp4.c
View file @
193f466c
...
...
@@ -3912,6 +3912,7 @@ static int MP4_ReadBox_meta( stream_t *p_stream, MP4_Box_t *p_box )
p_box
->
i_handler
=
BOXDATA
(
p_hdlr
)
->
i_handler_type
;
switch
(
p_box
->
i_handler
)
{
case
HANDLER_pict
:
case
HANDLER_mdta
:
case
HANDLER_mdir
:
/* then it behaves like a container */
...
...
modules/demux/mp4/libmp4.h
View file @
193f466c
...
...
@@ -42,6 +42,12 @@ typedef int64_t stime_t;
#define MAJOR_mp41 VLC_FOURCC( 'm', 'p', '4', '1' )
#define MAJOR_avc1 VLC_FOURCC( 'a', 'v', 'c', '1' )
#define MAJOR_M4A VLC_FOURCC( 'M', '4', 'A', ' ' )
#define MAJOR_mif1 VLC_FOURCC( 'm', 'i', 'f', '1' )
/* heif */
#define MAJOR_msf1 VLC_FOURCC( 'm', 's', 'f', '1' )
/* heif */
#define MAJOR_heic VLC_FOURCC( 'h', 'e', 'i', 'c' )
/* heif */
#define MAJOR_heix VLC_FOURCC( 'h', 'e', 'i', 'x' )
/* heif */
#define MAJOR_hevc VLC_FOURCC( 'h', 'e', 'v', 'c' )
/* heif */
#define MAJOR_hevx VLC_FOURCC( 'h', 'e', 'v', 'x' )
/* heif */
#define ATOM_root VLC_FOURCC( 'r', 'o', 'o', 't' )
#define ATOM_uuid VLC_FOURCC( 'u', 'u', 'i', 'd' )
...
...
modules/demux/mp4/mp4.c
View file @
193f466c
...
...
@@ -38,6 +38,7 @@
#include <assert.h>
#include <limits.h>
#include "../codec/cc.h"
#include "heif.h"
/*****************************************************************************
* Module descriptor
...
...
@@ -50,6 +51,11 @@ static void Close( vlc_object_t * );
#define MP4_M4A_TEXT N_("M4A audio only")
#define MP4_M4A_LONGTEXT N_("Ignore non audio tracks from iTunes audio files")
#define HEIF_DURATION_TEXT N_("Duration in seconds")
#define HEIF_DURATION_LONGTEXT N_( \
"Duration in seconds before simulating an end of file. " \
"A negative value means an unlimited play time.")
vlc_module_begin
()
set_category
(
CAT_INPUT
)
set_subcategory
(
SUBCAT_INPUT_DEMUX
)
...
...
@@ -60,6 +66,18 @@ vlc_module_begin ()
add_category_hint
(
"Hacks"
,
NULL
,
true
)
add_bool
(
CFG_PREFIX
"m4a-audioonly"
,
false
,
MP4_M4A_TEXT
,
MP4_M4A_LONGTEXT
,
true
)
add_submodule
()
set_category
(
CAT_INPUT
)
set_subcategory
(
SUBCAT_INPUT_DEMUX
)
set_description
(
N_
(
"HEIF demuxer"
)
)
set_shortname
(
"heif"
)
set_capability
(
"demux"
,
239
)
set_callbacks
(
OpenHEIF
,
CloseHEIF
)
set_section
(
N_
(
"HEIF demuxer"
),
NULL
)
add_float
(
"heif-image-duration"
,
HEIF_DEFAULT_DURATION
,
HEIF_DURATION_TEXT
,
HEIF_DURATION_LONGTEXT
,
false
)
change_safe
()
vlc_module_end
()
/*****************************************************************************
...
...
@@ -668,6 +686,9 @@ static void MP4_Block_Send( demux_t *p_demux, mp4_track_t *p_track, block_t *p_b
es_out_Send
(
p_demux
->
out
,
p_track
->
p_es
,
p_block
);
}
int
OpenHEIF
(
vlc_object_t
*
);
void
CloseHEIF
(
vlc_object_t
*
);
/*****************************************************************************
* Open: check file and initializes MP4 structures
*****************************************************************************/
...
...
@@ -705,6 +726,10 @@ static int Open( vlc_object_t * p_this )
/* Early handle some brands */
switch
(
VLC_FOURCC
(
p_peek
[
8
],
p_peek
[
9
],
p_peek
[
10
],
p_peek
[
11
])
)
{
/* HEIF pictures goes to heif demux */
case
MAJOR_heic
:
case
MAJOR_heix
:
case
MAJOR_mif1
:
/* We don't yet support f4v, but avformat does. */
case
MAJOR_f4v
:
return
VLC_EGENERIC
;
...
...
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