• Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

libavcodec/libschroedingerenc.c

Go to the documentation of this file.
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 };

Generated on Fri Sep 16 2011 17:17:38 for FFmpeg by  doxygen 1.7.1