00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00033
00034 #include "libavutil/common.h"
00035 #include "libavutil/intreadwrite.h"
00036 #include "libavutil/log.h"
00037 #include "libavutil/base64.h"
00038 #include "avcodec.h"
00039 #include "internal.h"
00040
00041
00042 #include <theora/theoraenc.h>
00043
00044 typedef struct TheoraContext {
00045 th_enc_ctx *t_state;
00046 uint8_t *stats;
00047 int stats_size;
00048 int stats_offset;
00049 int uv_hshift;
00050 int uv_vshift;
00051 int keyframe_mask;
00052 } TheoraContext;
00053
00055 static int concatenate_packet(unsigned int* offset,
00056 AVCodecContext* avc_context,
00057 const ogg_packet* packet)
00058 {
00059 const char* message = NULL;
00060 uint8_t* newdata = NULL;
00061 int newsize = avc_context->extradata_size + 2 + packet->bytes;
00062
00063 if (packet->bytes < 0) {
00064 message = "ogg_packet has negative size";
00065 } else if (packet->bytes > 0xffff) {
00066 message = "ogg_packet is larger than 65535 bytes";
00067 } else if (newsize < avc_context->extradata_size) {
00068 message = "extradata_size would overflow";
00069 } else {
00070 newdata = av_realloc(avc_context->extradata, newsize);
00071 if (!newdata)
00072 message = "av_realloc failed";
00073 }
00074 if (message) {
00075 av_log(avc_context, AV_LOG_ERROR, "concatenate_packet failed: %s\n", message);
00076 return -1;
00077 }
00078
00079 avc_context->extradata = newdata;
00080 avc_context->extradata_size = newsize;
00081 AV_WB16(avc_context->extradata + (*offset), packet->bytes);
00082 *offset += 2;
00083 memcpy(avc_context->extradata + (*offset), packet->packet, packet->bytes);
00084 (*offset) += packet->bytes;
00085 return 0;
00086 }
00087
00088 static int get_stats(AVCodecContext *avctx, int eos)
00089 {
00090 #ifdef TH_ENCCTL_2PASS_OUT
00091 TheoraContext *h = avctx->priv_data;
00092 uint8_t *buf;
00093 int bytes;
00094
00095 bytes = th_encode_ctl(h->t_state, TH_ENCCTL_2PASS_OUT, &buf, sizeof(buf));
00096 if (bytes < 0) {
00097 av_log(avctx, AV_LOG_ERROR, "Error getting first pass stats\n");
00098 return -1;
00099 }
00100 if (!eos) {
00101 h->stats = av_fast_realloc(h->stats, &h->stats_size,
00102 h->stats_offset + bytes);
00103 memcpy(h->stats + h->stats_offset, buf, bytes);
00104 h->stats_offset += bytes;
00105 } else {
00106 int b64_size = AV_BASE64_SIZE(h->stats_offset);
00107
00108 memcpy(h->stats, buf, bytes);
00109 avctx->stats_out = av_malloc(b64_size);
00110 av_base64_encode(avctx->stats_out, b64_size, h->stats, h->stats_offset);
00111 }
00112 return 0;
00113 #else
00114 av_log(avctx, AV_LOG_ERROR, "libtheora too old to support 2pass\n");
00115 return -1;
00116 #endif
00117 }
00118
00119
00120
00121 static int submit_stats(AVCodecContext *avctx)
00122 {
00123 #ifdef TH_ENCCTL_2PASS_IN
00124 TheoraContext *h = avctx->priv_data;
00125 int bytes;
00126 if (!h->stats) {
00127 if (!avctx->stats_in) {
00128 av_log(avctx, AV_LOG_ERROR, "No statsfile for second pass\n");
00129 return -1;
00130 }
00131 h->stats_size = strlen(avctx->stats_in) * 3/4;
00132 h->stats = av_malloc(h->stats_size);
00133 h->stats_size = av_base64_decode(h->stats, avctx->stats_in, h->stats_size);
00134 }
00135 while (h->stats_size - h->stats_offset > 0) {
00136 bytes = th_encode_ctl(h->t_state, TH_ENCCTL_2PASS_IN,
00137 h->stats + h->stats_offset,
00138 h->stats_size - h->stats_offset);
00139 if (bytes < 0) {
00140 av_log(avctx, AV_LOG_ERROR, "Error submitting stats\n");
00141 return -1;
00142 }
00143 if (!bytes)
00144 return 0;
00145 h->stats_offset += bytes;
00146 }
00147 return 0;
00148 #else
00149 av_log(avctx, AV_LOG_ERROR, "libtheora too old to support 2pass\n");
00150 return -1;
00151 #endif
00152 }
00153
00154 static av_cold int encode_init(AVCodecContext* avc_context)
00155 {
00156 th_info t_info;
00157 th_comment t_comment;
00158 ogg_packet o_packet;
00159 unsigned int offset;
00160 TheoraContext *h = avc_context->priv_data;
00161 uint32_t gop_size = avc_context->gop_size;
00162
00163
00164 th_info_init(&t_info);
00165 t_info.frame_width = FFALIGN(avc_context->width, 16);
00166 t_info.frame_height = FFALIGN(avc_context->height, 16);
00167 t_info.pic_width = avc_context->width;
00168 t_info.pic_height = avc_context->height;
00169 t_info.pic_x = 0;
00170 t_info.pic_y = 0;
00171
00172
00173 t_info.fps_numerator = avc_context->time_base.den;
00174 t_info.fps_denominator = avc_context->time_base.num;
00175 if (avc_context->sample_aspect_ratio.num) {
00176 t_info.aspect_numerator = avc_context->sample_aspect_ratio.num;
00177 t_info.aspect_denominator = avc_context->sample_aspect_ratio.den;
00178 } else {
00179 t_info.aspect_numerator = 1;
00180 t_info.aspect_denominator = 1;
00181 }
00182
00183 if (avc_context->color_primaries == AVCOL_PRI_BT470M)
00184 t_info.colorspace = TH_CS_ITU_REC_470M;
00185 else if (avc_context->color_primaries == AVCOL_PRI_BT470BG)
00186 t_info.colorspace = TH_CS_ITU_REC_470BG;
00187 else
00188 t_info.colorspace = TH_CS_UNSPECIFIED;
00189
00190 if (avc_context->pix_fmt == PIX_FMT_YUV420P)
00191 t_info.pixel_fmt = TH_PF_420;
00192 else if (avc_context->pix_fmt == PIX_FMT_YUV422P)
00193 t_info.pixel_fmt = TH_PF_422;
00194 else if (avc_context->pix_fmt == PIX_FMT_YUV444P)
00195 t_info.pixel_fmt = TH_PF_444;
00196 else {
00197 av_log(avc_context, AV_LOG_ERROR, "Unsupported pix_fmt\n");
00198 return -1;
00199 }
00200 avcodec_get_chroma_sub_sample(avc_context->pix_fmt, &h->uv_hshift, &h->uv_vshift);
00201
00202 if (avc_context->flags & CODEC_FLAG_QSCALE) {
00203
00204
00205
00206
00207
00208 t_info.quality = av_clip(avc_context->global_quality / (float)FF_QP2LAMBDA, 0, 10) * 6.3;
00209 t_info.target_bitrate = 0;
00210 } else {
00211 t_info.target_bitrate = avc_context->bit_rate;
00212 t_info.quality = 0;
00213 }
00214
00215
00216 h->t_state = th_encode_alloc(&t_info);
00217 if (!h->t_state) {
00218 av_log(avc_context, AV_LOG_ERROR, "theora_encode_init failed\n");
00219 return -1;
00220 }
00221
00222 h->keyframe_mask = (1 << t_info.keyframe_granule_shift) - 1;
00223
00224 th_info_clear(&t_info);
00225
00226 if (th_encode_ctl(h->t_state, TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE,
00227 &gop_size, sizeof(gop_size))) {
00228 av_log(avc_context, AV_LOG_ERROR, "Error setting GOP size\n");
00229 return -1;
00230 }
00231
00232
00233 if (avc_context->flags & CODEC_FLAG_PASS1) {
00234 if (get_stats(avc_context, 0))
00235 return -1;
00236 } else if (avc_context->flags & CODEC_FLAG_PASS2) {
00237 if (submit_stats(avc_context))
00238 return -1;
00239 }
00240
00241
00242
00243
00244
00245
00246
00247
00248 offset = 0;
00249
00250
00251 th_comment_init(&t_comment);
00252
00253 while (th_encode_flushheader(h->t_state, &t_comment, &o_packet))
00254 if (concatenate_packet(&offset, avc_context, &o_packet))
00255 return -1;
00256
00257 th_comment_clear(&t_comment);
00258
00259
00260 avc_context->coded_frame= avcodec_alloc_frame();
00261
00262 return 0;
00263 }
00264
00265 static int encode_frame(AVCodecContext* avc_context, AVPacket *pkt,
00266 const AVFrame *frame, int *got_packet)
00267 {
00268 th_ycbcr_buffer t_yuv_buffer;
00269 TheoraContext *h = avc_context->priv_data;
00270 ogg_packet o_packet;
00271 int result, i, ret;
00272
00273
00274 if (!frame) {
00275 th_encode_packetout(h->t_state, 1, &o_packet);
00276 if (avc_context->flags & CODEC_FLAG_PASS1)
00277 if (get_stats(avc_context, 1))
00278 return -1;
00279 return 0;
00280 }
00281
00282
00283 for (i = 0; i < 3; i++) {
00284 t_yuv_buffer[i].width = FFALIGN(avc_context->width, 16) >> (i && h->uv_hshift);
00285 t_yuv_buffer[i].height = FFALIGN(avc_context->height, 16) >> (i && h->uv_vshift);
00286 t_yuv_buffer[i].stride = frame->linesize[i];
00287 t_yuv_buffer[i].data = frame->data[i];
00288 }
00289
00290 if (avc_context->flags & CODEC_FLAG_PASS2)
00291 if (submit_stats(avc_context))
00292 return -1;
00293
00294
00295 result = th_encode_ycbcr_in(h->t_state, t_yuv_buffer);
00296 if (result) {
00297 const char* message;
00298 switch (result) {
00299 case -1:
00300 message = "differing frame sizes";
00301 break;
00302 case TH_EINVAL:
00303 message = "encoder is not ready or is finished";
00304 break;
00305 default:
00306 message = "unknown reason";
00307 break;
00308 }
00309 av_log(avc_context, AV_LOG_ERROR, "theora_encode_YUVin failed (%s) [%d]\n", message, result);
00310 return -1;
00311 }
00312
00313 if (avc_context->flags & CODEC_FLAG_PASS1)
00314 if (get_stats(avc_context, 0))
00315 return -1;
00316
00317
00318 result = th_encode_packetout(h->t_state, 0, &o_packet);
00319 switch (result) {
00320 case 0:
00321
00322 return 0;
00323 case 1:
00324
00325 break;
00326 default:
00327 av_log(avc_context, AV_LOG_ERROR, "theora_encode_packetout failed [%d]\n", result);
00328 return -1;
00329 }
00330
00331
00332 if ((ret = ff_alloc_packet2(avc_context, pkt, o_packet.bytes)) < 0)
00333 return ret;
00334 memcpy(pkt->data, o_packet.packet, o_packet.bytes);
00335
00336
00337
00338 pkt->pts = pkt->dts = frame->pts;
00339 avc_context->coded_frame->key_frame = !(o_packet.granulepos & h->keyframe_mask);
00340 if (avc_context->coded_frame->key_frame)
00341 pkt->flags |= AV_PKT_FLAG_KEY;
00342 *got_packet = 1;
00343
00344 return 0;
00345 }
00346
00347 static av_cold int encode_close(AVCodecContext* avc_context)
00348 {
00349 TheoraContext *h = avc_context->priv_data;
00350
00351 th_encode_free(h->t_state);
00352 av_freep(&h->stats);
00353 av_freep(&avc_context->coded_frame);
00354 av_freep(&avc_context->stats_out);
00355 av_freep(&avc_context->extradata);
00356 avc_context->extradata_size = 0;
00357
00358 return 0;
00359 }
00360
00362 AVCodec ff_libtheora_encoder = {
00363 .name = "libtheora",
00364 .type = AVMEDIA_TYPE_VIDEO,
00365 .id = AV_CODEC_ID_THEORA,
00366 .priv_data_size = sizeof(TheoraContext),
00367 .init = encode_init,
00368 .close = encode_close,
00369 .encode2 = encode_frame,
00370 .capabilities = CODEC_CAP_DELAY,
00371 .pix_fmts = (const enum PixelFormat[]){
00372 PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_YUV444P, PIX_FMT_NONE
00373 },
00374 .long_name = NULL_IF_CONFIG_SMALL("libtheora Theora"),
00375 };