annotate libtheoraenc.c @ 10381:9262948fd649 libavcodec

Hack: set the coded frame PTS to the incoming PTS. This is not correct, but libtheora does not seem to provide a way to get the correct value, and this is necessary to make encoding produce sensible time stamps when encoded content is variable FPS or the time base is simply different from FPS. Somewhat fixes issue 1197.
author reimar
date Sat, 10 Oct 2009 14:43:31 +0000
parents dfb91c11fe9c
children 00bd0c4c1489
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4403
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
1 /*
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
2 * Copyright (c) 2006 Paul Richards <paul.richards@gmail.com>
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
3 *
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
4 * This file is part of FFmpeg.
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
5 *
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
6 * FFmpeg is free software; you can redistribute it and/or
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
7 * modify it under the terms of the GNU Lesser General Public
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
8 * License as published by the Free Software Foundation; either
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
9 * version 2.1 of the License, or (at your option) any later version.
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
10 *
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
11 * FFmpeg is distributed in the hope that it will be useful,
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
14 * Lesser General Public License for more details.
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
15 *
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
16 * You should have received a copy of the GNU Lesser General Public
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
17 * License along with FFmpeg; if not, write to the Free Software
5215
2b72f9bc4f06 license header consistency cosmetics
diego
parents: 5089
diff changeset
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
4403
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
19 */
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
20
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
21 /*!
8673
5b7d5a33a3e2 Fix filenames in Doxygen comments.
diego
parents: 8574
diff changeset
22 * \file libtheoraenc.c
4403
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
23 * \brief Theora encoder using libtheora.
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
24 * \author Paul Richards <paul.richards@gmail.com>
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
25 *
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
26 * A lot of this is copy / paste from other output codecs in
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
27 * libavcodec or pure guesswork (or both).
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
28 *
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
29 * I have used t_ prefixes on variables which are libtheora types
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
30 * and o_ prefixes on variables which are libogg types.
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
31 */
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
32
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
33 /* FFmpeg includes */
8574
d679fd3a5359 Add missing inclusion of libavutil/intreadwrite.h, fix compilation when
stefano
parents: 7040
diff changeset
34 #include "libavutil/intreadwrite.h"
6763
f7cbb7733146 Use full path for #includes from another directory.
diego
parents: 6712
diff changeset
35 #include "libavutil/log.h"
4403
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
36 #include "avcodec.h"
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
37
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
38 /* libtheora includes */
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
39 #include <theora/theora.h>
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
40
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
41 typedef struct TheoraContext{
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
42 theora_state t_state;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
43 } TheoraContext;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
44
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
45 /*!
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
46 Concatenates an ogg_packet into the extradata.
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
47 */
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
48 static int concatenate_packet(unsigned int* offset, AVCodecContext* avc_context, const ogg_packet* packet)
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
49 {
9952
4b3abcad0628 Fix "warning: assignment discards qualifiers from pointer target type"
conrad
parents: 9951
diff changeset
50 const char* message = NULL;
4403
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
51 uint8_t* newdata = NULL;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
52 int newsize = avc_context->extradata_size + 2 + packet->bytes;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
53
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
54 if (packet->bytes < 0) {
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
55 message = "ogg_packet has negative size";
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
56 } else if (packet->bytes > 0xffff) {
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
57 message = "ogg_packet is larger than 65535 bytes";
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
58 } else if (newsize < avc_context->extradata_size) {
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
59 message = "extradata_size would overflow";
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
60 } else {
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
61 newdata = av_realloc(avc_context->extradata, newsize);
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
62 if (newdata == NULL) {
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
63 message = "av_realloc failed";
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
64 }
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
65 }
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
66 if (message != NULL) {
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
67 av_log(avc_context, AV_LOG_ERROR, "concatenate_packet failed: %s\n", message);
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
68 return -1;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
69 }
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
70
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
71 avc_context->extradata = newdata;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
72 avc_context->extradata_size = newsize;
5089
bff60ecc02f9 Use AV_xx throughout libavcodec
ramiro
parents: 4496
diff changeset
73 AV_WB16(avc_context->extradata + (*offset), packet->bytes);
bff60ecc02f9 Use AV_xx throughout libavcodec
ramiro
parents: 4496
diff changeset
74 *offset += 2;
4403
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
75 memcpy( avc_context->extradata + (*offset), packet->packet, packet->bytes );
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
76 (*offset) += packet->bytes;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
77 return 0;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
78 }
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
79
9007
043574c5c153 Add missing av_cold in static init/close functions.
stefano
parents: 8673
diff changeset
80 static av_cold int encode_init(AVCodecContext* avc_context)
4403
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
81 {
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
82 theora_info t_info;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
83 theora_comment t_comment;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
84 ogg_packet o_packet;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
85 unsigned int offset;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
86 TheoraContext *h = avc_context->priv_data;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
87
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
88 /* Set up the theora_info struct */
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
89 theora_info_init( &t_info );
9687
d9f8496b3b91 Fix libtheora encoding for non-mod16 sizes
conrad
parents: 9007
diff changeset
90 t_info.width = FFALIGN(avc_context->width, 16);
d9f8496b3b91 Fix libtheora encoding for non-mod16 sizes
conrad
parents: 9007
diff changeset
91 t_info.height = FFALIGN(avc_context->height, 16);
4403
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
92 t_info.frame_width = avc_context->width;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
93 t_info.frame_height = avc_context->height;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
94 t_info.offset_x = 0;
9687
d9f8496b3b91 Fix libtheora encoding for non-mod16 sizes
conrad
parents: 9007
diff changeset
95 t_info.offset_y = avc_context->height & 0xf;
4496
a02a0d06e99b Add a comment about swapped numerator and denominator.
diego
parents: 4403
diff changeset
96 /* Swap numerator and denominator as time_base in AVCodecContext gives the
a02a0d06e99b Add a comment about swapped numerator and denominator.
diego
parents: 4403
diff changeset
97 * time period between frames, but theora_info needs the framerate. */
4403
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
98 t_info.fps_numerator = avc_context->time_base.den;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
99 t_info.fps_denominator = avc_context->time_base.num;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
100 if (avc_context->sample_aspect_ratio.num != 0) {
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
101 t_info.aspect_numerator = avc_context->sample_aspect_ratio.num;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
102 t_info.aspect_denominator = avc_context->sample_aspect_ratio.den;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
103 } else {
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
104 t_info.aspect_numerator = 1;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
105 t_info.aspect_denominator = 1;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
106 }
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
107 t_info.colorspace = OC_CS_UNSPECIFIED;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
108 t_info.pixelformat = OC_PF_420;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
109 t_info.keyframe_frequency = avc_context->gop_size;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
110 t_info.keyframe_frequency_force = avc_context->gop_size;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
111 t_info.keyframe_mindistance = avc_context->keyint_min;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
112
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
113 t_info.quick_p = 1;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
114 t_info.dropframes_p = 0;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
115 t_info.keyframe_auto_p = 1;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
116 t_info.keyframe_data_target_bitrate = t_info.target_bitrate * 1.5;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
117 t_info.keyframe_auto_threshold = 80;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
118 t_info.noise_sensitivity = 1;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
119 t_info.sharpness = 0;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
120
10332
dfb91c11fe9c Support constant-quant encoding for libtheora
conrad
parents: 9952
diff changeset
121 if (avc_context->flags & CODEC_FLAG_QSCALE) {
dfb91c11fe9c Support constant-quant encoding for libtheora
conrad
parents: 9952
diff changeset
122 /* to be constant with the libvorbis implementation, clip global_quality to 0 - 10
dfb91c11fe9c Support constant-quant encoding for libtheora
conrad
parents: 9952
diff changeset
123 Theora accepts a quality parameter p, which is:
dfb91c11fe9c Support constant-quant encoding for libtheora
conrad
parents: 9952
diff changeset
124 * 0 <= p <=63
dfb91c11fe9c Support constant-quant encoding for libtheora
conrad
parents: 9952
diff changeset
125 * an int value
dfb91c11fe9c Support constant-quant encoding for libtheora
conrad
parents: 9952
diff changeset
126 */
dfb91c11fe9c Support constant-quant encoding for libtheora
conrad
parents: 9952
diff changeset
127 t_info.quality = av_clip(avc_context->global_quality / (float)FF_QP2LAMBDA, 0, 10) * 6.3;
dfb91c11fe9c Support constant-quant encoding for libtheora
conrad
parents: 9952
diff changeset
128 t_info.target_bitrate = 0;
dfb91c11fe9c Support constant-quant encoding for libtheora
conrad
parents: 9952
diff changeset
129 } else {
dfb91c11fe9c Support constant-quant encoding for libtheora
conrad
parents: 9952
diff changeset
130 t_info.target_bitrate = avc_context->bit_rate;
dfb91c11fe9c Support constant-quant encoding for libtheora
conrad
parents: 9952
diff changeset
131 t_info.quality = 0;
dfb91c11fe9c Support constant-quant encoding for libtheora
conrad
parents: 9952
diff changeset
132 }
dfb91c11fe9c Support constant-quant encoding for libtheora
conrad
parents: 9952
diff changeset
133
4403
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
134 /* Now initialise libtheora */
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
135 if (theora_encode_init( &(h->t_state), &t_info ) != 0) {
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
136 av_log(avc_context, AV_LOG_ERROR, "theora_encode_init failed\n");
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
137 return -1;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
138 }
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
139
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
140 /* Clear up theora_info struct */
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
141 theora_info_clear( &t_info );
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
142
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
143 /*
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
144 Output first header packet consisting of theora
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
145 header, comment, and tables.
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
146
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
147 Each one is prefixed with a 16bit size, then they
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
148 are concatenated together into ffmpeg's extradata.
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
149 */
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
150 offset = 0;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
151
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
152 /* Header */
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
153 theora_encode_header( &(h->t_state), &o_packet );
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
154 if (concatenate_packet( &offset, avc_context, &o_packet ) != 0) {
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
155 return -1;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
156 }
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
157
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
158 /* Comment */
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
159 theora_comment_init( &t_comment );
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
160 theora_encode_comment( &t_comment, &o_packet );
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
161 if (concatenate_packet( &offset, avc_context, &o_packet ) != 0) {
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
162 return -1;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
163 }
9951
702e111de423 Fix memory leak in libtheora encoder
conrad
parents: 9687
diff changeset
164 /* Clear up theora_comment struct before we reset the packet */
702e111de423 Fix memory leak in libtheora encoder
conrad
parents: 9687
diff changeset
165 theora_comment_clear( &t_comment );
702e111de423 Fix memory leak in libtheora encoder
conrad
parents: 9687
diff changeset
166 /* And despite documentation to the contrary, theora_comment_clear
702e111de423 Fix memory leak in libtheora encoder
conrad
parents: 9687
diff changeset
167 * does not release the packet */
702e111de423 Fix memory leak in libtheora encoder
conrad
parents: 9687
diff changeset
168 ogg_packet_clear(&o_packet);
4403
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
169
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
170 /* Tables */
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
171 theora_encode_tables( &(h->t_state), &o_packet );
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
172 if (concatenate_packet( &offset, avc_context, &o_packet ) != 0) {
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
173 return -1;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
174 }
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
175
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
176 /* Set up the output AVFrame */
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
177 avc_context->coded_frame= avcodec_alloc_frame();
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
178
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
179 return 0;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
180 }
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
181
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
182 static int encode_frame(
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
183 AVCodecContext* avc_context,
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
184 uint8_t *outbuf,
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
185 int buf_size,
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
186 void *data)
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
187 {
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
188 yuv_buffer t_yuv_buffer;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
189 TheoraContext *h = avc_context->priv_data;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
190 AVFrame *frame = data;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
191 ogg_packet o_packet;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
192 int result;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
193
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
194 assert(avc_context->pix_fmt == PIX_FMT_YUV420P);
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
195
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
196 /* Copy planes to the theora yuv_buffer */
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
197 if (frame->linesize[1] != frame->linesize[2]) {
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
198 av_log(avc_context, AV_LOG_ERROR, "U and V stride differ\n");
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
199 return -1;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
200 }
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
201
9687
d9f8496b3b91 Fix libtheora encoding for non-mod16 sizes
conrad
parents: 9007
diff changeset
202 t_yuv_buffer.y_width = FFALIGN(avc_context->width, 16);
d9f8496b3b91 Fix libtheora encoding for non-mod16 sizes
conrad
parents: 9007
diff changeset
203 t_yuv_buffer.y_height = FFALIGN(avc_context->height, 16);
4403
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
204 t_yuv_buffer.y_stride = frame->linesize[0];
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
205 t_yuv_buffer.uv_width = t_yuv_buffer.y_width / 2;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
206 t_yuv_buffer.uv_height = t_yuv_buffer.y_height / 2;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
207 t_yuv_buffer.uv_stride = frame->linesize[1];
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
208
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
209 t_yuv_buffer.y = frame->data[0];
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
210 t_yuv_buffer.u = frame->data[1];
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
211 t_yuv_buffer.v = frame->data[2];
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
212
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
213 /* Now call into theora_encode_YUVin */
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
214 result = theora_encode_YUVin( &(h->t_state), &t_yuv_buffer );
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
215 if (result != 0) {
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
216 const char* message;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
217 switch (result) {
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
218 case -1:
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
219 message = "differing frame sizes";
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
220 break;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
221 case OC_EINVAL:
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
222 message = "encoder is not ready or is finished";
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
223 break;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
224 default:
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
225 message = "unknown reason";
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
226 break;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
227 }
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
228 av_log(avc_context, AV_LOG_ERROR, "theora_encode_YUVin failed (%s) [%d]\n", message, result);
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
229 return -1;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
230 }
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
231
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
232 /* Pick up returned ogg_packet */
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
233 result = theora_encode_packetout( &(h->t_state), 0, &o_packet );
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
234 switch (result) {
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
235 case 0:
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
236 /* No packet is ready */
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
237 return 0;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
238 case 1:
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
239 /* Success, we have a packet */
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
240 break;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
241 default:
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
242 av_log(avc_context, AV_LOG_ERROR, "theora_encode_packetout failed [%d]\n", result);
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
243 return -1;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
244 }
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
245
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
246 /* Copy ogg_packet content out to buffer */
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
247 if (buf_size < o_packet.bytes) {
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
248 av_log(avc_context, AV_LOG_ERROR, "encoded frame too large\n");
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
249 return -1;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
250 }
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
251 memcpy(outbuf, o_packet.packet, o_packet.bytes);
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
252
10381
9262948fd649 Hack: set the coded frame PTS to the incoming PTS.
reimar
parents: 10332
diff changeset
253 // HACK: does not take codec delay into account (neither does the decoder though)
9262948fd649 Hack: set the coded frame PTS to the incoming PTS.
reimar
parents: 10332
diff changeset
254 avc_context->coded_frame->pts= frame->pts;
9262948fd649 Hack: set the coded frame PTS to the incoming PTS.
reimar
parents: 10332
diff changeset
255
4403
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
256 return o_packet.bytes;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
257 }
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
258
9007
043574c5c153 Add missing av_cold in static init/close functions.
stefano
parents: 8673
diff changeset
259 static av_cold int encode_close(AVCodecContext* avc_context)
4403
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
260 {
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
261 ogg_packet o_packet;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
262 TheoraContext *h = avc_context->priv_data;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
263 int result;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
264 const char* message;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
265
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
266 result = theora_encode_packetout( &(h->t_state), 1, &o_packet );
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
267 theora_clear( &(h->t_state) );
9951
702e111de423 Fix memory leak in libtheora encoder
conrad
parents: 9687
diff changeset
268 av_freep(&avc_context->coded_frame);
702e111de423 Fix memory leak in libtheora encoder
conrad
parents: 9687
diff changeset
269 av_freep(&avc_context->extradata);
702e111de423 Fix memory leak in libtheora encoder
conrad
parents: 9687
diff changeset
270 avc_context->extradata_size = 0;
702e111de423 Fix memory leak in libtheora encoder
conrad
parents: 9687
diff changeset
271
4403
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
272 switch (result) {
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
273 case 0:/* No packet is ready */
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
274 case -1:/* Encoding finished */
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
275 return 0;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
276 case 1:
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
277 /* We have a packet */
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
278 message = "gave us a packet";
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
279 break;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
280 default:
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
281 message = "unknown reason";
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
282 break;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
283 }
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
284 av_log(avc_context, AV_LOG_ERROR, "theora_encode_packetout failed (%s) [%d]\n", message, result);
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
285 return -1;
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
286 }
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
287
6788
e1302edb0f69 Replace some occurrences of -1 with PIX_FMT_NONE.
cehoyos
parents: 6763
diff changeset
288 static const enum PixelFormat supported_pixel_formats[] = { PIX_FMT_YUV420P, PIX_FMT_NONE };
4403
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
289
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
290 /*! AVCodec struct exposed to libavcodec */
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
291 AVCodec libtheora_encoder =
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
292 {
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
293 .name = "libtheora",
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
294 .type = CODEC_TYPE_VIDEO,
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
295 .id = CODEC_ID_THEORA,
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
296 .priv_data_size = sizeof(TheoraContext),
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
297 .init = encode_init,
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
298 .close = encode_close,
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
299 .encode = encode_frame,
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
300 .pix_fmts = supported_pixel_formats,
7040
e943e1409077 Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents: 6788
diff changeset
301 .long_name = NULL_IF_CONFIG_SMALL("libtheora Theora"),
4403
432d332b7def Theora encoding via libtheora.
diego
parents:
diff changeset
302 };