| 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 |
| 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 | #include <schroedinger/schro.h> |
| 31 | #include <schroedinger/schrodebug.h> |
| 32 | #include <schroedinger/schrovideoformat.h> |
| 33 | |
| 34 | #include "libavutil/attributes.h" |
| 35 | #include "libavutil/avassert.h" |
| 36 | #include "avcodec.h" |
| 37 | #include "internal.h" |
| 38 | #include "libschroedinger.h" |
| 39 | #include "bytestream.h" |
| 40 | |
| 41 | |
| 42 | /** libschroedinger encoder private data */ |
| 43 | typedef struct SchroEncoderParams { |
| 44 | /** Schroedinger video format */ |
| 45 | SchroVideoFormat *format; |
| 46 | |
| 47 | /** Schroedinger frame format */ |
| 48 | SchroFrameFormat frame_format; |
| 49 | |
| 50 | /** frame size */ |
| 51 | int frame_size; |
| 52 | |
| 53 | /** Schroedinger encoder handle*/ |
| 54 | SchroEncoder* encoder; |
| 55 | |
| 56 | /** buffer to store encoder output before writing it to the frame queue*/ |
| 57 | unsigned char *enc_buf; |
| 58 | |
| 59 | /** Size of encoder buffer*/ |
| 60 | int enc_buf_size; |
| 61 | |
| 62 | /** queue storing encoded frames */ |
| 63 | FFSchroQueue enc_frame_queue; |
| 64 | |
| 65 | /** end of sequence signalled */ |
| 66 | int eos_signalled; |
| 67 | |
| 68 | /** end of sequence pulled */ |
| 69 | int eos_pulled; |
| 70 | |
| 71 | /* counter for frames submitted to encoder, used as dts */ |
| 72 | int64_t dts; |
| 73 | } SchroEncoderParams; |
| 74 | |
| 75 | /** |
| 76 | * Works out Schro-compatible chroma format. |
| 77 | */ |
| 78 | static int set_chroma_format(AVCodecContext *avctx) |
| 79 | { |
| 80 | int num_formats = sizeof(schro_pixel_format_map) / |
| 81 | sizeof(schro_pixel_format_map[0]); |
| 82 | int idx; |
| 83 | |
| 84 | SchroEncoderParams *p_schro_params = avctx->priv_data; |
| 85 | |
| 86 | for (idx = 0; idx < num_formats; ++idx) { |
| 87 | if (schro_pixel_format_map[idx].ff_pix_fmt == avctx->pix_fmt) { |
| 88 | p_schro_params->format->chroma_format = |
| 89 | schro_pixel_format_map[idx].schro_pix_fmt; |
| 90 | return 0; |
| 91 | } |
| 92 | } |
| 93 | |
| 94 | av_log(avctx, AV_LOG_ERROR, |
| 95 | "This codec currently only supports planar YUV 4:2:0, 4:2:2" |
| 96 | " and 4:4:4 formats.\n"); |
| 97 | |
| 98 | return -1; |
| 99 | } |
| 100 | |
| 101 | static av_cold int libschroedinger_encode_init(AVCodecContext *avctx) |
| 102 | { |
| 103 | SchroEncoderParams *p_schro_params = avctx->priv_data; |
| 104 | SchroVideoFormatEnum preset; |
| 105 | |
| 106 | /* Initialize the libraries that libschroedinger depends on. */ |
| 107 | schro_init(); |
| 108 | |
| 109 | /* Create an encoder object. */ |
| 110 | p_schro_params->encoder = schro_encoder_new(); |
| 111 | |
| 112 | if (!p_schro_params->encoder) { |
| 113 | av_log(avctx, AV_LOG_ERROR, |
| 114 | "Unrecoverable Error: schro_encoder_new failed. "); |
| 115 | return -1; |
| 116 | } |
| 117 | |
| 118 | /* Initialize the format. */ |
| 119 | preset = ff_get_schro_video_format_preset(avctx); |
| 120 | p_schro_params->format = |
| 121 | schro_encoder_get_video_format(p_schro_params->encoder); |
| 122 | schro_video_format_set_std_video_format(p_schro_params->format, preset); |
| 123 | p_schro_params->format->width = avctx->width; |
| 124 | p_schro_params->format->height = avctx->height; |
| 125 | |
| 126 | if (set_chroma_format(avctx) == -1) |
| 127 | return -1; |
| 128 | |
| 129 | if (avctx->color_primaries == AVCOL_PRI_BT709) { |
| 130 | p_schro_params->format->colour_primaries = SCHRO_COLOUR_PRIMARY_HDTV; |
| 131 | } else if (avctx->color_primaries == AVCOL_PRI_BT470BG) { |
| 132 | p_schro_params->format->colour_primaries = SCHRO_COLOUR_PRIMARY_SDTV_625; |
| 133 | } else if (avctx->color_primaries == AVCOL_PRI_SMPTE170M) { |
| 134 | p_schro_params->format->colour_primaries = SCHRO_COLOUR_PRIMARY_SDTV_525; |
| 135 | } |
| 136 | |
| 137 | if (avctx->colorspace == AVCOL_SPC_BT709) { |
| 138 | p_schro_params->format->colour_matrix = SCHRO_COLOUR_MATRIX_HDTV; |
| 139 | } else if (avctx->colorspace == AVCOL_SPC_BT470BG) { |
| 140 | p_schro_params->format->colour_matrix = SCHRO_COLOUR_MATRIX_SDTV; |
| 141 | } |
| 142 | |
| 143 | if (avctx->color_trc == AVCOL_TRC_BT709) { |
| 144 | p_schro_params->format->transfer_function = SCHRO_TRANSFER_CHAR_TV_GAMMA; |
| 145 | } |
| 146 | |
| 147 | if (ff_get_schro_frame_format(p_schro_params->format->chroma_format, |
| 148 | &p_schro_params->frame_format) == -1) { |
| 149 | av_log(avctx, AV_LOG_ERROR, |
| 150 | "This codec currently supports only planar YUV 4:2:0, 4:2:2" |
| 151 | " and 4:4:4 formats.\n"); |
| 152 | return -1; |
| 153 | } |
| 154 | |
| 155 | p_schro_params->format->frame_rate_numerator = avctx->time_base.den; |
| 156 | p_schro_params->format->frame_rate_denominator = avctx->time_base.num; |
| 157 | |
| 158 | p_schro_params->frame_size = avpicture_get_size(avctx->pix_fmt, |
| 159 | avctx->width, |
| 160 | avctx->height); |
| 161 | |
| 162 | avctx->coded_frame = av_frame_alloc(); |
| 163 | if (!avctx->coded_frame) |
| 164 | return AVERROR(ENOMEM); |
| 165 | |
| 166 | if (!avctx->gop_size) { |
| 167 | schro_encoder_setting_set_double(p_schro_params->encoder, |
| 168 | "gop_structure", |
| 169 | SCHRO_ENCODER_GOP_INTRA_ONLY); |
| 170 | |
| 171 | if (avctx->coder_type == FF_CODER_TYPE_VLC) |
| 172 | schro_encoder_setting_set_double(p_schro_params->encoder, |
| 173 | "enable_noarith", 1); |
| 174 | } else { |
| 175 | schro_encoder_setting_set_double(p_schro_params->encoder, |
| 176 | "au_distance", avctx->gop_size); |
| 177 | avctx->has_b_frames = 1; |
| 178 | p_schro_params->dts = -1; |
| 179 | } |
| 180 | |
| 181 | /* FIXME - Need to handle SCHRO_ENCODER_RATE_CONTROL_LOW_DELAY. */ |
| 182 | if (avctx->flags & CODEC_FLAG_QSCALE) { |
| 183 | if (!avctx->global_quality) { |
| 184 | /* lossless coding */ |
| 185 | schro_encoder_setting_set_double(p_schro_params->encoder, |
| 186 | "rate_control", |
| 187 | SCHRO_ENCODER_RATE_CONTROL_LOSSLESS); |
| 188 | } else { |
| 189 | int quality; |
| 190 | schro_encoder_setting_set_double(p_schro_params->encoder, |
| 191 | "rate_control", |
| 192 | SCHRO_ENCODER_RATE_CONTROL_CONSTANT_QUALITY); |
| 193 | |
| 194 | quality = avctx->global_quality / FF_QP2LAMBDA; |
| 195 | if (quality > 10) |
| 196 | quality = 10; |
| 197 | schro_encoder_setting_set_double(p_schro_params->encoder, |
| 198 | "quality", quality); |
| 199 | } |
| 200 | } else { |
| 201 | schro_encoder_setting_set_double(p_schro_params->encoder, |
| 202 | "rate_control", |
| 203 | SCHRO_ENCODER_RATE_CONTROL_CONSTANT_BITRATE); |
| 204 | |
| 205 | schro_encoder_setting_set_double(p_schro_params->encoder, |
| 206 | "bitrate", avctx->bit_rate); |
| 207 | } |
| 208 | |
| 209 | if (avctx->flags & CODEC_FLAG_INTERLACED_ME) |
| 210 | /* All material can be coded as interlaced or progressive |
| 211 | irrespective of the type of source material. */ |
| 212 | schro_encoder_setting_set_double(p_schro_params->encoder, |
| 213 | "interlaced_coding", 1); |
| 214 | |
| 215 | schro_encoder_setting_set_double(p_schro_params->encoder, "open_gop", |
| 216 | !(avctx->flags & CODEC_FLAG_CLOSED_GOP)); |
| 217 | |
| 218 | /* FIXME: Signal range hardcoded to 8-bit data until both libschroedinger |
| 219 | * and libdirac support other bit-depth data. */ |
| 220 | schro_video_format_set_std_signal_range(p_schro_params->format, |
| 221 | SCHRO_SIGNAL_RANGE_8BIT_VIDEO); |
| 222 | |
| 223 | /* Set the encoder format. */ |
| 224 | schro_encoder_set_video_format(p_schro_params->encoder, |
| 225 | p_schro_params->format); |
| 226 | |
| 227 | /* Set the debug level. */ |
| 228 | schro_debug_set_level(avctx->debug); |
| 229 | |
| 230 | schro_encoder_start(p_schro_params->encoder); |
| 231 | |
| 232 | /* Initialize the encoded frame queue. */ |
| 233 | ff_schro_queue_init(&p_schro_params->enc_frame_queue); |
| 234 | return 0; |
| 235 | } |
| 236 | |
| 237 | static SchroFrame *libschroedinger_frame_from_data(AVCodecContext *avctx, |
| 238 | const AVFrame *frame) |
| 239 | { |
| 240 | SchroEncoderParams *p_schro_params = avctx->priv_data; |
| 241 | SchroFrame *in_frame; |
| 242 | /* Input line size may differ from what the codec supports. Especially |
| 243 | * when transcoding from one format to another. So use avpicture_layout |
| 244 | * to copy the frame. */ |
| 245 | in_frame = ff_create_schro_frame(avctx, p_schro_params->frame_format); |
| 246 | |
| 247 | if (in_frame) |
| 248 | avpicture_layout((const AVPicture *)frame, avctx->pix_fmt, |
| 249 | avctx->width, avctx->height, |
| 250 | in_frame->components[0].data, |
| 251 | p_schro_params->frame_size); |
| 252 | |
| 253 | return in_frame; |
| 254 | } |
| 255 | |
| 256 | static void libschroedinger_free_frame(void *data) |
| 257 | { |
| 258 | FFSchroEncodedFrame *enc_frame = data; |
| 259 | |
| 260 | av_freep(&enc_frame->p_encbuf); |
| 261 | av_free(enc_frame); |
| 262 | } |
| 263 | |
| 264 | static int libschroedinger_encode_frame(AVCodecContext *avctx, AVPacket *pkt, |
| 265 | const AVFrame *frame, int *got_packet) |
| 266 | { |
| 267 | int enc_size = 0; |
| 268 | SchroEncoderParams *p_schro_params = avctx->priv_data; |
| 269 | SchroEncoder *encoder = p_schro_params->encoder; |
| 270 | struct FFSchroEncodedFrame *p_frame_output = NULL; |
| 271 | int go = 1; |
| 272 | SchroBuffer *enc_buf; |
| 273 | int presentation_frame; |
| 274 | int parse_code; |
| 275 | int last_frame_in_sequence = 0; |
| 276 | int pkt_size, ret; |
| 277 | |
| 278 | if (!frame) { |
| 279 | /* Push end of sequence if not already signalled. */ |
| 280 | if (!p_schro_params->eos_signalled) { |
| 281 | schro_encoder_end_of_stream(encoder); |
| 282 | p_schro_params->eos_signalled = 1; |
| 283 | } |
| 284 | } else { |
| 285 | /* Allocate frame data to schro input buffer. */ |
| 286 | SchroFrame *in_frame = libschroedinger_frame_from_data(avctx, frame); |
| 287 | /* Load next frame. */ |
| 288 | schro_encoder_push_frame(encoder, in_frame); |
| 289 | } |
| 290 | |
| 291 | if (p_schro_params->eos_pulled) |
| 292 | go = 0; |
| 293 | |
| 294 | /* Now check to see if we have any output from the encoder. */ |
| 295 | while (go) { |
| 296 | int err; |
| 297 | SchroStateEnum state; |
| 298 | state = schro_encoder_wait(encoder); |
| 299 | switch (state) { |
| 300 | case SCHRO_STATE_HAVE_BUFFER: |
| 301 | case SCHRO_STATE_END_OF_STREAM: |
| 302 | enc_buf = schro_encoder_pull(encoder, &presentation_frame); |
| 303 | if (enc_buf->length <= 0) |
| 304 | return AVERROR_BUG; |
| 305 | parse_code = enc_buf->data[4]; |
| 306 | |
| 307 | /* All non-frame data is prepended to actual frame data to |
| 308 | * be able to set the pts correctly. So we don't write data |
| 309 | * to the frame output queue until we actually have a frame |
| 310 | */ |
| 311 | if ((err = av_reallocp(&p_schro_params->enc_buf, |
| 312 | p_schro_params->enc_buf_size + |
| 313 | enc_buf->length)) < 0) { |
| 314 | p_schro_params->enc_buf_size = 0; |
| 315 | return err; |
| 316 | } |
| 317 | |
| 318 | memcpy(p_schro_params->enc_buf + p_schro_params->enc_buf_size, |
| 319 | enc_buf->data, enc_buf->length); |
| 320 | p_schro_params->enc_buf_size += enc_buf->length; |
| 321 | |
| 322 | |
| 323 | if (state == SCHRO_STATE_END_OF_STREAM) { |
| 324 | p_schro_params->eos_pulled = 1; |
| 325 | go = 0; |
| 326 | } |
| 327 | |
| 328 | if (!SCHRO_PARSE_CODE_IS_PICTURE(parse_code)) { |
| 329 | schro_buffer_unref(enc_buf); |
| 330 | break; |
| 331 | } |
| 332 | |
| 333 | /* Create output frame. */ |
| 334 | p_frame_output = av_mallocz(sizeof(FFSchroEncodedFrame)); |
| 335 | /* Set output data. */ |
| 336 | p_frame_output->size = p_schro_params->enc_buf_size; |
| 337 | p_frame_output->p_encbuf = p_schro_params->enc_buf; |
| 338 | if (SCHRO_PARSE_CODE_IS_INTRA(parse_code) && |
| 339 | SCHRO_PARSE_CODE_IS_REFERENCE(parse_code)) |
| 340 | p_frame_output->key_frame = 1; |
| 341 | |
| 342 | /* Parse the coded frame number from the bitstream. Bytes 14 |
| 343 | * through 17 represesent the frame number. */ |
| 344 | p_frame_output->frame_num = AV_RB32(enc_buf->data + 13); |
| 345 | |
| 346 | ff_schro_queue_push_back(&p_schro_params->enc_frame_queue, |
| 347 | p_frame_output); |
| 348 | p_schro_params->enc_buf_size = 0; |
| 349 | p_schro_params->enc_buf = NULL; |
| 350 | |
| 351 | schro_buffer_unref(enc_buf); |
| 352 | |
| 353 | break; |
| 354 | |
| 355 | case SCHRO_STATE_NEED_FRAME: |
| 356 | go = 0; |
| 357 | break; |
| 358 | |
| 359 | case SCHRO_STATE_AGAIN: |
| 360 | break; |
| 361 | |
| 362 | default: |
| 363 | av_log(avctx, AV_LOG_ERROR, "Unknown Schro Encoder state\n"); |
| 364 | return -1; |
| 365 | } |
| 366 | } |
| 367 | |
| 368 | /* Copy 'next' frame in queue. */ |
| 369 | |
| 370 | if (p_schro_params->enc_frame_queue.size == 1 && |
| 371 | p_schro_params->eos_pulled) |
| 372 | last_frame_in_sequence = 1; |
| 373 | |
| 374 | p_frame_output = ff_schro_queue_pop(&p_schro_params->enc_frame_queue); |
| 375 | |
| 376 | if (!p_frame_output) |
| 377 | return 0; |
| 378 | |
| 379 | pkt_size = p_frame_output->size; |
| 380 | if (last_frame_in_sequence && p_schro_params->enc_buf_size > 0) |
| 381 | pkt_size += p_schro_params->enc_buf_size; |
| 382 | if ((ret = ff_alloc_packet2(avctx, pkt, pkt_size)) < 0) |
| 383 | goto error; |
| 384 | |
| 385 | memcpy(pkt->data, p_frame_output->p_encbuf, p_frame_output->size); |
| 386 | avctx->coded_frame->key_frame = p_frame_output->key_frame; |
| 387 | /* Use the frame number of the encoded frame as the pts. It is OK to |
| 388 | * do so since Dirac is a constant frame rate codec. It expects input |
| 389 | * to be of constant frame rate. */ |
| 390 | pkt->pts = |
| 391 | avctx->coded_frame->pts = p_frame_output->frame_num; |
| 392 | pkt->dts = p_schro_params->dts++; |
| 393 | enc_size = p_frame_output->size; |
| 394 | |
| 395 | /* Append the end of sequence information to the last frame in the |
| 396 | * sequence. */ |
| 397 | if (last_frame_in_sequence && p_schro_params->enc_buf_size > 0) { |
| 398 | memcpy(pkt->data + enc_size, p_schro_params->enc_buf, |
| 399 | p_schro_params->enc_buf_size); |
| 400 | enc_size += p_schro_params->enc_buf_size; |
| 401 | av_freep(&p_schro_params->enc_buf); |
| 402 | p_schro_params->enc_buf_size = 0; |
| 403 | } |
| 404 | |
| 405 | if (p_frame_output->key_frame) |
| 406 | pkt->flags |= AV_PKT_FLAG_KEY; |
| 407 | *got_packet = 1; |
| 408 | |
| 409 | error: |
| 410 | /* free frame */ |
| 411 | libschroedinger_free_frame(p_frame_output); |
| 412 | return ret; |
| 413 | } |
| 414 | |
| 415 | |
| 416 | static int libschroedinger_encode_close(AVCodecContext *avctx) |
| 417 | { |
| 418 | SchroEncoderParams *p_schro_params = avctx->priv_data; |
| 419 | |
| 420 | /* Close the encoder. */ |
| 421 | schro_encoder_free(p_schro_params->encoder); |
| 422 | |
| 423 | /* Free data in the output frame queue. */ |
| 424 | ff_schro_queue_free(&p_schro_params->enc_frame_queue, |
| 425 | libschroedinger_free_frame); |
| 426 | |
| 427 | |
| 428 | /* Free the encoder buffer. */ |
| 429 | if (p_schro_params->enc_buf_size) |
| 430 | av_freep(&p_schro_params->enc_buf); |
| 431 | |
| 432 | /* Free the video format structure. */ |
| 433 | av_freep(&p_schro_params->format); |
| 434 | |
| 435 | av_frame_free(&avctx->coded_frame); |
| 436 | |
| 437 | return 0; |
| 438 | } |
| 439 | |
| 440 | |
| 441 | AVCodec ff_libschroedinger_encoder = { |
| 442 | .name = "libschroedinger", |
| 443 | .long_name = NULL_IF_CONFIG_SMALL("libschroedinger Dirac 2.2"), |
| 444 | .type = AVMEDIA_TYPE_VIDEO, |
| 445 | .id = AV_CODEC_ID_DIRAC, |
| 446 | .priv_data_size = sizeof(SchroEncoderParams), |
| 447 | .init = libschroedinger_encode_init, |
| 448 | .encode2 = libschroedinger_encode_frame, |
| 449 | .close = libschroedinger_encode_close, |
| 450 | .capabilities = CODEC_CAP_DELAY, |
| 451 | .pix_fmts = (const enum AVPixelFormat[]){ |
| 452 | AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_NONE |
| 453 | }, |
| 454 | }; |