1/* 2 * Dirac encoder support via Schroedinger libraries 3 * Copyright (c) 2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot com > 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22/** 23* @file libavcodec/libschroedingerenc.c 24* Dirac encoder support via libschroedinger-1.0 libraries. More details about 25* the Schroedinger project can be found at http://www.diracvideo.org/. 26* The library implements Dirac Specification Version 2.2 27* (http://dirac.sourceforge.net/specification.html). 28*/ 29 30#undef NDEBUG 31#include <assert.h> 32 33#include <schroedinger/schro.h> 34#include <schroedinger/schrodebug.h> 35#include <schroedinger/schrovideoformat.h> 36 37#include "avcodec.h" 38#include "libdirac_libschro.h" 39#include "libschroedinger.h" 40 41 42/** libschroedinger encoder private data */ 43typedef struct FfmpegSchroEncoderParams 44{ 45 /** Schroedinger video format */ 46 SchroVideoFormat *format; 47 48 /** Schroedinger frame format */ 49 SchroFrameFormat frame_format; 50 51 /** frame being encoded */ 52 AVFrame picture; 53 54 /** frame size */ 55 int frame_size; 56 57 /** Schroedinger encoder handle*/ 58 SchroEncoder* encoder; 59 60 /** buffer to store encoder output before writing it to the frame queue*/ 61 unsigned char *enc_buf; 62 63 /** Size of encoder buffer*/ 64 int enc_buf_size; 65 66 /** queue storing encoded frames */ 67 FfmpegDiracSchroQueue enc_frame_queue; 68 69 /** end of sequence signalled */ 70 int eos_signalled; 71 72 /** end of sequence pulled */ 73 int eos_pulled; 74} FfmpegSchroEncoderParams; 75 76/** 77* Works out Schro-compatible chroma format. 78*/ 79static int SetSchroChromaFormat(AVCodecContext *avccontext) 80{ 81 int num_formats = sizeof(ffmpeg_schro_pixel_format_map) / 82 sizeof(ffmpeg_schro_pixel_format_map[0]); 83 int idx; 84 85 FfmpegSchroEncoderParams* p_schro_params = avccontext->priv_data; 86 87 for (idx = 0; idx < num_formats; ++idx) { 88 if (ffmpeg_schro_pixel_format_map[idx].ff_pix_fmt == 89 avccontext->pix_fmt) { 90 p_schro_params->format->chroma_format = 91 ffmpeg_schro_pixel_format_map[idx].schro_pix_fmt; 92 return 0; 93 } 94 } 95 96 av_log (avccontext, AV_LOG_ERROR, 97 "This codec currently only supports planar YUV 4:2:0, 4:2:2" 98 " and 4:4:4 formats.\n"); 99 100 return -1; 101} 102 103static int libschroedinger_encode_init(AVCodecContext *avccontext) 104{ 105 FfmpegSchroEncoderParams* p_schro_params = avccontext->priv_data; 106 SchroVideoFormatEnum preset; 107 108 /* Initialize the libraries that libschroedinger depends on. */ 109 schro_init(); 110 111 /* Create an encoder object. */ 112 p_schro_params->encoder = schro_encoder_new(); 113 114 if (!p_schro_params->encoder) { 115 av_log(avccontext, AV_LOG_ERROR, 116 "Unrecoverable Error: schro_encoder_new failed. "); 117 return -1; 118 } 119 120 /* Initialize the format. */ 121 preset = ff_get_schro_video_format_preset(avccontext); 122 p_schro_params->format = 123 schro_encoder_get_video_format(p_schro_params->encoder); 124 schro_video_format_set_std_video_format (p_schro_params->format, preset); 125 p_schro_params->format->width = avccontext->width; 126 p_schro_params->format->height = avccontext->height; 127 128 if (SetSchroChromaFormat(avccontext) == -1) 129 return -1; 130 131 if (ff_get_schro_frame_format(p_schro_params->format->chroma_format, 132 &p_schro_params->frame_format) == -1) { 133 av_log (avccontext, AV_LOG_ERROR, 134 "This codec currently supports only planar YUV 4:2:0, 4:2:2" 135 " and 4:4:4 formats.\n"); 136 return -1; 137 } 138 139 p_schro_params->format->frame_rate_numerator = avccontext->time_base.den; 140 p_schro_params->format->frame_rate_denominator = avccontext->time_base.num; 141 142 p_schro_params->frame_size = avpicture_get_size(avccontext->pix_fmt, 143 avccontext->width, 144 avccontext->height); 145 146 avccontext->coded_frame = &p_schro_params->picture; 147 148 if (avccontext->gop_size == 0){ 149 schro_encoder_setting_set_double (p_schro_params->encoder, 150 "gop_structure", 151 SCHRO_ENCODER_GOP_INTRA_ONLY); 152 153 if (avccontext->coder_type == FF_CODER_TYPE_VLC) { 154 schro_encoder_setting_set_double (p_schro_params->encoder, 155 "enable_noarith", 1); 156 } 157 } 158 else { 159 schro_encoder_setting_set_double (p_schro_params->encoder, 160 "gop_structure", 161 SCHRO_ENCODER_GOP_BIREF); 162 avccontext->has_b_frames = 1; 163 } 164 165 /* FIXME - Need to handle SCHRO_ENCODER_RATE_CONTROL_LOW_DELAY. */ 166 if (avccontext->flags & CODEC_FLAG_QSCALE) { 167 if (avccontext->global_quality == 0) { 168 /* lossless coding */ 169 schro_encoder_setting_set_double (p_schro_params->encoder, 170 "rate_control", 171 SCHRO_ENCODER_RATE_CONTROL_LOSSLESS); 172 } else { 173 int noise_threshold; 174 schro_encoder_setting_set_double (p_schro_params->encoder, 175 "rate_control", 176 SCHRO_ENCODER_RATE_CONTROL_CONSTANT_NOISE_THRESHOLD); 177 178 noise_threshold = avccontext->global_quality/FF_QP2LAMBDA; 179 if (noise_threshold > 100) 180 noise_threshold = 100; 181 schro_encoder_setting_set_double (p_schro_params->encoder, 182 "noise_threshold", 183 noise_threshold); 184 } 185 } 186 else { 187 schro_encoder_setting_set_double ( p_schro_params->encoder, 188 "rate_control", 189 SCHRO_ENCODER_RATE_CONTROL_CONSTANT_BITRATE); 190 191 schro_encoder_setting_set_double (p_schro_params->encoder, 192 "bitrate", 193 avccontext->bit_rate); 194 195 } 196 197 if (avccontext->flags & CODEC_FLAG_INTERLACED_ME) { 198 /* All material can be coded as interlaced or progressive 199 irrespective of the type of source material. */ 200 schro_encoder_setting_set_double (p_schro_params->encoder, 201 "interlaced_coding", 1); 202 } 203 204 /* FIXME: Signal range hardcoded to 8-bit data until both libschroedinger 205 * and libdirac support other bit-depth data. */ 206 schro_video_format_set_std_signal_range(p_schro_params->format, 207 SCHRO_SIGNAL_RANGE_8BIT_VIDEO); 208 209 /* Set the encoder format. */ 210 schro_encoder_set_video_format(p_schro_params->encoder, 211 p_schro_params->format); 212 213 /* Set the debug level. */ 214 schro_debug_set_level (avccontext->debug); 215 216 schro_encoder_start (p_schro_params->encoder); 217 218 /* Initialize the encoded frame queue. */ 219 ff_dirac_schro_queue_init (&p_schro_params->enc_frame_queue); 220 return 0 ; 221} 222 223static SchroFrame *libschroedinger_frame_from_data (AVCodecContext *avccontext, 224 void *in_data) 225{ 226 FfmpegSchroEncoderParams* p_schro_params = avccontext->priv_data; 227 SchroFrame *in_frame; 228 /* Input line size may differ from what the codec supports. Especially 229 * when transcoding from one format to another. So use avpicture_layout 230 * to copy the frame. */ 231 in_frame = schro_frame_new_and_alloc (NULL, 232 p_schro_params->frame_format, 233 p_schro_params->format->width, 234 p_schro_params->format->height); 235 236 avpicture_layout ((AVPicture *)in_data, avccontext->pix_fmt, 237 avccontext->width, avccontext->height, 238 in_frame->components[0].data, 239 p_schro_params->frame_size); 240 241 return in_frame; 242} 243 244static void SchroedingerFreeFrame(void *data) 245{ 246 FfmpegDiracSchroEncodedFrame *enc_frame = data; 247 248 av_freep (&(enc_frame->p_encbuf)); 249 av_free(enc_frame); 250} 251 252static int libschroedinger_encode_frame(AVCodecContext *avccontext, 253 unsigned char *frame, 254 int buf_size, void *data) 255{ 256 int enc_size = 0; 257 FfmpegSchroEncoderParams* p_schro_params = avccontext->priv_data; 258 SchroEncoder *encoder = p_schro_params->encoder; 259 struct FfmpegDiracSchroEncodedFrame* p_frame_output = NULL; 260 int go = 1; 261 SchroBuffer *enc_buf; 262 int presentation_frame; 263 int parse_code; 264 int last_frame_in_sequence = 0; 265 266 if(data == NULL) { 267 /* Push end of sequence if not already signalled. */ 268 if (!p_schro_params->eos_signalled) { 269 schro_encoder_end_of_stream(encoder); 270 p_schro_params->eos_signalled = 1; 271 } 272 } else { 273 /* Allocate frame data to schro input buffer. */ 274 SchroFrame *in_frame = libschroedinger_frame_from_data (avccontext, 275 data); 276 /* Load next frame. */ 277 schro_encoder_push_frame(encoder, in_frame); 278 } 279 280 if (p_schro_params->eos_pulled) 281 go = 0; 282 283 /* Now check to see if we have any output from the encoder. */ 284 while (go) { 285 SchroStateEnum state; 286 state = schro_encoder_wait(encoder); 287 switch (state) 288 { 289 case SCHRO_STATE_HAVE_BUFFER: 290 case SCHRO_STATE_END_OF_STREAM: 291 enc_buf = schro_encoder_pull (encoder, 292 &presentation_frame); 293 assert (enc_buf->length > 0); 294 assert (enc_buf->length <= buf_size); 295 parse_code = enc_buf->data[4]; 296 297 /* All non-frame data is prepended to actual frame data to 298 * be able to set the pts correctly. So we don't write data 299 * to the frame output queue until we actually have a frame 300 */ 301 p_schro_params->enc_buf = av_realloc ( 302 p_schro_params->enc_buf, 303 p_schro_params->enc_buf_size + enc_buf->length 304 ); 305 306 memcpy(p_schro_params->enc_buf+p_schro_params->enc_buf_size, 307 enc_buf->data, enc_buf->length); 308 p_schro_params->enc_buf_size += enc_buf->length; 309 310 311 if (state == SCHRO_STATE_END_OF_STREAM) { 312 p_schro_params->eos_pulled = 1; 313 go = 0; 314 } 315 316 if (!SCHRO_PARSE_CODE_IS_PICTURE(parse_code)) { 317 schro_buffer_unref (enc_buf); 318 break; 319 } 320 321 /* Create output frame. */ 322 p_frame_output = av_mallocz(sizeof(FfmpegDiracSchroEncodedFrame)); 323 /* Set output data. */ 324 p_frame_output->size = p_schro_params->enc_buf_size; 325 p_frame_output->p_encbuf = p_schro_params->enc_buf; 326 if (SCHRO_PARSE_CODE_IS_INTRA(parse_code) && 327 SCHRO_PARSE_CODE_IS_REFERENCE(parse_code)) { 328 p_frame_output->key_frame = 1; 329 } 330 331 /* Parse the coded frame number from the bitstream. Bytes 14 332 * through 17 represesent the frame number. */ 333 p_frame_output->frame_num = (enc_buf->data[13] << 24) + 334 (enc_buf->data[14] << 16) + 335 (enc_buf->data[15] << 8) + 336 enc_buf->data[16]; 337 338 ff_dirac_schro_queue_push_back (&p_schro_params->enc_frame_queue, 339 p_frame_output); 340 p_schro_params->enc_buf_size = 0; 341 p_schro_params->enc_buf = NULL; 342 343 schro_buffer_unref (enc_buf); 344 345 break; 346 347 case SCHRO_STATE_NEED_FRAME: 348 go = 0; 349 break; 350 351 case SCHRO_STATE_AGAIN: 352 break; 353 354 default: 355 av_log(avccontext, AV_LOG_ERROR, "Unknown Schro Encoder state\n"); 356 return -1; 357 } 358 } 359 360 /* Copy 'next' frame in queue. */ 361 362 if (p_schro_params->enc_frame_queue.size == 1 && 363 p_schro_params->eos_pulled) 364 last_frame_in_sequence = 1; 365 366 p_frame_output = 367 ff_dirac_schro_queue_pop (&p_schro_params->enc_frame_queue); 368 369 if (p_frame_output == NULL) 370 return 0; 371 372 memcpy(frame, p_frame_output->p_encbuf, p_frame_output->size); 373 avccontext->coded_frame->key_frame = p_frame_output->key_frame; 374 /* Use the frame number of the encoded frame as the pts. It is OK to 375 * do so since Dirac is a constant frame rate codec. It expects input 376 * to be of constant frame rate. */ 377 avccontext->coded_frame->pts = p_frame_output->frame_num; 378 enc_size = p_frame_output->size; 379 380 /* Append the end of sequence information to the last frame in the 381 * sequence. */ 382 if (last_frame_in_sequence && p_schro_params->enc_buf_size > 0) 383 { 384 memcpy (frame + enc_size, p_schro_params->enc_buf, 385 p_schro_params->enc_buf_size); 386 enc_size += p_schro_params->enc_buf_size; 387 av_freep (&p_schro_params->enc_buf); 388 p_schro_params->enc_buf_size = 0; 389 } 390 391 /* free frame */ 392 SchroedingerFreeFrame (p_frame_output); 393 394 return enc_size; 395} 396 397 398static int libschroedinger_encode_close(AVCodecContext *avccontext) 399{ 400 401 FfmpegSchroEncoderParams* p_schro_params = avccontext->priv_data; 402 403 /* Close the encoder. */ 404 schro_encoder_free(p_schro_params->encoder); 405 406 /* Free data in the output frame queue. */ 407 ff_dirac_schro_queue_free (&p_schro_params->enc_frame_queue, 408 SchroedingerFreeFrame); 409 410 411 /* Free the encoder buffer. */ 412 if (p_schro_params->enc_buf_size) 413 av_freep(&p_schro_params->enc_buf); 414 415 /* Free the video format structure. */ 416 av_freep(&p_schro_params->format); 417 418 return 0 ; 419} 420 421 422AVCodec libschroedinger_encoder = { 423 "libschroedinger", 424 CODEC_TYPE_VIDEO, 425 CODEC_ID_DIRAC, 426 sizeof(FfmpegSchroEncoderParams), 427 libschroedinger_encode_init, 428 libschroedinger_encode_frame, 429 libschroedinger_encode_close, 430 .capabilities= CODEC_CAP_DELAY, 431 .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_YUV444P, PIX_FMT_NONE}, 432 .long_name= NULL_IF_CONFIG_SMALL("libschroedinger Dirac 2.2"), 433}; 434