Libav
|
00001 /* 00002 * Dirac encoder support via Schroedinger libraries 00003 * Copyright (c) 2008 BBC, Anuradha Suraparaju <asuraparaju at gmail dot com > 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * FFmpeg is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 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 00041 00043 typedef struct FfmpegSchroEncoderParams { 00045 SchroVideoFormat *format; 00046 00048 SchroFrameFormat frame_format; 00049 00051 AVFrame picture; 00052 00054 int frame_size; 00055 00057 SchroEncoder* encoder; 00058 00060 unsigned char *enc_buf; 00061 00063 int enc_buf_size; 00064 00066 FfmpegDiracSchroQueue enc_frame_queue; 00067 00069 int eos_signalled; 00070 00072 int eos_pulled; 00073 } FfmpegSchroEncoderParams; 00074 00078 static int SetSchroChromaFormat(AVCodecContext *avccontext) 00079 { 00080 int num_formats = sizeof(ffmpeg_schro_pixel_format_map) / 00081 sizeof(ffmpeg_schro_pixel_format_map[0]); 00082 int idx; 00083 00084 FfmpegSchroEncoderParams* p_schro_params = avccontext->priv_data; 00085 00086 for (idx = 0; idx < num_formats; ++idx) { 00087 if (ffmpeg_schro_pixel_format_map[idx].ff_pix_fmt == 00088 avccontext->pix_fmt) { 00089 p_schro_params->format->chroma_format = 00090 ffmpeg_schro_pixel_format_map[idx].schro_pix_fmt; 00091 return 0; 00092 } 00093 } 00094 00095 av_log(avccontext, AV_LOG_ERROR, 00096 "This codec currently only supports planar YUV 4:2:0, 4:2:2" 00097 " and 4:4:4 formats.\n"); 00098 00099 return -1; 00100 } 00101 00102 static int libschroedinger_encode_init(AVCodecContext *avccontext) 00103 { 00104 FfmpegSchroEncoderParams* p_schro_params = avccontext->priv_data; 00105 SchroVideoFormatEnum preset; 00106 00107 /* Initialize the libraries that libschroedinger depends on. */ 00108 schro_init(); 00109 00110 /* Create an encoder object. */ 00111 p_schro_params->encoder = schro_encoder_new(); 00112 00113 if (!p_schro_params->encoder) { 00114 av_log(avccontext, AV_LOG_ERROR, 00115 "Unrecoverable Error: schro_encoder_new failed. "); 00116 return -1; 00117 } 00118 00119 /* Initialize the format. */ 00120 preset = ff_get_schro_video_format_preset(avccontext); 00121 p_schro_params->format = 00122 schro_encoder_get_video_format(p_schro_params->encoder); 00123 schro_video_format_set_std_video_format(p_schro_params->format, preset); 00124 p_schro_params->format->width = avccontext->width; 00125 p_schro_params->format->height = avccontext->height; 00126 00127 if (SetSchroChromaFormat(avccontext) == -1) 00128 return -1; 00129 00130 if (ff_get_schro_frame_format(p_schro_params->format->chroma_format, 00131 &p_schro_params->frame_format) == -1) { 00132 av_log(avccontext, AV_LOG_ERROR, 00133 "This codec currently supports only planar YUV 4:2:0, 4:2:2" 00134 " and 4:4:4 formats.\n"); 00135 return -1; 00136 } 00137 00138 p_schro_params->format->frame_rate_numerator = avccontext->time_base.den; 00139 p_schro_params->format->frame_rate_denominator = avccontext->time_base.num; 00140 00141 p_schro_params->frame_size = avpicture_get_size(avccontext->pix_fmt, 00142 avccontext->width, 00143 avccontext->height); 00144 00145 avccontext->coded_frame = &p_schro_params->picture; 00146 00147 if (!avccontext->gop_size) { 00148 schro_encoder_setting_set_double(p_schro_params->encoder, 00149 "gop_structure", 00150 SCHRO_ENCODER_GOP_INTRA_ONLY); 00151 00152 if (avccontext->coder_type == FF_CODER_TYPE_VLC) 00153 schro_encoder_setting_set_double(p_schro_params->encoder, 00154 "enable_noarith", 1); 00155 } else { 00156 schro_encoder_setting_set_double(p_schro_params->encoder, 00157 "gop_structure", 00158 SCHRO_ENCODER_GOP_BIREF); 00159 avccontext->has_b_frames = 1; 00160 } 00161 00162 /* FIXME - Need to handle SCHRO_ENCODER_RATE_CONTROL_LOW_DELAY. */ 00163 if (avccontext->flags & CODEC_FLAG_QSCALE) { 00164 if (!avccontext->global_quality) { 00165 /* lossless coding */ 00166 schro_encoder_setting_set_double(p_schro_params->encoder, 00167 "rate_control", 00168 SCHRO_ENCODER_RATE_CONTROL_LOSSLESS); 00169 } else { 00170 int noise_threshold; 00171 schro_encoder_setting_set_double(p_schro_params->encoder, 00172 "rate_control", 00173 SCHRO_ENCODER_RATE_CONTROL_CONSTANT_NOISE_THRESHOLD); 00174 00175 noise_threshold = avccontext->global_quality / FF_QP2LAMBDA; 00176 if (noise_threshold > 100) 00177 noise_threshold = 100; 00178 schro_encoder_setting_set_double(p_schro_params->encoder, 00179 "noise_threshold", 00180 noise_threshold); 00181 } 00182 } else { 00183 schro_encoder_setting_set_double(p_schro_params->encoder, 00184 "rate_control", 00185 SCHRO_ENCODER_RATE_CONTROL_CONSTANT_BITRATE); 00186 00187 schro_encoder_setting_set_double(p_schro_params->encoder, 00188 "bitrate", 00189 avccontext->bit_rate); 00190 00191 } 00192 00193 if (avccontext->flags & CODEC_FLAG_INTERLACED_ME) 00194 /* All material can be coded as interlaced or progressive 00195 irrespective of the type of source material. */ 00196 schro_encoder_setting_set_double(p_schro_params->encoder, 00197 "interlaced_coding", 1); 00198 00199 /* FIXME: Signal range hardcoded to 8-bit data until both libschroedinger 00200 * and libdirac support other bit-depth data. */ 00201 schro_video_format_set_std_signal_range(p_schro_params->format, 00202 SCHRO_SIGNAL_RANGE_8BIT_VIDEO); 00203 00204 /* Set the encoder format. */ 00205 schro_encoder_set_video_format(p_schro_params->encoder, 00206 p_schro_params->format); 00207 00208 /* Set the debug level. */ 00209 schro_debug_set_level(avccontext->debug); 00210 00211 schro_encoder_start(p_schro_params->encoder); 00212 00213 /* Initialize the encoded frame queue. */ 00214 ff_dirac_schro_queue_init(&p_schro_params->enc_frame_queue); 00215 return 0; 00216 } 00217 00218 static SchroFrame *libschroedinger_frame_from_data(AVCodecContext *avccontext, 00219 void *in_data) 00220 { 00221 FfmpegSchroEncoderParams* p_schro_params = avccontext->priv_data; 00222 SchroFrame *in_frame; 00223 /* Input line size may differ from what the codec supports. Especially 00224 * when transcoding from one format to another. So use avpicture_layout 00225 * to copy the frame. */ 00226 in_frame = ff_create_schro_frame(avccontext, p_schro_params->frame_format); 00227 00228 if (in_frame) 00229 avpicture_layout((AVPicture *)in_data, avccontext->pix_fmt, 00230 avccontext->width, avccontext->height, 00231 in_frame->components[0].data, 00232 p_schro_params->frame_size); 00233 00234 return in_frame; 00235 } 00236 00237 static void SchroedingerFreeFrame(void *data) 00238 { 00239 FfmpegDiracSchroEncodedFrame *enc_frame = data; 00240 00241 av_freep(&(enc_frame->p_encbuf)); 00242 av_free(enc_frame); 00243 } 00244 00245 static int libschroedinger_encode_frame(AVCodecContext *avccontext, 00246 unsigned char *frame, 00247 int buf_size, void *data) 00248 { 00249 int enc_size = 0; 00250 FfmpegSchroEncoderParams* p_schro_params = avccontext->priv_data; 00251 SchroEncoder *encoder = p_schro_params->encoder; 00252 struct FfmpegDiracSchroEncodedFrame* p_frame_output = NULL; 00253 int go = 1; 00254 SchroBuffer *enc_buf; 00255 int presentation_frame; 00256 int parse_code; 00257 int last_frame_in_sequence = 0; 00258 00259 if (!data) { 00260 /* Push end of sequence if not already signalled. */ 00261 if (!p_schro_params->eos_signalled) { 00262 schro_encoder_end_of_stream(encoder); 00263 p_schro_params->eos_signalled = 1; 00264 } 00265 } else { 00266 /* Allocate frame data to schro input buffer. */ 00267 SchroFrame *in_frame = libschroedinger_frame_from_data(avccontext, 00268 data); 00269 /* Load next frame. */ 00270 schro_encoder_push_frame(encoder, in_frame); 00271 } 00272 00273 if (p_schro_params->eos_pulled) 00274 go = 0; 00275 00276 /* Now check to see if we have any output from the encoder. */ 00277 while (go) { 00278 SchroStateEnum state; 00279 state = schro_encoder_wait(encoder); 00280 switch (state) { 00281 case SCHRO_STATE_HAVE_BUFFER: 00282 case SCHRO_STATE_END_OF_STREAM: 00283 enc_buf = schro_encoder_pull(encoder, &presentation_frame); 00284 assert(enc_buf->length > 0); 00285 assert(enc_buf->length <= buf_size); 00286 parse_code = enc_buf->data[4]; 00287 00288 /* All non-frame data is prepended to actual frame data to 00289 * be able to set the pts correctly. So we don't write data 00290 * to the frame output queue until we actually have a frame 00291 */ 00292 p_schro_params->enc_buf = av_realloc(p_schro_params->enc_buf, 00293 p_schro_params->enc_buf_size + enc_buf->length); 00294 00295 memcpy(p_schro_params->enc_buf + p_schro_params->enc_buf_size, 00296 enc_buf->data, enc_buf->length); 00297 p_schro_params->enc_buf_size += enc_buf->length; 00298 00299 00300 if (state == SCHRO_STATE_END_OF_STREAM) { 00301 p_schro_params->eos_pulled = 1; 00302 go = 0; 00303 } 00304 00305 if (!SCHRO_PARSE_CODE_IS_PICTURE(parse_code)) { 00306 schro_buffer_unref(enc_buf); 00307 break; 00308 } 00309 00310 /* Create output frame. */ 00311 p_frame_output = av_mallocz(sizeof(FfmpegDiracSchroEncodedFrame)); 00312 /* Set output data. */ 00313 p_frame_output->size = p_schro_params->enc_buf_size; 00314 p_frame_output->p_encbuf = p_schro_params->enc_buf; 00315 if (SCHRO_PARSE_CODE_IS_INTRA(parse_code) && 00316 SCHRO_PARSE_CODE_IS_REFERENCE(parse_code)) 00317 p_frame_output->key_frame = 1; 00318 00319 /* Parse the coded frame number from the bitstream. Bytes 14 00320 * through 17 represesent the frame number. */ 00321 p_frame_output->frame_num = (enc_buf->data[13] << 24) + 00322 (enc_buf->data[14] << 16) + 00323 (enc_buf->data[15] << 8) + 00324 enc_buf->data[16]; 00325 00326 ff_dirac_schro_queue_push_back(&p_schro_params->enc_frame_queue, 00327 p_frame_output); 00328 p_schro_params->enc_buf_size = 0; 00329 p_schro_params->enc_buf = NULL; 00330 00331 schro_buffer_unref(enc_buf); 00332 00333 break; 00334 00335 case SCHRO_STATE_NEED_FRAME: 00336 go = 0; 00337 break; 00338 00339 case SCHRO_STATE_AGAIN: 00340 break; 00341 00342 default: 00343 av_log(avccontext, AV_LOG_ERROR, "Unknown Schro Encoder state\n"); 00344 return -1; 00345 } 00346 } 00347 00348 /* Copy 'next' frame in queue. */ 00349 00350 if (p_schro_params->enc_frame_queue.size == 1 && 00351 p_schro_params->eos_pulled) 00352 last_frame_in_sequence = 1; 00353 00354 p_frame_output = ff_dirac_schro_queue_pop(&p_schro_params->enc_frame_queue); 00355 00356 if (!p_frame_output) 00357 return 0; 00358 00359 memcpy(frame, p_frame_output->p_encbuf, p_frame_output->size); 00360 avccontext->coded_frame->key_frame = p_frame_output->key_frame; 00361 /* Use the frame number of the encoded frame as the pts. It is OK to 00362 * do so since Dirac is a constant frame rate codec. It expects input 00363 * to be of constant frame rate. */ 00364 avccontext->coded_frame->pts = p_frame_output->frame_num; 00365 enc_size = p_frame_output->size; 00366 00367 /* Append the end of sequence information to the last frame in the 00368 * sequence. */ 00369 if (last_frame_in_sequence && p_schro_params->enc_buf_size > 0) { 00370 memcpy(frame + enc_size, p_schro_params->enc_buf, 00371 p_schro_params->enc_buf_size); 00372 enc_size += p_schro_params->enc_buf_size; 00373 av_freep(&p_schro_params->enc_buf); 00374 p_schro_params->enc_buf_size = 0; 00375 } 00376 00377 /* free frame */ 00378 SchroedingerFreeFrame(p_frame_output); 00379 00380 return enc_size; 00381 } 00382 00383 00384 static int libschroedinger_encode_close(AVCodecContext *avccontext) 00385 { 00386 00387 FfmpegSchroEncoderParams* p_schro_params = avccontext->priv_data; 00388 00389 /* Close the encoder. */ 00390 schro_encoder_free(p_schro_params->encoder); 00391 00392 /* Free data in the output frame queue. */ 00393 ff_dirac_schro_queue_free(&p_schro_params->enc_frame_queue, 00394 SchroedingerFreeFrame); 00395 00396 00397 /* Free the encoder buffer. */ 00398 if (p_schro_params->enc_buf_size) 00399 av_freep(&p_schro_params->enc_buf); 00400 00401 /* Free the video format structure. */ 00402 av_freep(&p_schro_params->format); 00403 00404 return 0; 00405 } 00406 00407 00408 AVCodec libschroedinger_encoder = { 00409 "libschroedinger", 00410 AVMEDIA_TYPE_VIDEO, 00411 CODEC_ID_DIRAC, 00412 sizeof(FfmpegSchroEncoderParams), 00413 libschroedinger_encode_init, 00414 libschroedinger_encode_frame, 00415 libschroedinger_encode_close, 00416 .capabilities = CODEC_CAP_DELAY, 00417 .pix_fmts = (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_YUV444P, PIX_FMT_NONE}, 00418 .long_name = NULL_IF_CONFIG_SMALL("libschroedinger Dirac 2.2"), 00419 };