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
4d0cd5f5
Commit
4d0cd5f5
authored
Nov 07, 2014
by
Andrew Stone
Committed by
Anton Khirnov
Nov 17, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
flvenc: move metadata updates into a single function
Signed-off-by:
Anton Khirnov
<
anton@khirnov.net
>
parent
8b573ddd
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
103 additions
and
90 deletions
+103
-90
flvenc.c
libavformat/flvenc.c
+103
-90
No files found.
libavformat/flvenc.c
View file @
4d0cd5f5
...
...
@@ -60,6 +60,11 @@ typedef struct FLVContext {
int64_t
filesize_offset
;
int64_t
duration
;
int64_t
delay
;
///< first dts delay (needed for AVC & Speex)
AVCodecContext
*
audio_enc
;
AVCodecContext
*
video_enc
;
double
framerate
;
AVCodecContext
*
data_enc
;
}
FLVContext
;
typedef
struct
FLVStreamContext
{
...
...
@@ -187,85 +192,14 @@ static void put_amf_bool(AVIOContext *pb, int b)
avio_w8
(
pb
,
!!
b
);
}
static
int
flv_write_header
(
AVFormatContext
*
s
)
static
void
write_metadata
(
AVFormatContext
*
s
)
{
AVIOContext
*
pb
=
s
->
pb
;
FLVContext
*
flv
=
s
->
priv_data
;
AVCodecContext
*
audio_enc
=
NULL
,
*
video_enc
=
NULL
,
*
data_enc
=
NULL
;
int
i
,
metadata_count
=
0
;
double
framerate
=
0
.
0
;
int64_t
metadata_size_pos
,
data_size
,
metadata_count_pos
;
AVDictionaryEntry
*
tag
=
NULL
;
for
(
i
=
0
;
i
<
s
->
nb_streams
;
i
++
)
{
AVCodecContext
*
enc
=
s
->
streams
[
i
]
->
codec
;
FLVStreamContext
*
sc
;
switch
(
enc
->
codec_type
)
{
case
AVMEDIA_TYPE_VIDEO
:
if
(
s
->
streams
[
i
]
->
avg_frame_rate
.
den
&&
s
->
streams
[
i
]
->
avg_frame_rate
.
num
)
{
framerate
=
av_q2d
(
s
->
streams
[
i
]
->
avg_frame_rate
);
}
if
(
video_enc
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"at most one video stream is supported in flv
\n
"
);
return
AVERROR
(
EINVAL
);
}
video_enc
=
enc
;
if
(
enc
->
codec_tag
==
0
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"video codec not compatible with flv
\n
"
);
return
-
1
;
}
break
;
case
AVMEDIA_TYPE_AUDIO
:
if
(
audio_enc
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"at most one audio stream is supported in flv
\n
"
);
return
AVERROR
(
EINVAL
);
}
audio_enc
=
enc
;
if
(
get_audio_flags
(
s
,
enc
)
<
0
)
return
AVERROR_INVALIDDATA
;
break
;
case
AVMEDIA_TYPE_DATA
:
if
(
enc
->
codec_id
!=
AV_CODEC_ID_TEXT
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"codec not compatible with flv
\n
"
);
return
AVERROR_INVALIDDATA
;
}
data_enc
=
enc
;
break
;
default:
av_log
(
s
,
AV_LOG_ERROR
,
"codec not compatible with flv
\n
"
);
return
-
1
;
}
avpriv_set_pts_info
(
s
->
streams
[
i
],
32
,
1
,
1000
);
/* 32 bit pts in ms */
sc
=
av_mallocz
(
sizeof
(
FLVStreamContext
));
if
(
!
sc
)
return
AVERROR
(
ENOMEM
);
s
->
streams
[
i
]
->
priv_data
=
sc
;
sc
->
last_ts
=
-
1
;
}
flv
->
delay
=
AV_NOPTS_VALUE
;
avio_write
(
pb
,
"FLV"
,
3
);
avio_w8
(
pb
,
1
);
avio_w8
(
pb
,
FLV_HEADER_FLAG_HASAUDIO
*
!!
audio_enc
+
FLV_HEADER_FLAG_HASVIDEO
*
!!
video_enc
);
avio_wb32
(
pb
,
9
);
avio_wb32
(
pb
,
0
);
for
(
i
=
0
;
i
<
s
->
nb_streams
;
i
++
)
if
(
s
->
streams
[
i
]
->
codec
->
codec_tag
==
5
)
{
avio_w8
(
pb
,
8
);
// message type
avio_wb24
(
pb
,
0
);
// include flags
avio_wb24
(
pb
,
0
);
// time stamp
avio_wb32
(
pb
,
0
);
// reserved
avio_wb32
(
pb
,
11
);
// size
flv
->
reserved
=
5
;
}
/* write meta_tag */
avio_w8
(
pb
,
18
);
// tag type META
metadata_size_pos
=
avio_tell
(
pb
);
...
...
@@ -282,57 +216,57 @@ static int flv_write_header(AVFormatContext *s)
/* mixed array (hash) with size and string/type/data tuples */
avio_w8
(
pb
,
AMF_DATA_TYPE_MIXEDARRAY
);
metadata_count_pos
=
avio_tell
(
pb
);
metadata_count
=
4
*
!!
video_enc
+
5
*
!!
audio_enc
+
1
*
!!
data_enc
+
metadata_count
=
4
*
!!
flv
->
video_enc
+
5
*
!!
flv
->
audio_enc
+
1
*
!!
flv
->
data_enc
+
2
;
// +2 for duration and file size
avio_wb32
(
pb
,
metadata_count
);
put_amf_string
(
pb
,
"duration"
);
flv
->
duration_offset
=
avio_tell
(
pb
);
flv
->
duration_offset
=
avio_tell
(
pb
);
// fill in the guessed duration, it'll be corrected later if incorrect
put_amf_double
(
pb
,
s
->
duration
/
AV_TIME_BASE
);
if
(
video_enc
)
{
if
(
flv
->
video_enc
)
{
put_amf_string
(
pb
,
"width"
);
put_amf_double
(
pb
,
video_enc
->
width
);
put_amf_double
(
pb
,
flv
->
video_enc
->
width
);
put_amf_string
(
pb
,
"height"
);
put_amf_double
(
pb
,
video_enc
->
height
);
put_amf_double
(
pb
,
flv
->
video_enc
->
height
);
put_amf_string
(
pb
,
"videodatarate"
);
put_amf_double
(
pb
,
video_enc
->
bit_rate
/
1024
.
0
);
put_amf_double
(
pb
,
flv
->
video_enc
->
bit_rate
/
1024
.
0
);
if
(
framerate
!=
0
.
0
)
{
if
(
f
lv
->
f
ramerate
!=
0
.
0
)
{
put_amf_string
(
pb
,
"framerate"
);
put_amf_double
(
pb
,
framerate
);
put_amf_double
(
pb
,
f
lv
->
f
ramerate
);
metadata_count
++
;
}
put_amf_string
(
pb
,
"videocodecid"
);
put_amf_double
(
pb
,
video_enc
->
codec_tag
);
put_amf_double
(
pb
,
flv
->
video_enc
->
codec_tag
);
}
if
(
audio_enc
)
{
if
(
flv
->
audio_enc
)
{
put_amf_string
(
pb
,
"audiodatarate"
);
put_amf_double
(
pb
,
audio_enc
->
bit_rate
/
1024
.
0
);
put_amf_double
(
pb
,
flv
->
audio_enc
->
bit_rate
/
1024
.
0
);
put_amf_string
(
pb
,
"audiosamplerate"
);
put_amf_double
(
pb
,
audio_enc
->
sample_rate
);
put_amf_double
(
pb
,
flv
->
audio_enc
->
sample_rate
);
put_amf_string
(
pb
,
"audiosamplesize"
);
put_amf_double
(
pb
,
audio_enc
->
codec_id
==
AV_CODEC_ID_PCM_U8
?
8
:
16
);
put_amf_double
(
pb
,
flv
->
audio_enc
->
codec_id
==
AV_CODEC_ID_PCM_U8
?
8
:
16
);
put_amf_string
(
pb
,
"stereo"
);
put_amf_bool
(
pb
,
audio_enc
->
channels
==
2
);
put_amf_bool
(
pb
,
flv
->
audio_enc
->
channels
==
2
);
put_amf_string
(
pb
,
"audiocodecid"
);
put_amf_double
(
pb
,
audio_enc
->
codec_tag
);
put_amf_double
(
pb
,
flv
->
audio_enc
->
codec_tag
);
}
if
(
data_enc
)
{
if
(
flv
->
data_enc
)
{
put_amf_string
(
pb
,
"datastream"
);
put_amf_double
(
pb
,
0
.
0
);
}
...
...
@@ -361,6 +295,85 @@ static int flv_write_header(AVFormatContext *s)
avio_wb24
(
pb
,
data_size
);
avio_skip
(
pb
,
data_size
+
10
-
3
);
avio_wb32
(
pb
,
data_size
+
11
);
}
static
int
flv_write_header
(
AVFormatContext
*
s
)
{
int
i
;
AVIOContext
*
pb
=
s
->
pb
;
FLVContext
*
flv
=
s
->
priv_data
;
int64_t
data_size
;
for
(
i
=
0
;
i
<
s
->
nb_streams
;
i
++
)
{
AVCodecContext
*
enc
=
s
->
streams
[
i
]
->
codec
;
FLVStreamContext
*
sc
;
switch
(
enc
->
codec_type
)
{
case
AVMEDIA_TYPE_VIDEO
:
if
(
s
->
streams
[
i
]
->
avg_frame_rate
.
den
&&
s
->
streams
[
i
]
->
avg_frame_rate
.
num
)
{
flv
->
framerate
=
av_q2d
(
s
->
streams
[
i
]
->
avg_frame_rate
);
}
if
(
flv
->
video_enc
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"at most one video stream is supported in flv
\n
"
);
return
AVERROR
(
EINVAL
);
}
flv
->
video_enc
=
enc
;
if
(
enc
->
codec_tag
==
0
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"video codec not compatible with flv
\n
"
);
return
-
1
;
}
break
;
case
AVMEDIA_TYPE_AUDIO
:
if
(
flv
->
audio_enc
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"at most one audio stream is supported in flv
\n
"
);
return
AVERROR
(
EINVAL
);
}
flv
->
audio_enc
=
enc
;
if
(
get_audio_flags
(
s
,
enc
)
<
0
)
return
AVERROR_INVALIDDATA
;
break
;
case
AVMEDIA_TYPE_DATA
:
if
(
enc
->
codec_id
!=
AV_CODEC_ID_TEXT
)
{
av_log
(
s
,
AV_LOG_ERROR
,
"codec not compatible with flv
\n
"
);
return
AVERROR_INVALIDDATA
;
}
flv
->
data_enc
=
enc
;
break
;
default:
av_log
(
s
,
AV_LOG_ERROR
,
"codec not compatible with flv
\n
"
);
return
-
1
;
}
avpriv_set_pts_info
(
s
->
streams
[
i
],
32
,
1
,
1000
);
/* 32 bit pts in ms */
sc
=
av_mallocz
(
sizeof
(
FLVStreamContext
));
if
(
!
sc
)
return
AVERROR
(
ENOMEM
);
s
->
streams
[
i
]
->
priv_data
=
sc
;
sc
->
last_ts
=
-
1
;
}
flv
->
delay
=
AV_NOPTS_VALUE
;
avio_write
(
pb
,
"FLV"
,
3
);
avio_w8
(
pb
,
1
);
avio_w8
(
pb
,
FLV_HEADER_FLAG_HASAUDIO
*
!!
flv
->
audio_enc
+
FLV_HEADER_FLAG_HASVIDEO
*
!!
flv
->
video_enc
);
avio_wb32
(
pb
,
9
);
avio_wb32
(
pb
,
0
);
for
(
i
=
0
;
i
<
s
->
nb_streams
;
i
++
)
if
(
s
->
streams
[
i
]
->
codec
->
codec_tag
==
5
)
{
avio_w8
(
pb
,
8
);
// message type
avio_wb24
(
pb
,
0
);
// include flags
avio_wb24
(
pb
,
0
);
// time stamp
avio_wb32
(
pb
,
0
);
// reserved
avio_wb32
(
pb
,
11
);
// size
flv
->
reserved
=
5
;
}
write_metadata
(
s
);
for
(
i
=
0
;
i
<
s
->
nb_streams
;
i
++
)
{
AVCodecContext
*
enc
=
s
->
streams
[
i
]
->
codec
;
...
...
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