FFmpeg  2.6.3
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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;
31  int loop;
32 } WebpContext;
33 
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);
111  }
112 
113  return 0;
114 }
115 
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 
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 };
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,
167  .priv_class = &webp_muxer_class,
169 };
#define NULL
Definition: coverity.c:32
void avio_wl16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:416
const char * s
Definition: avisynth_c.h:669
void av_free_packet(AVPacket *pkt)
Free a packet.
Definition: avpacket.c:280
AVOption.
Definition: opt.h:255
#define LIBAVUTIL_VERSION_INT
Definition: version.h:62
AVPacket last_pkt
Definition: webpenc.c:30
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: utils.c:3993
int size
Definition: avcodec.h:1161
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:203
static AVPacket pkt
int loop
Definition: webpenc.c:31
Format I/O context.
Definition: avformat.h:1214
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:71
void avio_wl32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:318
AVOptions.
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1282
uint8_t * data
Definition: avcodec.h:1160
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:273
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:177
int duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: avcodec.h:1178
#define av_log(a,...)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:175
static const AVOption options[]
Definition: webpenc.c:146
av_default_item_name
#define AVERROR(e)
Definition: error.h:43
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:180
AVCodecContext * codec
Codec context associated with this stream.
Definition: avformat.h:814
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1270
ret
Definition: avfilter.c:974
int width
picture width / height.
Definition: avcodec.h:1412
static int write_trailer(AVFormatContext *s1)
Definition: v4l2enc.c:94
const char * name
Definition: avformat.h:466
static int webp_write_header(AVFormatContext *s)
Definition: webpenc.c:34
#define AV_RL32
Definition: intreadwrite.h:146
int frame_count
Definition: webpenc.c:29
static const AVClass webp_muxer_class
Definition: webpenc.c:152
Stream structure.
Definition: avformat.h:795
enum AVCodecID codec_id
Definition: avcodec.h:1256
AVIOContext * pb
I/O context.
Definition: avformat.h:1256
static int loop
Definition: ffplay.c:328
void avio_w8(AVIOContext *s, int b)
Definition: aviobuf.c:155
int av_copy_packet(AVPacket *dst, const AVPacket *src)
Copy packet, including contents.
Definition: avpacket.c:265
Describe the class of an AVClass context structure.
Definition: log.h:66
void avio_wl24(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:428
static int flush(AVFormatContext *s, int trailer, int64_t pts)
Definition: webpenc.c:54
static int64_t pts
Global timestamp for the audio frames.
static int flags
Definition: cpu.c:47
static int webp_write_packet(AVFormatContext *s, AVPacket *pkt)
Definition: webpenc.c:116
AVOutputFormat ff_webp_muxer
Definition: webpenc.c:158
Main libavformat public API header.
#define AVFMT_VARIABLE_FPS
Format allows variable fps.
Definition: avformat.h:428
void * priv_data
Format private data.
Definition: avformat.h:1242
#define OFFSET(x)
Definition: webpenc.c:144
static void write_header(FFV1Context *f)
Definition: ffv1enc.c:493
static int webp_write_trailer(AVFormatContext *s)
Definition: webpenc.c:129
This structure stores compressed data.
Definition: avcodec.h:1137
static int write_packet(AVFormatContext *s1, AVPacket *pkt)
Definition: v4l2enc.c:86
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1153
#define ENC
Definition: webpenc.c:145
#define AV_NOPTS_VALUE
Undefined timestamp value.
Definition: avutil.h:241