FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavformat
webpenc.c
Go to the documentation of this file.
1
/*
2
* webp muxer
3
* Copyright (c) 2014 Michael Niedermayer
4
*
5
* This file is part of FFmpeg.
6
*
7
* FFmpeg is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
11
*
12
* FFmpeg is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
16
*
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with FFmpeg; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
*/
21
22
#include "
libavutil/intreadwrite.h
"
23
#include "
libavutil/opt.h
"
24
#include "
avformat.h
"
25
#include "
internal.h
"
26
27
typedef
struct
WebpContext
{
28
AVClass
*
class
;
29
int
frame_count
;
30
AVPacket
last_pkt
;
31
int
loop
;
32
}
WebpContext
;
33
34
static
int
webp_write_header
(
AVFormatContext
*
s
)
35
{
36
AVStream
*st;
37
38
if
(s->
nb_streams
!= 1) {
39
av_log
(s,
AV_LOG_ERROR
,
"Only exactly 1 stream is supported\n"
);
40
return
AVERROR
(EINVAL);
41
}
42
st = s->
streams
[0];
43
if
(st->
codec
->
codec_id
!=
AV_CODEC_ID_WEBP
) {
44
av_log
(s,
AV_LOG_ERROR
,
"Only WebP is supported\n"
);
45
return
AVERROR
(EINVAL);
46
}
47
avpriv_set_pts_info
(st, 24, 1, 1000);
48
49
avio_write
(s->
pb
,
"RIFF\0\0\0\0WEBP"
, 12);
50
51
return
0;
52
}
53
54
static
int
flush
(
AVFormatContext
*
s
,
int
trailer, int64_t pts)
55
{
56
WebpContext
*w = s->
priv_data
;
57
AVStream
*st = s->
streams
[0];
58
59
if
(w->
last_pkt
.
size
) {
60
int
skip = 0;
61
unsigned
flags
= 0;
62
int
vp8x = 0;
63
64
if
(
AV_RL32
(w->
last_pkt
.
data
) ==
AV_RL32
(
"RIFF"
))
65
skip = 12;
66
if
(
AV_RL32
(w->
last_pkt
.
data
+ skip) ==
AV_RL32
(
"VP8X"
)) {
67
flags |= w->
last_pkt
.
data
[skip + 4 + 4];
68
vp8x = 1;
69
skip +=
AV_RL32
(w->
last_pkt
.
data
+ skip + 4) + 8;
70
}
71
72
w->
frame_count
++;
73
74
if
(w->
frame_count
== 1) {
75
if
(!trailer) {
76
vp8x = 1;
77
flags |= 2 + 16;
78
}
79
80
if
(vp8x) {
81
avio_write
(s->
pb
,
"VP8X"
, 4);
82
avio_wl32
(s->
pb
, 10);
83
avio_w8
(s->
pb
, flags);
84
avio_wl24
(s->
pb
, 0);
85
avio_wl24
(s->
pb
, st->
codec
->
width
- 1);
86
avio_wl24
(s->
pb
, st->
codec
->
height
- 1);
87
}
88
if
(!trailer) {
89
avio_write
(s->
pb
,
"ANIM"
, 4);
90
avio_wl32
(s->
pb
, 6);
91
avio_wl32
(s->
pb
, 0xFFFFFFFF);
92
avio_wl16
(s->
pb
, w->
loop
);
93
}
94
}
95
96
if
(w->
frame_count
> trailer) {
97
avio_write
(s->
pb
,
"ANMF"
, 4);
98
avio_wl32
(s->
pb
, 16 + w->
last_pkt
.
size
- skip);
99
avio_wl24
(s->
pb
, 0);
100
avio_wl24
(s->
pb
, 0);
101
avio_wl24
(s->
pb
, st->
codec
->
width
- 1);
102
avio_wl24
(s->
pb
, st->
codec
->
height
- 1);
103
if
(w->
last_pkt
.
pts
!=
AV_NOPTS_VALUE
&& pts !=
AV_NOPTS_VALUE
) {
104
avio_wl24
(s->
pb
, pts - w->
last_pkt
.
pts
);
105
}
else
106
avio_wl24
(s->
pb
, w->
last_pkt
.
duration
);
107
avio_w8
(s->
pb
, 0);
108
}
109
avio_write
(s->
pb
, w->
last_pkt
.
data
+ skip, w->
last_pkt
.
size
- skip);
110
av_free_packet
(&w->
last_pkt
);
111
}
112
113
return
0;
114
}
115
116
static
int
webp_write_packet
(
AVFormatContext
*
s
,
AVPacket
*
pkt
)
117
{
118
WebpContext
*w = s->
priv_data
;
119
int
ret
;
120
121
if
((ret =
flush
(s, 0, pkt->
pts
)) < 0)
122
return
ret
;
123
124
av_copy_packet
(&w->
last_pkt
, pkt);
125
126
return
0;
127
}
128
129
static
int
webp_write_trailer
(
AVFormatContext
*
s
)
130
{
131
unsigned
filesize;
132
int
ret
;
133
134
if
((ret =
flush
(s, 1,
AV_NOPTS_VALUE
)) < 0)
135
return
ret
;
136
137
filesize =
avio_tell
(s->
pb
);
138
avio_seek
(s->
pb
, 4, SEEK_SET);
139
avio_wl32
(s->
pb
, filesize - 8);
140
141
return
0;
142
}
143
144
#define OFFSET(x) offsetof(WebpContext, x)
145
#define ENC AV_OPT_FLAG_ENCODING_PARAM
146
static
const
AVOption
options
[] = {
147
{
"loop"
,
"Number of times to loop the output: 0 - infinite loop"
,
OFFSET
(
loop
),
148
AV_OPT_TYPE_INT
, { .i64 = 1 }, 0, 65535,
ENC
},
149
{ NULL },
150
};
151
152
static
const
AVClass
webp_muxer_class
= {
153
.
class_name
=
"WebP muxer"
,
154
.item_name =
av_default_item_name
,
155
.version =
LIBAVUTIL_VERSION_INT
,
156
.option =
options
,
157
};
158
AVOutputFormat
ff_webp_muxer
= {
159
.
name
=
"webp"
,
160
.long_name =
NULL_IF_CONFIG_SMALL
(
"WebP"
),
161
.extensions =
"webp"
,
162
.priv_data_size =
sizeof
(
WebpContext
),
163
.video_codec =
AV_CODEC_ID_WEBP
,
164
.
write_header
=
webp_write_header
,
165
.
write_packet
=
webp_write_packet
,
166
.
write_trailer
=
webp_write_trailer
,
167
.priv_class = &webp_muxer_class,
168
.
flags
=
AVFMT_VARIABLE_FPS
,
169
};
Generated on Fri Dec 5 2014 04:42:15 for FFmpeg by
1.8.2