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

Generated on Tue Nov 4 2014 12:59:22 for ffmpeg by  doxygen 1.7.1