00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 #include <stdio.h>
00023 #include <stdlib.h>
00024 #include <string.h>
00025 #include <math.h>
00026 #include <stdint.h>
00027 #include <float.h>
00028 #include <xavs.h>
00029 #include "avcodec.h"
00030 #include "internal.h"
00031 #include "libavutil/internal.h"
00032 #include "libavutil/mem.h"
00033 #include "libavutil/opt.h"
00034 
00035 #define END_OF_STREAM 0x001
00036 
00037 #define XAVS_PART_I8X8 0x002 
00038 #define XAVS_PART_P8X8 0x010 
00039 #define XAVS_PART_B8X8 0x100 
00040 
00041 typedef struct XavsContext {
00042     AVClass        *class;
00043     xavs_param_t    params;
00044     xavs_t         *enc;
00045     xavs_picture_t  pic;
00046     uint8_t        *sei;
00047     int             sei_size;
00048     AVFrame         out_pic;
00049     int             end_of_stream;
00050     float crf;
00051     int cqp;
00052     int b_bias;
00053     float cplxblur;
00054     int direct_pred;
00055     int aud;
00056     int fast_pskip;
00057     int mbtree;
00058     int mixed_refs;
00059 
00060     int64_t *pts_buffer;
00061     int out_frame_count;
00062 } XavsContext;
00063 
00064 static void XAVS_log(void *p, int level, const char *fmt, va_list args)
00065 {
00066     static const int level_map[] = {
00067         [XAVS_LOG_ERROR]   = AV_LOG_ERROR,
00068         [XAVS_LOG_WARNING] = AV_LOG_WARNING,
00069         [XAVS_LOG_INFO]    = AV_LOG_INFO,
00070         [XAVS_LOG_DEBUG]   = AV_LOG_DEBUG
00071     };
00072 
00073     if (level < 0 || level > XAVS_LOG_DEBUG)
00074         return;
00075 
00076     av_vlog(p, level_map[level], fmt, args);
00077 }
00078 
00079 static int encode_nals(AVCodecContext *ctx, AVPacket *pkt,
00080                        xavs_nal_t *nals, int nnal)
00081 {
00082     XavsContext *x4 = ctx->priv_data;
00083     uint8_t *p;
00084     int i, s, ret, size = x4->sei_size + FF_MIN_BUFFER_SIZE;
00085 
00086     if (!nnal)
00087         return 0;
00088 
00089     for (i = 0; i < nnal; i++)
00090         size += nals[i].i_payload;
00091 
00092     if ((ret = ff_alloc_packet2(ctx, pkt, size)) < 0)
00093         return ret;
00094     p = pkt->data;
00095 
00096     
00097     if (x4->sei_size > 0 && nnal > 0) {
00098         memcpy(p, x4->sei, x4->sei_size);
00099         p += x4->sei_size;
00100         x4->sei_size = 0;
00101     }
00102 
00103     for (i = 0; i < nnal; i++) {
00104         s = xavs_nal_encode(p, &size, 1, nals + i);
00105         if (s < 0)
00106             return -1;
00107         p += s;
00108     }
00109     pkt->size = p - pkt->data;
00110 
00111     return 1;
00112 }
00113 
00114 static int XAVS_frame(AVCodecContext *ctx, AVPacket *pkt,
00115                       const AVFrame *frame, int *got_packet)
00116 {
00117     XavsContext *x4 = ctx->priv_data;
00118     xavs_nal_t *nal;
00119     int nnal, i, ret;
00120     xavs_picture_t pic_out;
00121 
00122     x4->pic.img.i_csp   = XAVS_CSP_I420;
00123     x4->pic.img.i_plane = 3;
00124 
00125     if (frame) {
00126        for (i = 0; i < 3; i++) {
00127             x4->pic.img.plane[i] = frame->data[i];
00128             x4->pic.img.i_stride[i] = frame->linesize[i];
00129        }
00130 
00131         x4->pic.i_pts  = frame->pts;
00132         x4->pic.i_type = XAVS_TYPE_AUTO;
00133         x4->pts_buffer[ctx->frame_number % (ctx->max_b_frames+1)] = frame->pts;
00134     }
00135 
00136     if (xavs_encoder_encode(x4->enc, &nal, &nnal,
00137                             frame? &x4->pic: NULL, &pic_out) < 0)
00138     return -1;
00139 
00140     ret = encode_nals(ctx, pkt, nal, nnal);
00141 
00142     if (ret < 0)
00143         return -1;
00144 
00145     if (!ret) {
00146         if (!frame && !(x4->end_of_stream)) {
00147             if ((ret = ff_alloc_packet2(ctx, pkt, 4)) < 0)
00148                 return ret;
00149 
00150             pkt->data[0] = 0x0;
00151             pkt->data[1] = 0x0;
00152             pkt->data[2] = 0x01;
00153             pkt->data[3] = 0xb1;
00154             pkt->dts = 2*x4->pts_buffer[(x4->out_frame_count-1)%(ctx->max_b_frames+1)] -
00155                        x4->pts_buffer[(x4->out_frame_count-2)%(ctx->max_b_frames+1)];
00156             x4->end_of_stream = END_OF_STREAM;
00157             *got_packet = 1;
00158         }
00159         return 0;
00160     }
00161 
00162     x4->out_pic.pts = pic_out.i_pts;
00163     pkt->pts = pic_out.i_pts;
00164     if (ctx->has_b_frames) {
00165         if (!x4->out_frame_count)
00166             pkt->dts = pkt->pts - (x4->pts_buffer[1] - x4->pts_buffer[0]);
00167         else
00168             pkt->dts = x4->pts_buffer[(x4->out_frame_count-1)%(ctx->max_b_frames+1)];
00169     } else
00170         pkt->dts = pkt->pts;
00171 
00172     switch (pic_out.i_type) {
00173     case XAVS_TYPE_IDR:
00174     case XAVS_TYPE_I:
00175         x4->out_pic.pict_type = AV_PICTURE_TYPE_I;
00176         break;
00177     case XAVS_TYPE_P:
00178         x4->out_pic.pict_type = AV_PICTURE_TYPE_P;
00179         break;
00180     case XAVS_TYPE_B:
00181     case XAVS_TYPE_BREF:
00182         x4->out_pic.pict_type = AV_PICTURE_TYPE_B;
00183         break;
00184     }
00185 
00186     
00187     
00188     if (pic_out.i_type == XAVS_TYPE_I) {
00189         x4->out_pic.key_frame = 1;
00190         pkt->flags |= AV_PKT_FLAG_KEY;
00191     }
00192 
00193     x4->out_pic.quality   = (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA;
00194 
00195     x4->out_frame_count++;
00196     *got_packet = ret;
00197     return 0;
00198 }
00199 
00200 static av_cold int XAVS_close(AVCodecContext *avctx)
00201 {
00202     XavsContext *x4 = avctx->priv_data;
00203 
00204     av_freep(&avctx->extradata);
00205     av_free(x4->sei);
00206     av_freep(&x4->pts_buffer);
00207 
00208     if (x4->enc)
00209         xavs_encoder_close(x4->enc);
00210 
00211     return 0;
00212 }
00213 
00214 static av_cold int XAVS_init(AVCodecContext *avctx)
00215 {
00216     XavsContext *x4 = avctx->priv_data;
00217 
00218     x4->sei_size = 0;
00219     xavs_param_default(&x4->params);
00220 
00221     x4->params.pf_log               = XAVS_log;
00222     x4->params.p_log_private        = avctx;
00223     x4->params.i_keyint_max         = avctx->gop_size;
00224     if (avctx->bit_rate) {
00225         x4->params.rc.i_bitrate   = avctx->bit_rate / 1000;
00226         x4->params.rc.i_rc_method = XAVS_RC_ABR;
00227     }
00228     x4->params.rc.i_vbv_buffer_size = avctx->rc_buffer_size / 1000;
00229     x4->params.rc.i_vbv_max_bitrate = avctx->rc_max_rate    / 1000;
00230     x4->params.rc.b_stat_write      = avctx->flags & CODEC_FLAG_PASS1;
00231     if (avctx->flags & CODEC_FLAG_PASS2) {
00232         x4->params.rc.b_stat_read = 1;
00233     } else {
00234         if (x4->crf >= 0) {
00235             x4->params.rc.i_rc_method   = XAVS_RC_CRF;
00236             x4->params.rc.f_rf_constant = x4->crf;
00237         } else if (x4->cqp >= 0) {
00238             x4->params.rc.i_rc_method   = XAVS_RC_CQP;
00239             x4->params.rc.i_qp_constant = x4->cqp;
00240         }
00241     }
00242 
00243     if (x4->aud >= 0)
00244         x4->params.b_aud                      = x4->aud;
00245     if (x4->mbtree >= 0)
00246         x4->params.rc.b_mb_tree               = x4->mbtree;
00247     if (x4->direct_pred >= 0)
00248         x4->params.analyse.i_direct_mv_pred   = x4->direct_pred;
00249     if (x4->fast_pskip >= 0)
00250         x4->params.analyse.b_fast_pskip       = x4->fast_pskip;
00251     if (x4->mixed_refs >= 0)
00252         x4->params.analyse.b_mixed_references = x4->mixed_refs;
00253     if (x4->b_bias != INT_MIN)
00254         x4->params.i_bframe_bias              = x4->b_bias;
00255     if (x4->cplxblur >= 0)
00256         x4->params.rc.f_complexity_blur = x4->cplxblur;
00257 
00258     x4->params.i_bframe          = avctx->max_b_frames;
00259     
00260     x4->params.b_cabac           = 0;
00261 
00262     x4->params.i_bframe_adaptive = avctx->b_frame_strategy;
00263 
00264     avctx->has_b_frames          = !!avctx->max_b_frames;
00265 
00266     
00267     
00268     x4->params.i_keyint_min      = avctx->keyint_min;
00269     if (x4->params.i_keyint_min > x4->params.i_keyint_max)
00270         x4->params.i_keyint_min = x4->params.i_keyint_max;
00271 
00272     x4->params.i_scenecut_threshold        = avctx->scenechange_threshold;
00273 
00274    
00275 
00276     x4->params.rc.i_qp_min                 = avctx->qmin;
00277     x4->params.rc.i_qp_max                 = avctx->qmax;
00278     x4->params.rc.i_qp_step                = avctx->max_qdiff;
00279 
00280     x4->params.rc.f_qcompress       = avctx->qcompress; 
00281     x4->params.rc.f_qblur           = avctx->qblur;     
00282 
00283     x4->params.i_frame_reference    = avctx->refs;
00284 
00285     x4->params.i_width              = avctx->width;
00286     x4->params.i_height             = avctx->height;
00287     x4->params.vui.i_sar_width      = avctx->sample_aspect_ratio.num;
00288     x4->params.vui.i_sar_height     = avctx->sample_aspect_ratio.den;
00289     
00290     x4->params.i_fps_num            = avctx->time_base.den;
00291     x4->params.i_fps_den            = avctx->time_base.num;
00292     x4->params.analyse.inter        = XAVS_ANALYSE_I8x8 |XAVS_ANALYSE_PSUB16x16| XAVS_ANALYSE_BSUB16x16;
00293 
00294     switch (avctx->me_method) {
00295          case  ME_EPZS:
00296                x4->params.analyse.i_me_method = XAVS_ME_DIA;
00297                break;
00298          case  ME_HEX:
00299                x4->params.analyse.i_me_method = XAVS_ME_HEX;
00300                break;
00301          case  ME_UMH:
00302                x4->params.analyse.i_me_method = XAVS_ME_UMH;
00303                break;
00304          case  ME_FULL:
00305                x4->params.analyse.i_me_method = XAVS_ME_ESA;
00306                break;
00307          case  ME_TESA:
00308                x4->params.analyse.i_me_method = XAVS_ME_TESA;
00309                break;
00310          default:
00311                x4->params.analyse.i_me_method = XAVS_ME_HEX;
00312     }
00313 
00314     x4->params.analyse.i_me_range = avctx->me_range;
00315     x4->params.analyse.i_subpel_refine    = avctx->me_subpel_quality;
00316 
00317     x4->params.analyse.b_chroma_me        = avctx->me_cmp & FF_CMP_CHROMA;
00318     
00319     x4->params.analyse.b_transform_8x8    = 1; 
00320 
00321     x4->params.analyse.i_trellis          = avctx->trellis;
00322     x4->params.analyse.i_noise_reduction  = avctx->noise_reduction;
00323 
00324     if (avctx->level > 0)
00325         x4->params.i_level_idc = avctx->level;
00326 
00327     x4->params.rc.f_rate_tolerance =
00328         (float)avctx->bit_rate_tolerance/avctx->bit_rate;
00329 
00330     if ((avctx->rc_buffer_size) &&
00331         (avctx->rc_initial_buffer_occupancy <= avctx->rc_buffer_size)) {
00332         x4->params.rc.f_vbv_buffer_init =
00333             (float)avctx->rc_initial_buffer_occupancy / avctx->rc_buffer_size;
00334     } else
00335         x4->params.rc.f_vbv_buffer_init = 0.9;
00336 
00337     
00338     
00339     x4->params.rc.f_ip_factor             = 1 / fabs(avctx->i_quant_factor);
00340     x4->params.rc.f_pb_factor             = avctx->b_quant_factor;
00341     x4->params.analyse.i_chroma_qp_offset = avctx->chromaoffset;
00342 
00343     x4->params.analyse.b_psnr = avctx->flags & CODEC_FLAG_PSNR;
00344     x4->params.i_log_level    = XAVS_LOG_DEBUG;
00345     x4->params.i_threads      = avctx->thread_count;
00346     x4->params.b_interlaced   = avctx->flags & CODEC_FLAG_INTERLACED_DCT;
00347 
00348     if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER)
00349         x4->params.b_repeat_headers = 0;
00350 
00351     x4->enc = xavs_encoder_open(&x4->params);
00352     if (!x4->enc)
00353         return -1;
00354 
00355     if (!(x4->pts_buffer = av_mallocz((avctx->max_b_frames+1) * sizeof(*x4->pts_buffer))))
00356         return AVERROR(ENOMEM);
00357 
00358     avctx->coded_frame = &x4->out_pic;
00359     
00360     
00361     if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) {
00362         xavs_nal_t *nal;
00363         int nnal, s, i, size;
00364         uint8_t *p;
00365 
00366         s = xavs_encoder_headers(x4->enc, &nal, &nnal);
00367 
00368         avctx->extradata = p = av_malloc(s);
00369         for (i = 0; i < nnal; i++) {
00370             
00371             if (nal[i].i_type == NAL_SEI) {
00372                 x4->sei = av_malloc( 5 + nal[i].i_payload * 4 / 3 );
00373                 if (xavs_nal_encode(x4->sei, &x4->sei_size, 1, nal + i) < 0)
00374                     return -1;
00375 
00376                 continue;
00377             }
00378             size = xavs_nal_encode(p, &s, 1, nal + i);
00379             if (size < 0)
00380                 return -1;
00381             p += size;
00382         }
00383         avctx->extradata_size = p - avctx->extradata;
00384     }
00385     return 0;
00386 }
00387 
00388 #define OFFSET(x) offsetof(XavsContext, x)
00389 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
00390 static const AVOption options[] = {
00391     { "crf",           "Select the quality for constant quality mode",    OFFSET(crf),           AV_OPT_TYPE_FLOAT,  {.dbl = -1 }, -1, FLT_MAX, VE },
00392     { "qp",            "Constant quantization parameter rate control method",OFFSET(cqp),        AV_OPT_TYPE_INT,    {.i64 = -1 }, -1, INT_MAX, VE },
00393     { "b-bias",        "Influences how often B-frames are used",          OFFSET(b_bias),        AV_OPT_TYPE_INT,    {.i64 = INT_MIN}, INT_MIN, INT_MAX, VE },
00394     { "cplxblur",      "Reduce fluctuations in QP (before curve compression)", OFFSET(cplxblur), AV_OPT_TYPE_FLOAT,  {.dbl = -1 }, -1, FLT_MAX, VE},
00395     { "direct-pred",   "Direct MV prediction mode",                       OFFSET(direct_pred),   AV_OPT_TYPE_INT,    {.i64 = -1 }, -1, INT_MAX, VE, "direct-pred" },
00396     { "none",          NULL,      0,    AV_OPT_TYPE_CONST, { .i64 = XAVS_DIRECT_PRED_NONE },     0, 0, VE, "direct-pred" },
00397     { "spatial",       NULL,      0,    AV_OPT_TYPE_CONST, { .i64 = XAVS_DIRECT_PRED_SPATIAL },  0, 0, VE, "direct-pred" },
00398     { "temporal",      NULL,      0,    AV_OPT_TYPE_CONST, { .i64 = XAVS_DIRECT_PRED_TEMPORAL }, 0, 0, VE, "direct-pred" },
00399     { "auto",          NULL,      0,    AV_OPT_TYPE_CONST, { .i64 = XAVS_DIRECT_PRED_AUTO },     0, 0, VE, "direct-pred" },
00400     { "aud",           "Use access unit delimiters.",                     OFFSET(aud),           AV_OPT_TYPE_INT,    {.i64 = -1 }, -1, 1, VE},
00401     { "mbtree",        "Use macroblock tree ratecontrol.",                OFFSET(mbtree),        AV_OPT_TYPE_INT,    {.i64 = -1 }, -1, 1, VE},
00402     { "mixed-refs",    "One reference per partition, as opposed to one reference per macroblock", OFFSET(mixed_refs), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, VE },
00403     { "fast-pskip",    NULL,                                              OFFSET(fast_pskip),    AV_OPT_TYPE_INT,    {.i64 = -1 }, -1, 1, VE},
00404     { NULL },
00405 };
00406 
00407 static const AVClass class = {
00408     .class_name = "libxavs",
00409     .item_name  = av_default_item_name,
00410     .option     = options,
00411     .version    = LIBAVUTIL_VERSION_INT,
00412 };
00413 
00414 static const AVCodecDefault xavs_defaults[] = {
00415     { "b",                "0" },
00416     { NULL },
00417 };
00418 
00419 AVCodec ff_libxavs_encoder = {
00420     .name           = "libxavs",
00421     .type           = AVMEDIA_TYPE_VIDEO,
00422     .id             = AV_CODEC_ID_CAVS,
00423     .priv_data_size = sizeof(XavsContext),
00424     .init           = XAVS_init,
00425     .encode2        = XAVS_frame,
00426     .close          = XAVS_close,
00427     .capabilities   = CODEC_CAP_DELAY | CODEC_CAP_AUTO_THREADS,
00428     .pix_fmts       = (const enum PixelFormat[]) { PIX_FMT_YUV420P, PIX_FMT_NONE },
00429     .long_name      = NULL_IF_CONFIG_SMALL("libxavs Chinese AVS (Audio Video Standard)"),
00430     .priv_class     = &class,
00431     .defaults       = xavs_defaults,
00432 };