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