00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00031 #include "libdirac_libschro.h"
00032 #include "libdirac.h"
00033
00034 #undef NDEBUG
00035 #include <assert.h>
00036
00037
00038 #include <libdirac_encoder/dirac_encoder.h>
00039
00041 typedef struct FfmpegDiracEncoderParams {
00043 dirac_encoder_context_t enc_ctx;
00044
00046 AVFrame picture;
00047
00049 int frame_size;
00050
00052 dirac_encoder_t* p_encoder;
00053
00055 unsigned char *p_in_frame_buf;
00056
00058 unsigned char *enc_buf;
00059
00061 int enc_buf_size;
00062
00064 FfmpegDiracSchroQueue enc_frame_queue;
00065
00067 int eos_signalled;
00068
00070 int eos_pulled;
00071 } FfmpegDiracEncoderParams;
00072
00076 static dirac_chroma_t GetDiracChromaFormat(enum PixelFormat ff_pix_fmt)
00077 {
00078 int num_formats = sizeof(ffmpeg_dirac_pixel_format_map) /
00079 sizeof(ffmpeg_dirac_pixel_format_map[0]);
00080 int idx;
00081
00082 for (idx = 0; idx < num_formats; ++idx)
00083 if (ffmpeg_dirac_pixel_format_map[idx].ff_pix_fmt == ff_pix_fmt)
00084 return ffmpeg_dirac_pixel_format_map[idx].dirac_pix_fmt;
00085 return formatNK;
00086 }
00087
00092 static const VideoFormat ff_dirac_video_formats[]={
00093 VIDEO_FORMAT_CUSTOM ,
00094 VIDEO_FORMAT_QSIF525 ,
00095 VIDEO_FORMAT_QCIF ,
00096 VIDEO_FORMAT_SIF525 ,
00097 VIDEO_FORMAT_CIF ,
00098 VIDEO_FORMAT_4SIF525 ,
00099 VIDEO_FORMAT_4CIF ,
00100 VIDEO_FORMAT_SD_480I60 ,
00101 VIDEO_FORMAT_SD_576I50 ,
00102 VIDEO_FORMAT_HD_720P60 ,
00103 VIDEO_FORMAT_HD_720P50 ,
00104 VIDEO_FORMAT_HD_1080I60 ,
00105 VIDEO_FORMAT_HD_1080I50 ,
00106 VIDEO_FORMAT_HD_1080P60 ,
00107 VIDEO_FORMAT_HD_1080P50 ,
00108 VIDEO_FORMAT_DIGI_CINEMA_2K24 ,
00109 VIDEO_FORMAT_DIGI_CINEMA_4K24 ,
00110 };
00111
00116 static VideoFormat GetDiracVideoFormatPreset(AVCodecContext *avccontext)
00117 {
00118 unsigned int num_formats = sizeof(ff_dirac_video_formats) /
00119 sizeof(ff_dirac_video_formats[0]);
00120
00121 unsigned int idx = ff_dirac_schro_get_video_format_idx(avccontext);
00122
00123 return (idx < num_formats) ?
00124 ff_dirac_video_formats[idx] : VIDEO_FORMAT_CUSTOM;
00125 }
00126
00127 static av_cold int libdirac_encode_init(AVCodecContext *avccontext)
00128 {
00129
00130 FfmpegDiracEncoderParams* p_dirac_params = avccontext->priv_data;
00131 int no_local = 1;
00132 int verbose = avccontext->debug;
00133 VideoFormat preset;
00134
00135
00136 preset = GetDiracVideoFormatPreset(avccontext);
00137
00138
00139 dirac_encoder_context_init(&(p_dirac_params->enc_ctx), preset);
00140
00141 p_dirac_params->enc_ctx.src_params.chroma = GetDiracChromaFormat(avccontext->pix_fmt);
00142
00143 if (p_dirac_params->enc_ctx.src_params.chroma == formatNK) {
00144 av_log(avccontext, AV_LOG_ERROR,
00145 "Unsupported pixel format %d. This codec supports only "
00146 "Planar YUV formats (yuv420p, yuv422p, yuv444p\n",
00147 avccontext->pix_fmt);
00148 return -1;
00149 }
00150
00151 p_dirac_params->enc_ctx.src_params.frame_rate.numerator = avccontext->time_base.den;
00152 p_dirac_params->enc_ctx.src_params.frame_rate.denominator = avccontext->time_base.num;
00153
00154 p_dirac_params->enc_ctx.src_params.width = avccontext->width;
00155 p_dirac_params->enc_ctx.src_params.height = avccontext->height;
00156
00157 p_dirac_params->frame_size = avpicture_get_size(avccontext->pix_fmt,
00158 avccontext->width,
00159 avccontext->height);
00160
00161 avccontext->coded_frame = &p_dirac_params->picture;
00162
00163 if (no_local) {
00164 p_dirac_params->enc_ctx.decode_flag = 0;
00165 p_dirac_params->enc_ctx.instr_flag = 0;
00166 } else {
00167 p_dirac_params->enc_ctx.decode_flag = 1;
00168 p_dirac_params->enc_ctx.instr_flag = 1;
00169 }
00170
00171
00172 if (!avccontext->gop_size) {
00173 p_dirac_params->enc_ctx.enc_params.num_L1 = 0;
00174 if (avccontext->coder_type == FF_CODER_TYPE_VLC)
00175 p_dirac_params->enc_ctx.enc_params.using_ac = 0;
00176 } else
00177 avccontext->has_b_frames = 1;
00178
00179 if (avccontext->flags & CODEC_FLAG_QSCALE) {
00180 if (avccontext->global_quality) {
00181 p_dirac_params->enc_ctx.enc_params.qf = avccontext->global_quality
00182 / (FF_QP2LAMBDA * 10.0);
00183
00184 if (avccontext->bit_rate >= 1000 &&
00185 avccontext->bit_rate != 200000)
00186 p_dirac_params->enc_ctx.enc_params.trate = avccontext->bit_rate
00187 / 1000;
00188 } else
00189 p_dirac_params->enc_ctx.enc_params.lossless = 1;
00190 } else if (avccontext->bit_rate >= 1000)
00191 p_dirac_params->enc_ctx.enc_params.trate = avccontext->bit_rate / 1000;
00192
00193 if ((preset > VIDEO_FORMAT_QCIF || preset < VIDEO_FORMAT_QSIF525) &&
00194 avccontext->bit_rate == 200000)
00195 p_dirac_params->enc_ctx.enc_params.trate = 0;
00196
00197 if (avccontext->flags & CODEC_FLAG_INTERLACED_ME)
00198
00199
00200 p_dirac_params->enc_ctx.enc_params.picture_coding_mode = 1;
00201
00202 p_dirac_params->p_encoder = dirac_encoder_init(&(p_dirac_params->enc_ctx),
00203 verbose);
00204
00205 if (!p_dirac_params->p_encoder) {
00206 av_log(avccontext, AV_LOG_ERROR,
00207 "Unrecoverable Error: dirac_encoder_init failed. ");
00208 return EXIT_FAILURE;
00209 }
00210
00211
00212 p_dirac_params->p_in_frame_buf = av_malloc(p_dirac_params->frame_size);
00213
00214
00215 ff_dirac_schro_queue_init(&p_dirac_params->enc_frame_queue);
00216
00217 return 0;
00218 }
00219
00220 static void DiracFreeFrame(void *data)
00221 {
00222 FfmpegDiracSchroEncodedFrame *enc_frame = data;
00223
00224 av_freep(&(enc_frame->p_encbuf));
00225 av_free(enc_frame);
00226 }
00227
00228 static int libdirac_encode_frame(AVCodecContext *avccontext,
00229 unsigned char *frame,
00230 int buf_size, void *data)
00231 {
00232 int enc_size = 0;
00233 dirac_encoder_state_t state;
00234 FfmpegDiracEncoderParams* p_dirac_params = avccontext->priv_data;
00235 FfmpegDiracSchroEncodedFrame* p_frame_output = NULL;
00236 FfmpegDiracSchroEncodedFrame* p_next_output_frame = NULL;
00237 int go = 1;
00238 int last_frame_in_sequence = 0;
00239
00240 if (!data) {
00241
00242 if (!p_dirac_params->eos_signalled) {
00243 dirac_encoder_end_sequence(p_dirac_params->p_encoder);
00244 p_dirac_params->eos_signalled = 1;
00245 }
00246 } else {
00247
00248
00249
00250
00251
00252 avpicture_layout((AVPicture *)data, avccontext->pix_fmt,
00253 avccontext->width, avccontext->height,
00254 p_dirac_params->p_in_frame_buf,
00255 p_dirac_params->frame_size);
00256
00257
00258 if (dirac_encoder_load(p_dirac_params->p_encoder,
00259 p_dirac_params->p_in_frame_buf,
00260 p_dirac_params->frame_size) < 0) {
00261 av_log(avccontext, AV_LOG_ERROR, "Unrecoverable Encoder Error."
00262 " dirac_encoder_load failed...\n");
00263 return -1;
00264 }
00265 }
00266
00267 if (p_dirac_params->eos_pulled)
00268 go = 0;
00269
00270 while (go) {
00271 p_dirac_params->p_encoder->enc_buf.buffer = frame;
00272 p_dirac_params->p_encoder->enc_buf.size = buf_size;
00273
00274 state = dirac_encoder_output(p_dirac_params->p_encoder);
00275
00276 switch (state) {
00277 case ENC_STATE_AVAIL:
00278 case ENC_STATE_EOS:
00279 assert(p_dirac_params->p_encoder->enc_buf.size > 0);
00280
00281
00282
00283
00284
00285
00286 p_dirac_params->enc_buf = av_realloc(p_dirac_params->enc_buf,
00287 p_dirac_params->enc_buf_size +
00288 p_dirac_params->p_encoder->enc_buf.size);
00289 memcpy(p_dirac_params->enc_buf + p_dirac_params->enc_buf_size,
00290 p_dirac_params->p_encoder->enc_buf.buffer,
00291 p_dirac_params->p_encoder->enc_buf.size);
00292
00293 p_dirac_params->enc_buf_size += p_dirac_params->p_encoder->enc_buf.size;
00294
00295 if (state == ENC_STATE_EOS) {
00296 p_dirac_params->eos_pulled = 1;
00297 go = 0;
00298 }
00299
00300
00301
00302 if (p_dirac_params->p_encoder->enc_pparams.pnum == -1)
00303 break;
00304
00305
00306 p_frame_output = av_mallocz(sizeof(FfmpegDiracSchroEncodedFrame));
00307
00308 p_frame_output->size = p_dirac_params->enc_buf_size;
00309 p_frame_output->p_encbuf = p_dirac_params->enc_buf;
00310 p_frame_output->frame_num = p_dirac_params->p_encoder->enc_pparams.pnum;
00311
00312 if (p_dirac_params->p_encoder->enc_pparams.ptype == INTRA_PICTURE &&
00313 p_dirac_params->p_encoder->enc_pparams.rtype == REFERENCE_PICTURE)
00314 p_frame_output->key_frame = 1;
00315
00316 ff_dirac_schro_queue_push_back(&p_dirac_params->enc_frame_queue,
00317 p_frame_output);
00318
00319 p_dirac_params->enc_buf_size = 0;
00320 p_dirac_params->enc_buf = NULL;
00321 break;
00322
00323 case ENC_STATE_BUFFER:
00324 go = 0;
00325 break;
00326
00327 case ENC_STATE_INVALID:
00328 av_log(avccontext, AV_LOG_ERROR,
00329 "Unrecoverable Dirac Encoder Error. Quitting...\n");
00330 return -1;
00331
00332 default:
00333 av_log(avccontext, AV_LOG_ERROR, "Unknown Dirac Encoder state\n");
00334 return -1;
00335 }
00336 }
00337
00338
00339
00340 if (p_dirac_params->enc_frame_queue.size == 1 && p_dirac_params->eos_pulled)
00341 last_frame_in_sequence = 1;
00342
00343 p_next_output_frame = ff_dirac_schro_queue_pop(&p_dirac_params->enc_frame_queue);
00344
00345 if (!p_next_output_frame)
00346 return 0;
00347
00348 memcpy(frame, p_next_output_frame->p_encbuf, p_next_output_frame->size);
00349 avccontext->coded_frame->key_frame = p_next_output_frame->key_frame;
00350
00351
00352
00353 avccontext->coded_frame->pts = p_next_output_frame->frame_num;
00354 enc_size = p_next_output_frame->size;
00355
00356
00357
00358 if (last_frame_in_sequence && p_dirac_params->enc_buf_size > 0) {
00359 memcpy(frame + enc_size, p_dirac_params->enc_buf,
00360 p_dirac_params->enc_buf_size);
00361 enc_size += p_dirac_params->enc_buf_size;
00362 av_freep(&p_dirac_params->enc_buf);
00363 p_dirac_params->enc_buf_size = 0;
00364 }
00365
00366
00367 DiracFreeFrame(p_next_output_frame);
00368
00369 return enc_size;
00370 }
00371
00372 static av_cold int libdirac_encode_close(AVCodecContext *avccontext)
00373 {
00374 FfmpegDiracEncoderParams* p_dirac_params = avccontext->priv_data;
00375
00376
00377 dirac_encoder_close(p_dirac_params->p_encoder);
00378
00379
00380 ff_dirac_schro_queue_free(&p_dirac_params->enc_frame_queue,
00381 DiracFreeFrame);
00382
00383
00384 if (p_dirac_params->enc_buf_size)
00385 av_freep(&p_dirac_params->enc_buf);
00386
00387
00388 av_freep(&p_dirac_params->p_in_frame_buf);
00389
00390 return 0;
00391 }
00392
00393
00394 AVCodec ff_libdirac_encoder = {
00395 "libdirac",
00396 AVMEDIA_TYPE_VIDEO,
00397 CODEC_ID_DIRAC,
00398 sizeof(FfmpegDiracEncoderParams),
00399 libdirac_encode_init,
00400 libdirac_encode_frame,
00401 libdirac_encode_close,
00402 .capabilities = CODEC_CAP_DELAY,
00403 .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_YUV444P, PIX_FMT_NONE},
00404 .long_name = NULL_IF_CONFIG_SMALL("libdirac Dirac 2.2"),
00405 };