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 Sun Mar 8 2015 02:35:13 for FFmpeg by
1.8.2