00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00030 #undef NDEBUG
00031 #include <assert.h>
00032
00033 #include <schroedinger/schro.h>
00034 #include <schroedinger/schrodebug.h>
00035 #include <schroedinger/schrovideoformat.h>
00036
00037 #include "avcodec.h"
00038 #include "libdirac_libschro.h"
00039 #include "libschroedinger.h"
00040
00041
00043 typedef struct FfmpegSchroEncoderParams {
00045 SchroVideoFormat *format;
00046
00048 SchroFrameFormat frame_format;
00049
00051 AVFrame picture;
00052
00054 int frame_size;
00055
00057 SchroEncoder* encoder;
00058
00060 unsigned char *enc_buf;
00061
00063 int enc_buf_size;
00064
00066 FfmpegDiracSchroQueue enc_frame_queue;
00067
00069 int eos_signalled;
00070
00072 int eos_pulled;
00073 } FfmpegSchroEncoderParams;
00074
00078 static int SetSchroChromaFormat(AVCodecContext *avccontext)
00079 {
00080 int num_formats = sizeof(ffmpeg_schro_pixel_format_map) /
00081 sizeof(ffmpeg_schro_pixel_format_map[0]);
00082 int idx;
00083
00084 FfmpegSchroEncoderParams* p_schro_params = avccontext->priv_data;
00085
00086 for (idx = 0; idx < num_formats; ++idx) {
00087 if (ffmpeg_schro_pixel_format_map[idx].ff_pix_fmt ==
00088 avccontext->pix_fmt) {
00089 p_schro_params->format->chroma_format =
00090 ffmpeg_schro_pixel_format_map[idx].schro_pix_fmt;
00091 return 0;
00092 }
00093 }
00094
00095 av_log(avccontext, AV_LOG_ERROR,
00096 "This codec currently only supports planar YUV 4:2:0, 4:2:2"
00097 " and 4:4:4 formats.\n");
00098
00099 return -1;
00100 }
00101
00102 static int libschroedinger_encode_init(AVCodecContext *avccontext)
00103 {
00104 FfmpegSchroEncoderParams* p_schro_params = avccontext->priv_data;
00105 SchroVideoFormatEnum preset;
00106
00107
00108 schro_init();
00109
00110
00111 p_schro_params->encoder = schro_encoder_new();
00112
00113 if (!p_schro_params->encoder) {
00114 av_log(avccontext, AV_LOG_ERROR,
00115 "Unrecoverable Error: schro_encoder_new failed. ");
00116 return -1;
00117 }
00118
00119
00120 preset = ff_get_schro_video_format_preset(avccontext);
00121 p_schro_params->format =
00122 schro_encoder_get_video_format(p_schro_params->encoder);
00123 schro_video_format_set_std_video_format(p_schro_params->format, preset);
00124 p_schro_params->format->width = avccontext->width;
00125 p_schro_params->format->height = avccontext->height;
00126
00127 if (SetSchroChromaFormat(avccontext) == -1)
00128 return -1;
00129
00130 if (ff_get_schro_frame_format(p_schro_params->format->chroma_format,
00131 &p_schro_params->frame_format) == -1) {
00132 av_log(avccontext, AV_LOG_ERROR,
00133 "This codec currently supports only planar YUV 4:2:0, 4:2:2"
00134 " and 4:4:4 formats.\n");
00135 return -1;
00136 }
00137
00138 p_schro_params->format->frame_rate_numerator = avccontext->time_base.den;
00139 p_schro_params->format->frame_rate_denominator = avccontext->time_base.num;
00140
00141 p_schro_params->frame_size = avpicture_get_size(avccontext->pix_fmt,
00142 avccontext->width,
00143 avccontext->height);
00144
00145 avccontext->coded_frame = &p_schro_params->picture;
00146
00147 if (!avccontext->gop_size) {
00148 schro_encoder_setting_set_double(p_schro_params->encoder,
00149 "gop_structure",
00150 SCHRO_ENCODER_GOP_INTRA_ONLY);
00151
00152 if (avccontext->coder_type == FF_CODER_TYPE_VLC)
00153 schro_encoder_setting_set_double(p_schro_params->encoder,
00154 "enable_noarith", 1);
00155 } else {
00156 schro_encoder_setting_set_double(p_schro_params->encoder,
00157 "gop_structure",
00158 SCHRO_ENCODER_GOP_BIREF);
00159 avccontext->has_b_frames = 1;
00160 }
00161
00162
00163 if (avccontext->flags & CODEC_FLAG_QSCALE) {
00164 if (!avccontext->global_quality) {
00165
00166 schro_encoder_setting_set_double(p_schro_params->encoder,
00167 "rate_control",
00168 SCHRO_ENCODER_RATE_CONTROL_LOSSLESS);
00169 } else {
00170 int noise_threshold;
00171 schro_encoder_setting_set_double(p_schro_params->encoder,
00172 "rate_control",
00173 SCHRO_ENCODER_RATE_CONTROL_CONSTANT_NOISE_THRESHOLD);
00174
00175 noise_threshold = avccontext->global_quality / FF_QP2LAMBDA;
00176 if (noise_threshold > 100)
00177 noise_threshold = 100;
00178 schro_encoder_setting_set_double(p_schro_params->encoder,
00179 "noise_threshold",
00180 noise_threshold);
00181 }
00182 } else {
00183 schro_encoder_setting_set_double(p_schro_params->encoder,
00184 "rate_control",
00185 SCHRO_ENCODER_RATE_CONTROL_CONSTANT_BITRATE);
00186
00187 schro_encoder_setting_set_double(p_schro_params->encoder,
00188 "bitrate",
00189 avccontext->bit_rate);
00190
00191 }
00192
00193 if (avccontext->flags & CODEC_FLAG_INTERLACED_ME)
00194
00195
00196 schro_encoder_setting_set_double(p_schro_params->encoder,
00197 "interlaced_coding", 1);
00198
00199
00200
00201 schro_video_format_set_std_signal_range(p_schro_params->format,
00202 SCHRO_SIGNAL_RANGE_8BIT_VIDEO);
00203
00204
00205 schro_encoder_set_video_format(p_schro_params->encoder,
00206 p_schro_params->format);
00207
00208
00209 schro_debug_set_level(avccontext->debug);
00210
00211 schro_encoder_start(p_schro_params->encoder);
00212
00213
00214 ff_dirac_schro_queue_init(&p_schro_params->enc_frame_queue);
00215 return 0;
00216 }
00217
00218 static SchroFrame *libschroedinger_frame_from_data(AVCodecContext *avccontext,
00219 void *in_data)
00220 {
00221 FfmpegSchroEncoderParams* p_schro_params = avccontext->priv_data;
00222 SchroFrame *in_frame;
00223
00224
00225
00226 in_frame = ff_create_schro_frame(avccontext, p_schro_params->frame_format);
00227
00228 if (in_frame)
00229 avpicture_layout((AVPicture *)in_data, avccontext->pix_fmt,
00230 avccontext->width, avccontext->height,
00231 in_frame->components[0].data,
00232 p_schro_params->frame_size);
00233
00234 return in_frame;
00235 }
00236
00237 static void SchroedingerFreeFrame(void *data)
00238 {
00239 FfmpegDiracSchroEncodedFrame *enc_frame = data;
00240
00241 av_freep(&(enc_frame->p_encbuf));
00242 av_free(enc_frame);
00243 }
00244
00245 static int libschroedinger_encode_frame(AVCodecContext *avccontext,
00246 unsigned char *frame,
00247 int buf_size, void *data)
00248 {
00249 int enc_size = 0;
00250 FfmpegSchroEncoderParams* p_schro_params = avccontext->priv_data;
00251 SchroEncoder *encoder = p_schro_params->encoder;
00252 struct FfmpegDiracSchroEncodedFrame* p_frame_output = NULL;
00253 int go = 1;
00254 SchroBuffer *enc_buf;
00255 int presentation_frame;
00256 int parse_code;
00257 int last_frame_in_sequence = 0;
00258
00259 if (!data) {
00260
00261 if (!p_schro_params->eos_signalled) {
00262 schro_encoder_end_of_stream(encoder);
00263 p_schro_params->eos_signalled = 1;
00264 }
00265 } else {
00266
00267 SchroFrame *in_frame = libschroedinger_frame_from_data(avccontext,
00268 data);
00269
00270 schro_encoder_push_frame(encoder, in_frame);
00271 }
00272
00273 if (p_schro_params->eos_pulled)
00274 go = 0;
00275
00276
00277 while (go) {
00278 SchroStateEnum state;
00279 state = schro_encoder_wait(encoder);
00280 switch (state) {
00281 case SCHRO_STATE_HAVE_BUFFER:
00282 case SCHRO_STATE_END_OF_STREAM:
00283 enc_buf = schro_encoder_pull(encoder, &presentation_frame);
00284 assert(enc_buf->length > 0);
00285 assert(enc_buf->length <= buf_size);
00286 parse_code = enc_buf->data[4];
00287
00288
00289
00290
00291
00292 p_schro_params->enc_buf = av_realloc(p_schro_params->enc_buf,
00293 p_schro_params->enc_buf_size + enc_buf->length);
00294
00295 memcpy(p_schro_params->enc_buf + p_schro_params->enc_buf_size,
00296 enc_buf->data, enc_buf->length);
00297 p_schro_params->enc_buf_size += enc_buf->length;
00298
00299
00300 if (state == SCHRO_STATE_END_OF_STREAM) {
00301 p_schro_params->eos_pulled = 1;
00302 go = 0;
00303 }
00304
00305 if (!SCHRO_PARSE_CODE_IS_PICTURE(parse_code)) {
00306 schro_buffer_unref(enc_buf);
00307 break;
00308 }
00309
00310
00311 p_frame_output = av_mallocz(sizeof(FfmpegDiracSchroEncodedFrame));
00312
00313 p_frame_output->size = p_schro_params->enc_buf_size;
00314 p_frame_output->p_encbuf = p_schro_params->enc_buf;
00315 if (SCHRO_PARSE_CODE_IS_INTRA(parse_code) &&
00316 SCHRO_PARSE_CODE_IS_REFERENCE(parse_code))
00317 p_frame_output->key_frame = 1;
00318
00319
00320
00321 p_frame_output->frame_num = (enc_buf->data[13] << 24) +
00322 (enc_buf->data[14] << 16) +
00323 (enc_buf->data[15] << 8) +
00324 enc_buf->data[16];
00325
00326 ff_dirac_schro_queue_push_back(&p_schro_params->enc_frame_queue,
00327 p_frame_output);
00328 p_schro_params->enc_buf_size = 0;
00329 p_schro_params->enc_buf = NULL;
00330
00331 schro_buffer_unref(enc_buf);
00332
00333 break;
00334
00335 case SCHRO_STATE_NEED_FRAME:
00336 go = 0;
00337 break;
00338
00339 case SCHRO_STATE_AGAIN:
00340 break;
00341
00342 default:
00343 av_log(avccontext, AV_LOG_ERROR, "Unknown Schro Encoder state\n");
00344 return -1;
00345 }
00346 }
00347
00348
00349
00350 if (p_schro_params->enc_frame_queue.size == 1 &&
00351 p_schro_params->eos_pulled)
00352 last_frame_in_sequence = 1;
00353
00354 p_frame_output = ff_dirac_schro_queue_pop(&p_schro_params->enc_frame_queue);
00355
00356 if (!p_frame_output)
00357 return 0;
00358
00359 memcpy(frame, p_frame_output->p_encbuf, p_frame_output->size);
00360 avccontext->coded_frame->key_frame = p_frame_output->key_frame;
00361
00362
00363
00364 avccontext->coded_frame->pts = p_frame_output->frame_num;
00365 enc_size = p_frame_output->size;
00366
00367
00368
00369 if (last_frame_in_sequence && p_schro_params->enc_buf_size > 0) {
00370 memcpy(frame + enc_size, p_schro_params->enc_buf,
00371 p_schro_params->enc_buf_size);
00372 enc_size += p_schro_params->enc_buf_size;
00373 av_freep(&p_schro_params->enc_buf);
00374 p_schro_params->enc_buf_size = 0;
00375 }
00376
00377
00378 SchroedingerFreeFrame(p_frame_output);
00379
00380 return enc_size;
00381 }
00382
00383
00384 static int libschroedinger_encode_close(AVCodecContext *avccontext)
00385 {
00386
00387 FfmpegSchroEncoderParams* p_schro_params = avccontext->priv_data;
00388
00389
00390 schro_encoder_free(p_schro_params->encoder);
00391
00392
00393 ff_dirac_schro_queue_free(&p_schro_params->enc_frame_queue,
00394 SchroedingerFreeFrame);
00395
00396
00397
00398 if (p_schro_params->enc_buf_size)
00399 av_freep(&p_schro_params->enc_buf);
00400
00401
00402 av_freep(&p_schro_params->format);
00403
00404 return 0;
00405 }
00406
00407
00408 AVCodec libschroedinger_encoder = {
00409 "libschroedinger",
00410 AVMEDIA_TYPE_VIDEO,
00411 CODEC_ID_DIRAC,
00412 sizeof(FfmpegSchroEncoderParams),
00413 libschroedinger_encode_init,
00414 libschroedinger_encode_frame,
00415 libschroedinger_encode_close,
00416 .capabilities = CODEC_CAP_DELAY,
00417 .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_YUV444P, PIX_FMT_NONE},
00418 .long_name = NULL_IF_CONFIG_SMALL("libschroedinger Dirac 2.2"),
00419 };