00001 /* 00002 * Dirac encoding support via libdirac library 00003 * Copyright (c) 2005 BBC, Andrew Kennedy <dirac at rd dot bbc dot co dot uk> 00004 * Copyright (c) 2006-2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot com > 00005 * 00006 * This file is part of FFmpeg. 00007 * 00008 * FFmpeg is free software; you can redistribute it and/or 00009 * modify it under the terms of the GNU Lesser General Public 00010 * License as published by the Free Software Foundation; either 00011 * version 2.1 of the License, or (at your option) any later version. 00012 * 00013 * FFmpeg is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with FFmpeg; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 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 00042 { 00044 dirac_encoder_context_t enc_ctx; 00045 00047 AVFrame picture; 00048 00050 int frame_size; 00051 00053 dirac_encoder_t* p_encoder; 00054 00056 unsigned char *p_in_frame_buf; 00057 00059 unsigned char *enc_buf; 00060 00062 int enc_buf_size; 00063 00065 FfmpegDiracSchroQueue enc_frame_queue; 00066 00068 int eos_signalled; 00069 00071 int eos_pulled; 00072 } FfmpegDiracEncoderParams; 00073 00077 static dirac_chroma_t GetDiracChromaFormat(enum PixelFormat ff_pix_fmt) 00078 { 00079 int num_formats = sizeof(ffmpeg_dirac_pixel_format_map) / 00080 sizeof(ffmpeg_dirac_pixel_format_map[0]); 00081 int idx; 00082 00083 for (idx = 0; idx < num_formats; ++idx) { 00084 if (ffmpeg_dirac_pixel_format_map[idx].ff_pix_fmt == ff_pix_fmt) { 00085 return ffmpeg_dirac_pixel_format_map[idx].dirac_pix_fmt; 00086 } 00087 } 00088 return formatNK; 00089 } 00090 00095 static const VideoFormat ff_dirac_video_formats[]={ 00096 VIDEO_FORMAT_CUSTOM , 00097 VIDEO_FORMAT_QSIF525 , 00098 VIDEO_FORMAT_QCIF , 00099 VIDEO_FORMAT_SIF525 , 00100 VIDEO_FORMAT_CIF , 00101 VIDEO_FORMAT_4SIF525 , 00102 VIDEO_FORMAT_4CIF , 00103 VIDEO_FORMAT_SD_480I60 , 00104 VIDEO_FORMAT_SD_576I50 , 00105 VIDEO_FORMAT_HD_720P60 , 00106 VIDEO_FORMAT_HD_720P50 , 00107 VIDEO_FORMAT_HD_1080I60 , 00108 VIDEO_FORMAT_HD_1080I50 , 00109 VIDEO_FORMAT_HD_1080P60 , 00110 VIDEO_FORMAT_HD_1080P50 , 00111 VIDEO_FORMAT_DIGI_CINEMA_2K24 , 00112 VIDEO_FORMAT_DIGI_CINEMA_4K24 , 00113 }; 00114 00119 static VideoFormat GetDiracVideoFormatPreset (AVCodecContext *avccontext) 00120 { 00121 unsigned int num_formats = sizeof(ff_dirac_video_formats) / 00122 sizeof(ff_dirac_video_formats[0]); 00123 00124 unsigned int idx = ff_dirac_schro_get_video_format_idx (avccontext); 00125 00126 return (idx < num_formats) ? 00127 ff_dirac_video_formats[idx] : VIDEO_FORMAT_CUSTOM; 00128 } 00129 00130 static av_cold int libdirac_encode_init(AVCodecContext *avccontext) 00131 { 00132 00133 FfmpegDiracEncoderParams* p_dirac_params = avccontext->priv_data; 00134 int no_local = 1; 00135 int verbose = avccontext->debug; 00136 VideoFormat preset; 00137 00138 /* get Dirac preset */ 00139 preset = GetDiracVideoFormatPreset(avccontext); 00140 00141 /* initialize the encoder context */ 00142 dirac_encoder_context_init (&(p_dirac_params->enc_ctx), preset); 00143 00144 p_dirac_params->enc_ctx.src_params.chroma = 00145 GetDiracChromaFormat(avccontext->pix_fmt); 00146 00147 if (p_dirac_params->enc_ctx.src_params.chroma == formatNK) { 00148 av_log (avccontext, AV_LOG_ERROR, 00149 "Unsupported pixel format %d. This codec supports only " 00150 "Planar YUV formats (yuv420p, yuv422p, yuv444p\n", 00151 avccontext->pix_fmt); 00152 return -1; 00153 } 00154 00155 p_dirac_params->enc_ctx.src_params.frame_rate.numerator = 00156 avccontext->time_base.den; 00157 p_dirac_params->enc_ctx.src_params.frame_rate.denominator = 00158 avccontext->time_base.num; 00159 00160 p_dirac_params->enc_ctx.src_params.width = avccontext->width; 00161 p_dirac_params->enc_ctx.src_params.height = avccontext->height; 00162 00163 p_dirac_params->frame_size = avpicture_get_size(avccontext->pix_fmt, 00164 avccontext->width, 00165 avccontext->height); 00166 00167 avccontext->coded_frame = &p_dirac_params->picture; 00168 00169 if (no_local) { 00170 p_dirac_params->enc_ctx.decode_flag = 0; 00171 p_dirac_params->enc_ctx.instr_flag = 0; 00172 } else { 00173 p_dirac_params->enc_ctx.decode_flag = 1; 00174 p_dirac_params->enc_ctx.instr_flag = 1; 00175 } 00176 00177 /* Intra-only sequence */ 00178 if (avccontext->gop_size == 0 ) { 00179 p_dirac_params->enc_ctx.enc_params.num_L1 = 0; 00180 if (avccontext->coder_type == FF_CODER_TYPE_VLC) 00181 p_dirac_params->enc_ctx.enc_params.using_ac = 0; 00182 } else 00183 avccontext->has_b_frames = 1; 00184 00185 if (avccontext->flags & CODEC_FLAG_QSCALE) { 00186 if (avccontext->global_quality != 0) { 00187 p_dirac_params->enc_ctx.enc_params.qf = 00188 avccontext->global_quality / (FF_QP2LAMBDA*10.0); 00189 /* if it is not default bitrate then send target rate. */ 00190 if (avccontext->bit_rate >= 1000 && 00191 avccontext->bit_rate != 200000) { 00192 p_dirac_params->enc_ctx.enc_params.trate = 00193 avccontext->bit_rate / 1000; 00194 } 00195 } else 00196 p_dirac_params->enc_ctx.enc_params.lossless = 1; 00197 } else if (avccontext->bit_rate >= 1000) 00198 p_dirac_params->enc_ctx.enc_params.trate = avccontext->bit_rate / 1000; 00199 00200 if ((preset > VIDEO_FORMAT_QCIF || preset < VIDEO_FORMAT_QSIF525) && 00201 avccontext->bit_rate == 200000) { 00202 p_dirac_params->enc_ctx.enc_params.trate = 0; 00203 } 00204 00205 if (avccontext->flags & CODEC_FLAG_INTERLACED_ME) { 00206 /* all material can be coded as interlaced or progressive 00207 * irrespective of the type of source material */ 00208 p_dirac_params->enc_ctx.enc_params.picture_coding_mode = 1; 00209 } 00210 00211 p_dirac_params->p_encoder = dirac_encoder_init (&(p_dirac_params->enc_ctx), 00212 verbose ); 00213 00214 if (!p_dirac_params->p_encoder) { 00215 av_log(avccontext, AV_LOG_ERROR, 00216 "Unrecoverable Error: dirac_encoder_init failed. "); 00217 return EXIT_FAILURE; 00218 } 00219 00220 /* allocate enough memory for the incoming data */ 00221 p_dirac_params->p_in_frame_buf = av_malloc(p_dirac_params->frame_size); 00222 00223 /* initialize the encoded frame queue */ 00224 ff_dirac_schro_queue_init(&p_dirac_params->enc_frame_queue); 00225 00226 return 0 ; 00227 } 00228 00229 static void DiracFreeFrame (void *data) 00230 { 00231 FfmpegDiracSchroEncodedFrame *enc_frame = data; 00232 00233 av_freep (&(enc_frame->p_encbuf)); 00234 av_free(enc_frame); 00235 } 00236 00237 static int libdirac_encode_frame(AVCodecContext *avccontext, 00238 unsigned char *frame, 00239 int buf_size, void *data) 00240 { 00241 int enc_size = 0; 00242 dirac_encoder_state_t state; 00243 FfmpegDiracEncoderParams* p_dirac_params = avccontext->priv_data; 00244 FfmpegDiracSchroEncodedFrame* p_frame_output = NULL; 00245 FfmpegDiracSchroEncodedFrame* p_next_output_frame = NULL; 00246 int go = 1; 00247 int last_frame_in_sequence = 0; 00248 00249 if (data == NULL) { 00250 /* push end of sequence if not already signalled */ 00251 if (!p_dirac_params->eos_signalled) { 00252 dirac_encoder_end_sequence( p_dirac_params->p_encoder ); 00253 p_dirac_params->eos_signalled = 1; 00254 } 00255 } else { 00256 00257 /* Allocate frame data to Dirac input buffer. 00258 * Input line size may differ from what the codec supports, 00259 * especially when transcoding from one format to another. 00260 * So use avpicture_layout to copy the frame. */ 00261 avpicture_layout ((AVPicture *)data, avccontext->pix_fmt, 00262 avccontext->width, avccontext->height, 00263 p_dirac_params->p_in_frame_buf, 00264 p_dirac_params->frame_size); 00265 00266 /* load next frame */ 00267 if (dirac_encoder_load (p_dirac_params->p_encoder, 00268 p_dirac_params->p_in_frame_buf, 00269 p_dirac_params->frame_size ) < 0) { 00270 av_log(avccontext, AV_LOG_ERROR, "Unrecoverable Encoder Error." 00271 " dirac_encoder_load failed...\n"); 00272 return -1; 00273 } 00274 } 00275 00276 if (p_dirac_params->eos_pulled) 00277 go = 0; 00278 00279 while(go) { 00280 p_dirac_params->p_encoder->enc_buf.buffer = frame; 00281 p_dirac_params->p_encoder->enc_buf.size = buf_size; 00282 /* process frame */ 00283 state = dirac_encoder_output ( p_dirac_params->p_encoder ); 00284 00285 switch (state) 00286 { 00287 case ENC_STATE_AVAIL: 00288 case ENC_STATE_EOS: 00289 assert (p_dirac_params->p_encoder->enc_buf.size > 0); 00290 00291 /* All non-frame data is prepended to actual frame data to 00292 * be able to set the pts correctly. So we don't write data 00293 * to the frame output queue until we actually have a frame 00294 */ 00295 00296 p_dirac_params->enc_buf = av_realloc ( 00297 p_dirac_params->enc_buf, 00298 p_dirac_params->enc_buf_size + 00299 p_dirac_params->p_encoder->enc_buf.size 00300 ); 00301 memcpy(p_dirac_params->enc_buf + p_dirac_params->enc_buf_size, 00302 p_dirac_params->p_encoder->enc_buf.buffer, 00303 p_dirac_params->p_encoder->enc_buf.size); 00304 00305 p_dirac_params->enc_buf_size += 00306 p_dirac_params->p_encoder->enc_buf.size; 00307 00308 if (state == ENC_STATE_EOS) { 00309 p_dirac_params->eos_pulled = 1; 00310 go = 0; 00311 } 00312 00313 /* If non-frame data, don't output it until it we get an 00314 * encoded frame back from the encoder. */ 00315 if (p_dirac_params->p_encoder->enc_pparams.pnum == -1) 00316 break; 00317 00318 /* create output frame */ 00319 p_frame_output = av_mallocz(sizeof(FfmpegDiracSchroEncodedFrame)); 00320 /* set output data */ 00321 p_frame_output->size = p_dirac_params->enc_buf_size; 00322 p_frame_output->p_encbuf = p_dirac_params->enc_buf; 00323 p_frame_output->frame_num = 00324 p_dirac_params->p_encoder->enc_pparams.pnum; 00325 00326 if (p_dirac_params->p_encoder->enc_pparams.ptype == INTRA_PICTURE && 00327 p_dirac_params->p_encoder->enc_pparams.rtype == REFERENCE_PICTURE) 00328 p_frame_output->key_frame = 1; 00329 00330 ff_dirac_schro_queue_push_back (&p_dirac_params->enc_frame_queue, 00331 p_frame_output); 00332 00333 p_dirac_params->enc_buf_size = 0; 00334 p_dirac_params->enc_buf = NULL; 00335 break; 00336 00337 case ENC_STATE_BUFFER: 00338 go = 0; 00339 break; 00340 00341 case ENC_STATE_INVALID: 00342 av_log(avccontext, AV_LOG_ERROR, 00343 "Unrecoverable Dirac Encoder Error. Quitting...\n"); 00344 return -1; 00345 00346 default: 00347 av_log(avccontext, AV_LOG_ERROR, "Unknown Dirac Encoder state\n"); 00348 return -1; 00349 } 00350 } 00351 00352 /* copy 'next' frame in queue */ 00353 00354 if (p_dirac_params->enc_frame_queue.size == 1 && 00355 p_dirac_params->eos_pulled) 00356 last_frame_in_sequence = 1; 00357 00358 p_next_output_frame = 00359 ff_dirac_schro_queue_pop(&p_dirac_params->enc_frame_queue); 00360 00361 if (p_next_output_frame == NULL) 00362 return 0; 00363 00364 memcpy(frame, p_next_output_frame->p_encbuf, p_next_output_frame->size); 00365 avccontext->coded_frame->key_frame = p_next_output_frame->key_frame; 00366 /* Use the frame number of the encoded frame as the pts. It is OK to do 00367 * so since Dirac is a constant framerate codec. It expects input to be 00368 * of constant framerate. */ 00369 avccontext->coded_frame->pts = p_next_output_frame->frame_num; 00370 enc_size = p_next_output_frame->size; 00371 00372 /* Append the end of sequence information to the last frame in the 00373 * sequence. */ 00374 if (last_frame_in_sequence && p_dirac_params->enc_buf_size > 0) 00375 { 00376 memcpy (frame + enc_size, p_dirac_params->enc_buf, 00377 p_dirac_params->enc_buf_size); 00378 enc_size += p_dirac_params->enc_buf_size; 00379 av_freep (&p_dirac_params->enc_buf); 00380 p_dirac_params->enc_buf_size = 0; 00381 } 00382 00383 /* free frame */ 00384 DiracFreeFrame(p_next_output_frame); 00385 00386 return enc_size; 00387 } 00388 00389 static av_cold int libdirac_encode_close(AVCodecContext *avccontext) 00390 { 00391 FfmpegDiracEncoderParams* p_dirac_params = avccontext->priv_data; 00392 00393 /* close the encoder */ 00394 dirac_encoder_close(p_dirac_params->p_encoder ); 00395 00396 /* free data in the output frame queue */ 00397 ff_dirac_schro_queue_free(&p_dirac_params->enc_frame_queue, 00398 DiracFreeFrame); 00399 00400 /* free the encoder buffer */ 00401 if (p_dirac_params->enc_buf_size) 00402 av_freep(&p_dirac_params->enc_buf); 00403 00404 /* free the input frame buffer */ 00405 av_freep(&p_dirac_params->p_in_frame_buf); 00406 00407 return 0 ; 00408 } 00409 00410 00411 AVCodec libdirac_encoder = { 00412 "libdirac", 00413 CODEC_TYPE_VIDEO, 00414 CODEC_ID_DIRAC, 00415 sizeof(FfmpegDiracEncoderParams), 00416 libdirac_encode_init, 00417 libdirac_encode_frame, 00418 libdirac_encode_close, 00419 .capabilities= CODEC_CAP_DELAY, 00420 .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_YUV444P, PIX_FMT_NONE}, 00421 .long_name= NULL_IF_CONFIG_SMALL("libdirac Dirac 2.2"), 00422 } ;