FFmpeg
Loading...
Searching...
No Matches
libtheoraenc.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 2006 Paul Richards <paul.richards@gmail.com>
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21/**
22 * @file
23 * @brief Theora encoder using libtheora.
24 * @author Paul Richards <paul.richards@gmail.com>
25 *
26 * A lot of this is copy / paste from other output codecs in
27 * libavcodec or pure guesswork (or both).
28 *
29 * I have used t_ prefixes on variables which are libtheora types
30 * and o_ prefixes on variables which are libogg types.
31 */
32
33/* FFmpeg includes */
34#include "libavutil/common.h"
36#include "libavutil/mem.h"
37#include "libavutil/pixdesc.h"
38#include "libavutil/log.h"
39#include "libavutil/base64.h"
40#include "libavutil/opt.h"
41#include "avcodec.h"
42#include "codec_internal.h"
43#include "encode.h"
44
45/* libtheora includes */
46#include <theora/theoraenc.h>
47
48typedef struct TheoraContext {
49 AVClass *av_class; /**< class for AVOptions */
50 th_enc_ctx *t_state;
51 uint8_t *stats;
56 unsigned keyframe_mask;
59
60static const AVOption options[] = {
61 { "speed_level", "Sets the encoding speed level", offsetof(TheoraContext, speed_level), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM },
62 { NULL }
63};
64
65static const AVClass theora_class = {
66 .class_name = "libtheora",
67 .item_name = av_default_item_name,
68 .option = options,
69 .version = LIBAVUTIL_VERSION_INT,
70};
71
72/** Concatenate an ogg_packet into the extradata. */
73static int concatenate_packet(unsigned int* offset,
74 AVCodecContext* avc_context,
75 const ogg_packet* packet)
76{
77 const char* message = NULL;
78 int newsize = avc_context->extradata_size + 2 + packet->bytes;
79 int err = AVERROR_INVALIDDATA;
80
81 if (packet->bytes < 0) {
82 message = "ogg_packet has negative size";
83 } else if (packet->bytes > 0xffff) {
84 message = "ogg_packet is larger than 65535 bytes";
85 } else if (newsize < avc_context->extradata_size) {
86 message = "extradata_size would overflow";
87 } else {
88 if ((err = av_reallocp(&avc_context->extradata, newsize)) < 0) {
89 avc_context->extradata_size = 0;
90 message = "av_realloc failed";
91 }
92 }
93 if (message) {
94 av_log(avc_context, AV_LOG_ERROR, "concatenate_packet failed: %s\n", message);
95 return err;
96 }
97
98 avc_context->extradata_size = newsize;
99 AV_WB16(avc_context->extradata + (*offset), packet->bytes);
100 *offset += 2;
101 memcpy(avc_context->extradata + (*offset), packet->packet, packet->bytes);
102 (*offset) += packet->bytes;
103 return 0;
104}
105
106static int get_stats(AVCodecContext *avctx, int eos)
107{
108#ifdef TH_ENCCTL_2PASS_OUT
109 TheoraContext *h = avctx->priv_data;
110 uint8_t *buf;
111 int bytes;
112
113 bytes = th_encode_ctl(h->t_state, TH_ENCCTL_2PASS_OUT, &buf, sizeof(buf));
114 if (bytes < 0) {
115 av_log(avctx, AV_LOG_ERROR, "Error getting first pass stats\n");
116 return AVERROR_EXTERNAL;
117 }
118 if (!eos) {
119 void *tmp = av_fast_realloc(h->stats, &h->stats_size,
120 h->stats_offset + bytes);
121 if (!tmp)
122 return AVERROR(ENOMEM);
123 h->stats = tmp;
124 memcpy(h->stats + h->stats_offset, buf, bytes);
125 h->stats_offset += bytes;
126 } else {
127 int b64_size = AV_BASE64_SIZE(h->stats_offset);
128 // libtheora generates a summary header at the end
129 memcpy(h->stats, buf, bytes);
130 avctx->stats_out = av_malloc(b64_size);
131 if (!avctx->stats_out)
132 return AVERROR(ENOMEM);
133 av_base64_encode(avctx->stats_out, b64_size, h->stats, h->stats_offset);
134 }
135 return 0;
136#else
137 av_log(avctx, AV_LOG_ERROR, "libtheora too old to support 2pass\n");
138 return AVERROR(ENOTSUP);
139#endif
140}
141
142// libtheora won't read the entire buffer we give it at once, so we have to
143// repeatedly submit it...
144static int submit_stats(AVCodecContext *avctx)
145{
146#ifdef TH_ENCCTL_2PASS_IN
147 TheoraContext *h = avctx->priv_data;
148 int bytes;
149 if (!h->stats) {
150 if (!avctx->stats_in) {
151 av_log(avctx, AV_LOG_ERROR, "No statsfile for second pass\n");
152 return AVERROR(EINVAL);
153 }
154 h->stats_size = strlen(avctx->stats_in) * 3/4;
155 h->stats = av_malloc(h->stats_size);
156 if (!h->stats) {
157 h->stats_size = 0;
158 return AVERROR(ENOMEM);
159 }
160 h->stats_size = av_base64_decode(h->stats, avctx->stats_in, h->stats_size);
161 }
162 while (h->stats_size - h->stats_offset > 0) {
163 bytes = th_encode_ctl(h->t_state, TH_ENCCTL_2PASS_IN,
164 h->stats + h->stats_offset,
165 h->stats_size - h->stats_offset);
166 if (bytes < 0) {
167 av_log(avctx, AV_LOG_ERROR, "Error submitting stats\n");
168 return AVERROR_EXTERNAL;
169 }
170 if (!bytes)
171 return 0;
172 h->stats_offset += bytes;
173 }
174 return 0;
175#else
176 av_log(avctx, AV_LOG_ERROR, "libtheora too old to support 2pass\n");
177 return AVERROR(ENOTSUP);
178#endif
179}
180
181static av_cold int encode_init(AVCodecContext* avc_context)
182{
183 th_info t_info;
184 th_comment t_comment;
185 ogg_packet o_packet;
186 unsigned int offset;
187 TheoraContext *h = avc_context->priv_data;
188 uint32_t gop_size = avc_context->gop_size;
189 int ret;
190
191 /* Set up the theora_info struct */
192 th_info_init(&t_info);
193 t_info.frame_width = FFALIGN(avc_context->width, 16);
194 t_info.frame_height = FFALIGN(avc_context->height, 16);
195 t_info.pic_width = avc_context->width;
196 t_info.pic_height = avc_context->height;
197 t_info.pic_x = 0;
198 t_info.pic_y = 0;
199 /* Swap numerator and denominator as time_base in AVCodecContext gives the
200 * time period between frames, but theora_info needs the framerate. */
201 t_info.fps_numerator = avc_context->time_base.den;
202 t_info.fps_denominator = avc_context->time_base.num;
203 if (avc_context->sample_aspect_ratio.num) {
204 t_info.aspect_numerator = avc_context->sample_aspect_ratio.num;
205 t_info.aspect_denominator = avc_context->sample_aspect_ratio.den;
206 } else {
207 t_info.aspect_numerator = 1;
208 t_info.aspect_denominator = 1;
209 }
210
211 if (avc_context->color_primaries == AVCOL_PRI_BT470M)
212 t_info.colorspace = TH_CS_ITU_REC_470M;
213 else if (avc_context->color_primaries == AVCOL_PRI_BT470BG)
214 t_info.colorspace = TH_CS_ITU_REC_470BG;
215 else
216 t_info.colorspace = TH_CS_UNSPECIFIED;
217
218 if (avc_context->pix_fmt == AV_PIX_FMT_YUV420P)
219 t_info.pixel_fmt = TH_PF_420;
220 else if (avc_context->pix_fmt == AV_PIX_FMT_YUV422P)
221 t_info.pixel_fmt = TH_PF_422;
222 else if (avc_context->pix_fmt == AV_PIX_FMT_YUV444P)
223 t_info.pixel_fmt = TH_PF_444;
224 else {
225 av_log(avc_context, AV_LOG_ERROR, "Unsupported pix_fmt\n");
226 return AVERROR(EINVAL);
227 }
228 ret = av_pix_fmt_get_chroma_sub_sample(avc_context->pix_fmt, &h->uv_hshift, &h->uv_vshift);
229 if (ret)
230 return ret;
231
232 if (avc_context->flags & AV_CODEC_FLAG_QSCALE) {
233 /* Clip global_quality in QP units to the [0 - 10] range
234 to be consistent with the libvorbis implementation.
235 Theora accepts a quality parameter which is an int value in
236 the [0 - 63] range.
237 */
238 t_info.quality = av_clipf(avc_context->global_quality / (float)FF_QP2LAMBDA, 0, 10) * 6.3;
239 t_info.target_bitrate = 0;
240 } else {
241 t_info.target_bitrate = avc_context->bit_rate;
242 t_info.quality = 0;
243 }
244
245 /* Now initialise libtheora */
246 h->t_state = th_encode_alloc(&t_info);
247 if (!h->t_state) {
248 av_log(avc_context, AV_LOG_ERROR, "theora_encode_init failed\n");
249 return AVERROR_EXTERNAL;
250 }
251
252 h->keyframe_mask = (1U << av_ceil_log2(avc_context->gop_size)) - 1;
253 /* Clear up theora_info struct */
254 th_info_clear(&t_info);
255
256 if (th_encode_ctl(h->t_state, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
257 &gop_size, sizeof(gop_size))) {
258 av_log(avc_context, AV_LOG_ERROR, "Error setting GOP size\n");
259 return AVERROR_EXTERNAL;
260 }
261
262 // Set encoding speed level
263 if (h->speed_level != -1) {
264 int max_speed_level;
265 int speed_level = h->speed_level;
266 th_encode_ctl(h->t_state, TH_ENCCTL_GET_SPLEVEL_MAX, &max_speed_level, sizeof(max_speed_level));
267 speed_level = FFMIN(speed_level, max_speed_level);
268 th_encode_ctl(h->t_state, TH_ENCCTL_SET_SPLEVEL, &speed_level, sizeof(speed_level));
269 }
270
271 // need to enable 2 pass (via TH_ENCCTL_2PASS_) before encoding headers
272 if (avc_context->flags & AV_CODEC_FLAG_PASS1) {
273 if ((ret = get_stats(avc_context, 0)) < 0)
274 return ret;
275 } else if (avc_context->flags & AV_CODEC_FLAG_PASS2) {
276 if ((ret = submit_stats(avc_context)) < 0)
277 return ret;
278 }
279
280 /*
281 Output first header packet consisting of theora
282 header, comment, and tables.
283
284 Each one is prefixed with a 16-bit size, then they
285 are concatenated together into libavcodec's extradata.
286 */
287 offset = 0;
288
289 /* Headers */
290 th_comment_init(&t_comment);
291
292 while (th_encode_flushheader(h->t_state, &t_comment, &o_packet))
293 if ((ret = concatenate_packet(&offset, avc_context, &o_packet)) < 0)
294 return ret;
295
296 th_comment_clear(&t_comment);
297
298 return 0;
299}
300
301static int encode_frame(AVCodecContext* avc_context, AVPacket *pkt,
302 const AVFrame *frame, int *got_packet)
303{
304 th_ycbcr_buffer t_yuv_buffer;
305 TheoraContext *h = avc_context->priv_data;
306 ogg_packet o_packet;
307 int result, i, ret;
308
309 // EOS, finish and get 1st pass stats if applicable
310 if (!frame) {
311 th_encode_packetout(h->t_state, 1, &o_packet);
312 if (avc_context->flags & AV_CODEC_FLAG_PASS1)
313 if ((ret = get_stats(avc_context, 1)) < 0)
314 return ret;
315 return 0;
316 }
317
318 /* Copy planes to the theora yuv_buffer */
319 for (i = 0; i < 3; i++) {
320 t_yuv_buffer[i].width = FFALIGN(avc_context->width, 16) >> (i && h->uv_hshift);
321 t_yuv_buffer[i].height = FFALIGN(avc_context->height, 16) >> (i && h->uv_vshift);
322 t_yuv_buffer[i].stride = frame->linesize[i];
323 t_yuv_buffer[i].data = frame->data[i];
324 }
325
326 if (avc_context->flags & AV_CODEC_FLAG_PASS2)
327 if ((ret = submit_stats(avc_context)) < 0)
328 return ret;
329
330 /* Now call into theora_encode_YUVin */
331 result = th_encode_ycbcr_in(h->t_state, t_yuv_buffer);
332 if (result) {
333 const char* message;
334 switch (result) {
335 case -1:
336 message = "differing frame sizes";
337 break;
338 case TH_EINVAL:
339 message = "encoder is not ready or is finished";
340 break;
341 default:
342 message = "unknown reason";
343 break;
344 }
345 av_log(avc_context, AV_LOG_ERROR, "theora_encode_YUVin failed (%s) [%d]\n", message, result);
346 return AVERROR_EXTERNAL;
347 }
348
349 if (avc_context->flags & AV_CODEC_FLAG_PASS1)
350 if ((ret = get_stats(avc_context, 0)) < 0)
351 return ret;
352
353 /* Pick up returned ogg_packet */
354 result = th_encode_packetout(h->t_state, 0, &o_packet);
355 switch (result) {
356 case 0:
357 /* No packet is ready */
358 return 0;
359 case 1:
360 /* Success, we have a packet */
361 break;
362 default:
363 av_log(avc_context, AV_LOG_ERROR, "theora_encode_packetout failed [%d]\n", result);
364 return AVERROR_EXTERNAL;
365 }
366
367 /* Copy ogg_packet content out to buffer */
368 if ((ret = ff_get_encode_buffer(avc_context, pkt, o_packet.bytes, 0)) < 0)
369 return ret;
370 memcpy(pkt->data, o_packet.packet, o_packet.bytes);
371
372 // HACK: assumes no encoder delay, this is true until libtheora becomes
373 // multithreaded (which will be disabled unless explicitly requested)
374 pkt->pts = frame->pts;
375 pkt->duration = frame->duration;
376
377 ret = ff_encode_reordered_opaque(avc_context, pkt, frame);
378 if (ret < 0)
379 return ret;
380
381 if (!(o_packet.granulepos & h->keyframe_mask))
382 pkt->flags |= AV_PKT_FLAG_KEY;
383 *got_packet = 1;
384
385 return 0;
386}
387
388static av_cold int encode_close(AVCodecContext* avc_context)
389{
390 TheoraContext *h = avc_context->priv_data;
391
392 th_encode_free(h->t_state);
393 av_freep(&h->stats);
394 av_freep(&avc_context->stats_out);
395 avc_context->extradata_size = 0;
396
397 return 0;
398}
399
400/** AVCodec struct exposed to libavcodec */
402 .p.name = "libtheora",
403 CODEC_LONG_NAME("libtheora Theora"),
404 .p.type = AVMEDIA_TYPE_VIDEO,
405 .p.id = AV_CODEC_ID_THEORA,
406 .p.capabilities = AV_CODEC_CAP_DR1 |
407 /* for statsfile summary */
410 .caps_internal = FF_CODEC_CAP_NOT_INIT_THREADSAFE,
411 .priv_data_size = sizeof(TheoraContext),
412 .init = encode_init,
416 .p.priv_class = &theora_class,
417 .color_ranges = AVCOL_RANGE_MPEG,
418 .p.wrapper_name = "libtheora",
419};
const FFCodec ff_libtheora_encoder
AVCodec struct exposed to libavcodec.
static av_cold void close(AVCodecParserContext *s)
Definition apv_parser.c:197
static av_cold int encode_init(AVCodecContext *avctx)
Definition asvenc.c:373
Libavcodec external API header.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define CODEC_PIXFMTS(...)
#define FF_CODEC_CAP_NOT_INIT_THREADSAFE
The codec is not known to be init-threadsafe (i.e.
#define FF_CODEC_ENCODE_CB(func)
#define CODEC_LONG_NAME(str)
common internal and external API header
#define av_clipf
Definition common.h:145
#define av_ceil_log2
Definition common.h:97
#define NULL
Definition coverity.c:32
static av_cold int encode_close(AVCodecContext *avctx)
Definition dcaenc.c:354
static AVPacket * pkt
static AVFrame * frame
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags)
Get a buffer for a packet.
Definition encode.c:106
int ff_encode_reordered_opaque(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame)
Propagate user opaque values from the frame to avctx/pkt as needed.
Definition encode.c:280
static int encode_frame(OutputFile *of, OutputStream *ost, AVFrame *frame, AVPacket *pkt)
Definition ffmpeg_enc.c:694
#define AV_OPT_FLAG_VIDEO_PARAM
Definition opt.h:357
#define AV_OPT_FLAG_ENCODING_PARAM
A generic parameter which can be set by the user for muxing or encoding.
Definition opt.h:351
@ AV_OPT_TYPE_INT
Underlying C type is int.
Definition opt.h:258
#define AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
This encoder can reorder user opaque values from input AVFrames and return them with corresponding ou...
Definition codec.h:147
#define AV_CODEC_FLAG_PASS2
Use internal 2pass ratecontrol in second pass mode.
Definition avcodec.h:294
#define AV_CODEC_CAP_DELAY
Encoder or decoder requires flushing with NULL input at the end in order to give the complete and cor...
Definition codec.h:79
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition codec.h:49
#define AV_CODEC_FLAG_QSCALE
Use fixed qscale.
Definition avcodec.h:213
#define AV_CODEC_FLAG_PASS1
Use internal 2pass ratecontrol in first pass mode.
Definition avcodec.h:290
@ AV_CODEC_ID_THEORA
Definition codec_id.h:80
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition packet.h:650
char * av_base64_encode(char *out, int out_size, const uint8_t *in, int in_size)
Encode data to base64 and null-terminate.
Definition base64.c:147
#define AV_BASE64_SIZE(x)
Calculate the output size needed to base64-encode x bytes to a null-terminated string.
Definition base64.h:66
int av_base64_decode(uint8_t *out, const char *in_str, int out_size)
Decode a base64-encoded string.
Definition base64.c:81
#define FF_QP2LAMBDA
factor to convert from H.263 QP to lambda
Definition avutil.h:226
#define AVERROR_EXTERNAL
Generic error in an external library.
Definition error.h:59
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
const char * av_default_item_name(void *ptr)
Return the context name.
Definition log.c:241
void * av_fast_realloc(void *ptr, unsigned int *size, size_t min_size)
Reallocate the given buffer if it is not large enough, otherwise do nothing.
Definition mem.c:495
int av_reallocp(void *ptr, size_t size)
Allocate, reallocate, or free a block of memory through a pointer to a pointer.
Definition mem.c:188
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define LIBAVUTIL_VERSION_INT
Definition version.h:85
#define AV_WB16(p, v)
unsigned offset
Definition libaomenc.c:763
#define av_cold
Definition attributes.h:117
static av_cold int encode_init(AVCodecContext *avc_context)
static const AVClass theora_class
static int concatenate_packet(unsigned int *offset, AVCodecContext *avc_context, const ogg_packet *packet)
Concatenate an ogg_packet into the extradata.
static int encode_frame(AVCodecContext *avc_context, AVPacket *pkt, const AVFrame *frame, int *got_packet)
static av_cold int encode_close(AVCodecContext *avc_context)
static int submit_stats(AVCodecContext *avctx)
static int get_stats(AVCodecContext *avctx, int eos)
#define FFMIN(a, b)
Definition macros.h:49
#define FFALIGN(x, a)
Definition macros.h:78
Memory handling functions.
static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize, int64_t *fpos)
find the next Ogg packet
Definition oggdec.c:503
#define av_malloc(s)
Definition ops_static.c:52
AVOptions.
int av_pix_fmt_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift)
Utility function to access log2_chroma_w log2_chroma_h from the pixel format AVPixFmtDescriptor.
Definition pixdesc.c:3488
@ AVCOL_RANGE_MPEG
Narrow or limited range content.
Definition pixfmt.h:766
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition pixfmt.h:73
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition pixfmt.h:77
@ AV_PIX_FMT_YUV444P
planar YUV 4:4:4, 24bpp, (1 Cr & Cb sample per 1x1 Y samples)
Definition pixfmt.h:78
@ AVCOL_PRI_BT470BG
also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM
Definition pixfmt.h:649
@ AVCOL_PRI_BT470M
also FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
Definition pixfmt.h:647
Describe the class of an AVClass context structure.
Definition log.h:76
main external API structure.
Definition avcodec.h:443
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:643
int width
picture width / height.
Definition avcodec.h:604
char * stats_out
pass1 encoding statistics output buffer
Definition avcodec.h:1330
int global_quality
Global quality for codecs which cannot change it per frame.
Definition avcodec.h:1235
enum AVColorPrimaries color_primaries
Chromaticity coordinates of the source primaries.
Definition avcodec.h:657
char * stats_in
pass2 encoding statistics input buffer Concatenated stuff from stats_out of pass1 should be placed he...
Definition avcodec.h:1338
AVRational sample_aspect_ratio
sample aspect ratio (0 if unknown) That is the width of a pixel divided by the height of the pixel.
Definition avcodec.h:628
int64_t bit_rate
the average bitrate
Definition avcodec.h:493
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
Definition avcodec.h:1021
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
Definition avcodec.h:547
int flags
AV_CODEC_FLAG_*.
Definition avcodec.h:500
uint8_t * extradata
Out-of-band global headers that may be used by some codecs.
Definition avcodec.h:526
int extradata_size
Definition avcodec.h:527
void * priv_data
Definition avcodec.h:470
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
AVOption.
Definition opt.h:428
This structure stores compressed data.
Definition packet.h:580
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
unsigned keyframe_mask
th_enc_ctx * t_state
uint8_t * stats
AVClass * av_class
class for AVOptions
#define av_freep(p)
#define av_log(a,...)
static uint8_t tmp[40]
Definition aes_ctr.c:52
static int gop_size
Definition movenc.c:68