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