Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
ddb63017
Commit
ddb63017
authored
May 05, 2010
by
David Conrad
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
movenc: Write QuickTime chapters
Originally committed as revision 23022 to
svn://svn.ffmpeg.org/ffmpeg/trunk
parent
1b206f62
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
70 additions
and
5 deletions
+70
-5
movenc.c
libavformat/movenc.c
+70
-5
No files found.
libavformat/movenc.c
View file @
ddb63017
...
...
@@ -77,12 +77,15 @@ typedef struct MOVIndex {
MOVIentry
*
cluster
;
int
audio_vbr
;
int
height
;
///< active picture (w/o VBI) height for D-10/IMX
uint32_t
tref_tag
;
int
tref_id
;
///< trackID of the referenced track
}
MOVTrack
;
typedef
struct
MOVMuxContext
{
int
mode
;
int64_t
time
;
int
nb_streams
;
int
chapter_track
;
///< qt chapter track number
int64_t
mdat_pos
;
uint64_t
mdat_size
;
MOVTrack
*
tracks
;
...
...
@@ -1183,8 +1186,8 @@ static int mov_write_tkhd_tag(ByteIOContext *pb, MOVTrack *track, AVStream *st)
put_be32
(
pb
,
0x40000000
);
/* reserved */
/* Track width and height, for visual only */
if
(
track
->
enc
->
codec_type
==
AVMEDIA_TYPE_VIDEO
||
track
->
enc
->
codec_type
==
AVMEDIA_TYPE_SUBTITLE
)
{
if
(
st
&&
(
track
->
enc
->
codec_type
==
AVMEDIA_TYPE_VIDEO
||
track
->
enc
->
codec_type
==
AVMEDIA_TYPE_SUBTITLE
)
)
{
double
sample_aspect_ratio
=
av_q2d
(
st
->
sample_aspect_ratio
);
if
(
!
sample_aspect_ratio
||
track
->
height
!=
track
->
enc
->
height
)
sample_aspect_ratio
=
1
;
...
...
@@ -1217,6 +1220,16 @@ static int mov_write_edts_tag(ByteIOContext *pb, MOVTrack *track)
return
0x24
;
}
static
int
mov_write_tref_tag
(
ByteIOContext
*
pb
,
MOVTrack
*
track
)
{
put_be32
(
pb
,
20
);
// size
put_tag
(
pb
,
"tref"
);
put_be32
(
pb
,
12
);
// size (subatom)
put_le32
(
pb
,
track
->
tref_tag
);
put_be32
(
pb
,
track
->
tref_id
);
return
20
;
}
// goes at the end of each track! ... Critical for PSP playback ("Incompatible data" without it)
static
int
mov_write_uuid_tag_psp
(
ByteIOContext
*
pb
,
MOVTrack
*
mov
)
{
...
...
@@ -1244,6 +1257,8 @@ static int mov_write_trak_tag(ByteIOContext *pb, MOVTrack *track, AVStream *st)
mov_write_tkhd_tag
(
pb
,
track
,
st
);
if
(
track
->
mode
==
MODE_PSP
||
track
->
flags
&
MOV_TRACK_CTTS
)
mov_write_edts_tag
(
pb
,
track
);
// PSP Movies require edts box
if
(
track
->
tref_tag
)
mov_write_tref_tag
(
pb
,
track
);
mov_write_mdia_tag
(
pb
,
track
);
if
(
track
->
mode
==
MODE_PSP
)
mov_write_uuid_tag_psp
(
pb
,
track
);
// PSP Movies require this uuid box
...
...
@@ -1656,11 +1671,17 @@ static int mov_write_moov_tag(ByteIOContext *pb, MOVMuxContext *mov,
mov
->
tracks
[
i
].
trackID
=
i
+
1
;
}
if
(
mov
->
chapter_track
)
for
(
i
=
0
;
i
<
s
->
nb_streams
;
i
++
)
{
mov
->
tracks
[
i
].
tref_tag
=
MKTAG
(
'c'
,
'h'
,
'a'
,
'p'
);
mov
->
tracks
[
i
].
tref_id
=
mov
->
tracks
[
mov
->
chapter_track
].
trackID
;
}
mov_write_mvhd_tag
(
pb
,
mov
);
//mov_write_iods_tag(pb, mov);
for
(
i
=
0
;
i
<
mov
->
nb_streams
;
i
++
)
{
if
(
mov
->
tracks
[
i
].
entry
>
0
)
{
mov_write_trak_tag
(
pb
,
&
(
mov
->
tracks
[
i
]),
s
->
streams
[
i
]
);
mov_write_trak_tag
(
pb
,
&
(
mov
->
tracks
[
i
]),
i
<
s
->
nb_streams
?
s
->
streams
[
i
]
:
NULL
);
}
}
...
...
@@ -1918,6 +1939,41 @@ static int mov_write_packet(AVFormatContext *s, AVPacket *pkt)
return
0
;
}
// QuickTime chapters involve an additional text track with the chapter names
// as samples, and a tref pointing from the other tracks to the chapter one.
static
void
mov_create_chapter_track
(
AVFormatContext
*
s
,
int
tracknum
)
{
MOVMuxContext
*
mov
=
s
->
priv_data
;
MOVTrack
*
track
=
&
mov
->
tracks
[
tracknum
];
AVPacket
pkt
=
{
.
stream_index
=
tracknum
,
.
flags
=
AV_PKT_FLAG_KEY
};
int
i
,
len
;
track
->
mode
=
mov
->
mode
;
track
->
tag
=
MKTAG
(
't'
,
'e'
,
'x'
,
't'
);
track
->
timescale
=
MOV_TIMESCALE
;
track
->
enc
=
avcodec_alloc_context
();
track
->
enc
->
codec_type
=
AVMEDIA_TYPE_SUBTITLE
;
for
(
i
=
0
;
i
<
s
->
nb_chapters
;
i
++
)
{
AVChapter
*
c
=
s
->
chapters
[
i
];
AVMetadataTag
*
t
;
int64_t
end
=
av_rescale_q
(
c
->
end
,
c
->
time_base
,
(
AVRational
){
1
,
MOV_TIMESCALE
});
pkt
.
pts
=
pkt
.
dts
=
av_rescale_q
(
c
->
start
,
c
->
time_base
,
(
AVRational
){
1
,
MOV_TIMESCALE
});
pkt
.
duration
=
end
-
pkt
.
dts
;
if
((
t
=
av_metadata_get
(
c
->
metadata
,
"title"
,
NULL
,
0
)))
{
len
=
strlen
(
t
->
value
);
pkt
.
size
=
len
+
2
;
pkt
.
data
=
av_malloc
(
pkt
.
size
);
AV_WB16
(
pkt
.
data
,
len
);
memcpy
(
pkt
.
data
+
2
,
t
->
value
,
len
);
mov_write_packet
(
s
,
&
pkt
);
av_freep
(
&
pkt
.
data
);
}
}
}
static
int
mov_write_header
(
AVFormatContext
*
s
)
{
ByteIOContext
*
pb
=
s
->
pb
;
...
...
@@ -1949,7 +2005,11 @@ static int mov_write_header(AVFormatContext *s)
}
}
mov
->
tracks
=
av_mallocz
(
s
->
nb_streams
*
sizeof
(
*
mov
->
tracks
));
mov
->
nb_streams
=
s
->
nb_streams
;
if
(
mov
->
mode
&
(
MODE_MOV
|
MODE_IPOD
)
&&
s
->
nb_chapters
)
mov
->
chapter_track
=
mov
->
nb_streams
++
;
mov
->
tracks
=
av_mallocz
(
mov
->
nb_streams
*
sizeof
(
*
mov
->
tracks
));
if
(
!
mov
->
tracks
)
return
AVERROR
(
ENOMEM
);
...
...
@@ -2019,7 +2079,9 @@ static int mov_write_header(AVFormatContext *s)
mov_write_mdat_tag
(
pb
,
mov
);
mov
->
time
=
s
->
timestamp
+
0x7C25B080
;
//1970 based -> 1904 based
mov
->
nb_streams
=
s
->
nb_streams
;
if
(
mov
->
chapter_track
)
mov_create_chapter_track
(
s
,
mov
->
chapter_track
);
put_flush_packet
(
pb
);
...
...
@@ -2053,6 +2115,9 @@ static int mov_write_trailer(AVFormatContext *s)
mov_write_moov_tag
(
pb
,
mov
,
s
);
if
(
mov
->
chapter_track
)
av_freep
(
&
mov
->
tracks
[
mov
->
chapter_track
].
enc
);
for
(
i
=
0
;
i
<
mov
->
nb_streams
;
i
++
)
{
av_freep
(
&
mov
->
tracks
[
i
].
cluster
);
...
...
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