~siretart/x264/trunk

« back to all changes in this revision

Viewing changes to encoder/encoder.c

  • Committer: Henrik Gramner
  • Author(s): Emanuele Ruffaldi
  • Date: 2018-08-06 21:24:12 UTC
  • Revision ID: git-v1:698c5a32e63a3ed6b976ed196abe479efd78530b
4:0:0 (monochrome) encoding support

Virtually zero increase in compression efficiency compared to 4:2:0 with empty
chroma planes. Performance is better though, especially with fast settings.

Show diffs side-by-side

added added

removed removed

Lines of Context:
100
100
        for( int p = 0; p < (CHROMA444 ? 3 : 1); p++ )
101
101
            for( int y = 0; y < h->param.i_height; y++ )
102
102
                fwrite( &h->fdec->plane[p][y*h->fdec->i_stride[p]], sizeof(pixel), h->param.i_width, f );
103
 
        if( !CHROMA444 )
 
103
        if( CHROMA_FORMAT == CHROMA_420 || CHROMA_FORMAT == CHROMA_422 )
104
104
        {
105
105
            int cw = h->param.i_width>>1;
106
106
            int ch = h->param.i_height>>CHROMA_V_SHIFT;
293
293
    {
294
294
        sh->b_weighted_pred = sh->weight[0][0].weightfn || sh->weight[0][1].weightfn || sh->weight[0][2].weightfn;
295
295
        /* pred_weight_table() */
296
 
        bs_write_ue( s, sh->weight[0][0].i_denom );
297
 
        bs_write_ue( s, sh->weight[0][1].i_denom );
 
296
        bs_write_ue( s, sh->weight[0][0].i_denom ); /* luma_log2_weight_denom */
 
297
        if( sh->sps->i_chroma_format_idc )
 
298
            bs_write_ue( s, sh->weight[0][1].i_denom ); /* chroma_log2_weight_denom */
298
299
        for( int i = 0; i < sh->i_num_ref_idx_l0_active; i++ )
299
300
        {
300
301
            int luma_weight_l0_flag = !!sh->weight[i][0].weightfn;
301
 
            int chroma_weight_l0_flag = !!sh->weight[i][1].weightfn || !!sh->weight[i][2].weightfn;
302
302
            bs_write1( s, luma_weight_l0_flag );
303
303
            if( luma_weight_l0_flag )
304
304
            {
305
305
                bs_write_se( s, sh->weight[i][0].i_scale );
306
306
                bs_write_se( s, sh->weight[i][0].i_offset );
307
307
            }
308
 
            bs_write1( s, chroma_weight_l0_flag );
309
 
            if( chroma_weight_l0_flag )
 
308
            if( sh->sps->i_chroma_format_idc )
310
309
            {
311
 
                for( int j = 1; j < 3; j++ )
 
310
                int chroma_weight_l0_flag = sh->weight[i][1].weightfn || sh->weight[i][2].weightfn;
 
311
                bs_write1( s, chroma_weight_l0_flag );
 
312
                if( chroma_weight_l0_flag )
312
313
                {
313
 
                    bs_write_se( s, sh->weight[i][j].i_scale );
314
 
                    bs_write_se( s, sh->weight[i][j].i_offset );
 
314
                    for( int j = 1; j < 3; j++ )
 
315
                    {
 
316
                        bs_write_se( s, sh->weight[i][j].i_scale );
 
317
                        bs_write_se( s, sh->weight[i][j].i_offset );
 
318
                    }
315
319
                }
316
320
            }
317
321
        }
475
479
 
476
480
    int i_csp = h->param.i_csp & X264_CSP_MASK;
477
481
#if X264_CHROMA_FORMAT
478
 
    if( CHROMA_FORMAT != CHROMA_420 && i_csp >= X264_CSP_I420 && i_csp < X264_CSP_I422 )
 
482
    if( CHROMA_FORMAT != CHROMA_400 && i_csp == X264_CSP_I400 )
 
483
    {
 
484
        x264_log( h, X264_LOG_ERROR, "not compiled with 4:0:0 support\n" );
 
485
        return -1;
 
486
    }
 
487
    else if( CHROMA_FORMAT != CHROMA_420 && i_csp >= X264_CSP_I420 && i_csp < X264_CSP_I422 )
479
488
    {
480
489
        x264_log( h, X264_LOG_ERROR, "not compiled with 4:2:0 support\n" );
481
490
        return -1;
493
502
#endif
494
503
    if( i_csp <= X264_CSP_NONE || i_csp >= X264_CSP_MAX )
495
504
    {
496
 
        x264_log( h, X264_LOG_ERROR, "invalid CSP (only I420/YV12/NV12/NV21/I422/YV16/NV16/YUYV/UYVY/"
 
505
        x264_log( h, X264_LOG_ERROR, "invalid CSP (only I400/I420/YV12/NV12/NV21/I422/YV16/NV16/YUYV/UYVY/"
497
506
                                     "I444/YV24/BGR/BGRA/RGB supported)\n" );
498
507
        return -1;
499
508
    }
500
509
 
501
 
    int w_mod = i_csp < X264_CSP_I444 ? 2 : 1;
502
 
    int h_mod = (i_csp < X264_CSP_I422 ? 2 : 1) << PARAM_INTERLACED;
 
510
    int w_mod = 1;
 
511
    int h_mod = 1 << PARAM_INTERLACED;
 
512
    if( i_csp == X264_CSP_I400 )
 
513
    {
 
514
        h->param.analyse.i_chroma_qp_offset = 0;
 
515
        h->param.analyse.b_chroma_me = 0;
 
516
        h->param.vui.i_colmatrix = 2; /* undefined */
 
517
    }
 
518
    else if( i_csp < X264_CSP_I444 )
 
519
    {
 
520
        w_mod = 2;
 
521
        if( i_csp < X264_CSP_I422 )
 
522
            h_mod *= 2;
 
523
    }
 
524
 
503
525
    if( h->param.i_width % w_mod )
504
526
    {
505
527
        x264_log( h, X264_LOG_ERROR, "width not divisible by %d (%dx%d)\n",
1348
1370
 
1349
1371
    switch( CHROMA_FORMAT )
1350
1372
    {
 
1373
        case CHROMA_400:
 
1374
            h->mc.prefetch_fenc = h->mc.prefetch_fenc_400;
 
1375
            break;
1351
1376
        case CHROMA_420:
1352
1377
            memcpy( h->predict_chroma, h->predict_8x8c, sizeof(h->predict_chroma) );
1353
1378
            h->mc.prefetch_fenc = h->mc.prefetch_fenc_420;
1737
1762
        (h->sps->i_profile_idc == PROFILE_BASELINE || h->sps->i_profile_idc == PROFILE_MAIN) ) )
1738
1763
        strcpy( level, "1b" );
1739
1764
 
1740
 
    if( h->sps->i_profile_idc < PROFILE_HIGH10 )
1741
 
    {
1742
 
        x264_log( h, X264_LOG_INFO, "profile %s, level %s\n",
1743
 
            profile, level );
1744
 
    }
1745
 
    else
1746
 
    {
1747
 
        static const char * const subsampling[4] = { "4:0:0", "4:2:0", "4:2:2", "4:4:4" };
1748
 
        x264_log( h, X264_LOG_INFO, "profile %s, level %s, %s %d-bit\n",
1749
 
            profile, level, subsampling[CHROMA_FORMAT], BIT_DEPTH );
1750
 
    }
 
1765
    static const char * const subsampling[4] = { "4:0:0", "4:2:0", "4:2:2", "4:4:4" };
 
1766
    x264_log( h, X264_LOG_INFO, "profile %s, level %s, %s, %d-bit\n",
 
1767
              profile, level, subsampling[CHROMA_FORMAT], BIT_DEPTH );
1751
1768
 
1752
1769
    return h;
1753
1770
fail:
4253
4270
        }
4254
4271
 
4255
4272
        buf[0] = 0;
4256
 
        int csize = CHROMA444 ? 4 : 1;
4257
 
        if( i_mb_count != i_all_intra )
4258
 
            sprintf( buf, " inter: %.1f%% %.1f%% %.1f%%",
4259
 
                     h->stat.i_mb_cbp[1] * 100.0 / ((i_mb_count - i_all_intra)*4),
4260
 
                     h->stat.i_mb_cbp[3] * 100.0 / ((i_mb_count - i_all_intra)*csize),
4261
 
                     h->stat.i_mb_cbp[5] * 100.0 / ((i_mb_count - i_all_intra)*csize) );
4262
 
        x264_log( h, X264_LOG_INFO, "coded y,%s,%s intra: %.1f%% %.1f%% %.1f%%%s\n",
4263
 
                  CHROMA444?"u":"uvDC", CHROMA444?"v":"uvAC",
4264
 
                  h->stat.i_mb_cbp[0] * 100.0 / (i_all_intra*4),
4265
 
                  h->stat.i_mb_cbp[2] * 100.0 / (i_all_intra*csize),
4266
 
                  h->stat.i_mb_cbp[4] * 100.0 / (i_all_intra*csize), buf );
 
4273
        if( CHROMA_FORMAT )
 
4274
        {
 
4275
            int csize = CHROMA444 ? 4 : 1;
 
4276
            if( i_mb_count != i_all_intra )
 
4277
                sprintf( buf, " inter: %.1f%% %.1f%% %.1f%%",
 
4278
                         h->stat.i_mb_cbp[1] * 100.0 / ((i_mb_count - i_all_intra)*4),
 
4279
                         h->stat.i_mb_cbp[3] * 100.0 / ((i_mb_count - i_all_intra)*csize),
 
4280
                         h->stat.i_mb_cbp[5] * 100.0 / ((i_mb_count - i_all_intra)*csize) );
 
4281
            x264_log( h, X264_LOG_INFO, "coded y,%s,%s intra: %.1f%% %.1f%% %.1f%%%s\n",
 
4282
                      CHROMA444?"u":"uvDC", CHROMA444?"v":"uvAC",
 
4283
                      h->stat.i_mb_cbp[0] * 100.0 / (i_all_intra*4),
 
4284
                      h->stat.i_mb_cbp[2] * 100.0 / (i_all_intra*csize),
 
4285
                      h->stat.i_mb_cbp[4] * 100.0 / (i_all_intra*csize), buf );
 
4286
        }
 
4287
        else
 
4288
        {
 
4289
            if( i_mb_count != i_all_intra )
 
4290
                sprintf( buf, " inter: %.1f%%", h->stat.i_mb_cbp[1] * 100.0 / ((i_mb_count - i_all_intra)*4) );
 
4291
            x264_log( h, X264_LOG_INFO, "coded y intra: %.1f%%%s\n",
 
4292
                      h->stat.i_mb_cbp[0] * 100.0 / (i_all_intra*4), buf );
 
4293
        }
4267
4294
 
4268
4295
        int64_t fixed_pred_modes[4][9] = {{0}};
4269
4296
        int64_t sum_pred_modes[4] = {0};
4310
4337
                      fixed_pred_modes[3][3] * 100.0 / sum_pred_modes[3] );
4311
4338
 
4312
4339
        if( h->param.analyse.i_weighted_pred >= X264_WEIGHTP_SIMPLE && h->stat.i_frame_count[SLICE_TYPE_P] > 0 )
4313
 
            x264_log( h, X264_LOG_INFO, "Weighted P-Frames: Y:%.1f%% UV:%.1f%%\n",
4314
 
                      h->stat.i_wpred[0] * 100.0 / h->stat.i_frame_count[SLICE_TYPE_P],
4315
 
                      h->stat.i_wpred[1] * 100.0 / h->stat.i_frame_count[SLICE_TYPE_P] );
 
4340
        {
 
4341
            buf[0] = 0;
 
4342
            if( CHROMA_FORMAT )
 
4343
                sprintf( buf, " UV:%.1f%%", h->stat.i_wpred[1] * 100.0 / h->stat.i_frame_count[SLICE_TYPE_P] );
 
4344
            x264_log( h, X264_LOG_INFO, "Weighted P-Frames: Y:%.1f%%%s\n",
 
4345
                      h->stat.i_wpred[0] * 100.0 / h->stat.i_frame_count[SLICE_TYPE_P], buf );
 
4346
        }
4316
4347
 
4317
4348
        for( int i_list = 0; i_list < 2; i_list++ )
4318
4349
            for( int i_slice = 0; i_slice < 2; i_slice++ )