OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. | 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
318 case VPX_IMG_FMT_I444: return 24; | 318 case VPX_IMG_FMT_I444: return 24; |
319 default: assert(0 && "Invalid image format"); break; | 319 default: assert(0 && "Invalid image format"); break; |
320 } | 320 } |
321 return 0; | 321 return 0; |
322 } | 322 } |
323 | 323 |
324 static vpx_codec_err_t set_encoder_config( | 324 static vpx_codec_err_t set_encoder_config( |
325 VP9EncoderConfig *oxcf, | 325 VP9EncoderConfig *oxcf, |
326 const vpx_codec_enc_cfg_t *cfg, | 326 const vpx_codec_enc_cfg_t *cfg, |
327 const struct vp9_extracfg *extra_cfg) { | 327 const struct vp9_extracfg *extra_cfg) { |
| 328 const int is_vbr = cfg->rc_end_usage == VPX_VBR; |
328 oxcf->profile = cfg->g_profile; | 329 oxcf->profile = cfg->g_profile; |
329 oxcf->width = cfg->g_w; | 330 oxcf->width = cfg->g_w; |
330 oxcf->height = cfg->g_h; | 331 oxcf->height = cfg->g_h; |
331 oxcf->bit_depth = extra_cfg->bit_depth; | 332 oxcf->bit_depth = extra_cfg->bit_depth; |
332 // guess a frame rate if out of whack, use 30 | 333 // guess a frame rate if out of whack, use 30 |
333 oxcf->init_framerate = (double)cfg->g_timebase.den / cfg->g_timebase.num; | 334 oxcf->init_framerate = (double)cfg->g_timebase.den / cfg->g_timebase.num; |
334 if (oxcf->init_framerate > 180) | 335 if (oxcf->init_framerate > 180) |
335 oxcf->init_framerate = 30; | 336 oxcf->init_framerate = 30; |
336 | 337 |
| 338 oxcf->mode = BEST; |
| 339 |
337 switch (cfg->g_pass) { | 340 switch (cfg->g_pass) { |
338 case VPX_RC_ONE_PASS: | 341 case VPX_RC_ONE_PASS: |
339 oxcf->mode = ONE_PASS_GOOD; | |
340 oxcf->pass = 0; | 342 oxcf->pass = 0; |
341 break; | 343 break; |
342 case VPX_RC_FIRST_PASS: | 344 case VPX_RC_FIRST_PASS: |
343 oxcf->mode = TWO_PASS_FIRST; | |
344 oxcf->pass = 1; | 345 oxcf->pass = 1; |
345 break; | 346 break; |
346 case VPX_RC_LAST_PASS: | 347 case VPX_RC_LAST_PASS: |
347 oxcf->mode = TWO_PASS_SECOND_BEST; | |
348 oxcf->pass = 2; | 348 oxcf->pass = 2; |
349 break; | 349 break; |
350 } | 350 } |
351 | 351 |
352 oxcf->lag_in_frames = cfg->g_pass == VPX_RC_FIRST_PASS ? 0 | 352 oxcf->lag_in_frames = cfg->g_pass == VPX_RC_FIRST_PASS ? 0 |
353 : cfg->g_lag_in_frames; | 353 : cfg->g_lag_in_frames; |
354 oxcf->rc_mode = cfg->rc_end_usage; | 354 oxcf->rc_mode = cfg->rc_end_usage; |
355 | 355 |
356 // Convert target bandwidth from Kbit/s to Bit/s | 356 // Convert target bandwidth from Kbit/s to Bit/s |
357 oxcf->target_bandwidth = 1000 * cfg->rc_target_bitrate; | 357 oxcf->target_bandwidth = 1000 * cfg->rc_target_bitrate; |
358 oxcf->rc_max_intra_bitrate_pct = extra_cfg->rc_max_intra_bitrate_pct; | 358 oxcf->rc_max_intra_bitrate_pct = extra_cfg->rc_max_intra_bitrate_pct; |
359 | 359 |
360 oxcf->best_allowed_q = | 360 oxcf->best_allowed_q = |
361 extra_cfg->lossless ? 0 : vp9_quantizer_to_qindex(cfg->rc_min_quantizer); | 361 extra_cfg->lossless ? 0 : vp9_quantizer_to_qindex(cfg->rc_min_quantizer); |
362 oxcf->worst_allowed_q = | 362 oxcf->worst_allowed_q = |
363 extra_cfg->lossless ? 0 : vp9_quantizer_to_qindex(cfg->rc_max_quantizer); | 363 extra_cfg->lossless ? 0 : vp9_quantizer_to_qindex(cfg->rc_max_quantizer); |
364 oxcf->cq_level = vp9_quantizer_to_qindex(extra_cfg->cq_level); | 364 oxcf->cq_level = vp9_quantizer_to_qindex(extra_cfg->cq_level); |
365 oxcf->fixed_q = -1; | 365 oxcf->fixed_q = -1; |
366 | 366 |
367 oxcf->under_shoot_pct = cfg->rc_undershoot_pct; | 367 oxcf->under_shoot_pct = cfg->rc_undershoot_pct; |
368 oxcf->over_shoot_pct = cfg->rc_overshoot_pct; | 368 oxcf->over_shoot_pct = cfg->rc_overshoot_pct; |
369 | 369 |
370 oxcf->allow_spatial_resampling = cfg->rc_resize_allowed; | 370 oxcf->allow_spatial_resampling = cfg->rc_resize_allowed; |
371 oxcf->scaled_frame_width = cfg->rc_scaled_width; | 371 oxcf->scaled_frame_width = cfg->rc_scaled_width; |
372 oxcf->scaled_frame_height = cfg->rc_scaled_height; | 372 oxcf->scaled_frame_height = cfg->rc_scaled_height; |
373 | 373 |
374 oxcf->maximum_buffer_size_ms = cfg->rc_buf_sz; | 374 oxcf->maximum_buffer_size_ms = is_vbr ? 240000 : cfg->rc_buf_sz; |
375 oxcf->starting_buffer_level_ms = cfg->rc_buf_initial_sz; | 375 oxcf->starting_buffer_level_ms = is_vbr ? 60000 : cfg->rc_buf_initial_sz; |
376 oxcf->optimal_buffer_level_ms = cfg->rc_buf_optimal_sz; | 376 oxcf->optimal_buffer_level_ms = is_vbr ? 60000 : cfg->rc_buf_optimal_sz; |
377 | 377 |
378 oxcf->drop_frames_water_mark = cfg->rc_dropframe_thresh; | 378 oxcf->drop_frames_water_mark = cfg->rc_dropframe_thresh; |
379 | 379 |
380 oxcf->two_pass_vbrbias = cfg->rc_2pass_vbr_bias_pct; | 380 oxcf->two_pass_vbrbias = cfg->rc_2pass_vbr_bias_pct; |
381 oxcf->two_pass_vbrmin_section = cfg->rc_2pass_vbr_minsection_pct; | 381 oxcf->two_pass_vbrmin_section = cfg->rc_2pass_vbr_minsection_pct; |
382 oxcf->two_pass_vbrmax_section = cfg->rc_2pass_vbr_maxsection_pct; | 382 oxcf->two_pass_vbrmax_section = cfg->rc_2pass_vbr_maxsection_pct; |
383 | 383 |
384 oxcf->auto_key = cfg->kf_mode == VPX_KF_AUTO && | 384 oxcf->auto_key = cfg->kf_mode == VPX_KF_AUTO && |
385 cfg->kf_min_dist != cfg->kf_max_dist; | 385 cfg->kf_min_dist != cfg->kf_max_dist; |
386 | 386 |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
661 if (ctx->priv == NULL) { | 661 if (ctx->priv == NULL) { |
662 int i; | 662 int i; |
663 vpx_codec_enc_cfg_t *cfg; | 663 vpx_codec_enc_cfg_t *cfg; |
664 struct vpx_codec_alg_priv *priv = calloc(1, sizeof(*priv)); | 664 struct vpx_codec_alg_priv *priv = calloc(1, sizeof(*priv)); |
665 | 665 |
666 if (priv == NULL) | 666 if (priv == NULL) |
667 return VPX_CODEC_MEM_ERROR; | 667 return VPX_CODEC_MEM_ERROR; |
668 | 668 |
669 ctx->priv = &priv->base; | 669 ctx->priv = &priv->base; |
670 ctx->priv->sz = sizeof(*ctx->priv); | 670 ctx->priv->sz = sizeof(*ctx->priv); |
671 ctx->priv->iface = ctx->iface; | |
672 ctx->priv->alg_priv = priv; | 671 ctx->priv->alg_priv = priv; |
673 ctx->priv->init_flags = ctx->init_flags; | 672 ctx->priv->init_flags = ctx->init_flags; |
674 ctx->priv->enc.total_encoders = 1; | 673 ctx->priv->enc.total_encoders = 1; |
675 | 674 |
676 if (ctx->config.enc) { | 675 if (ctx->config.enc) { |
677 // Update the reference to the config structure to an internal copy. | 676 // Update the reference to the config structure to an internal copy. |
678 ctx->priv->alg_priv->cfg = *ctx->config.enc; | 677 ctx->priv->alg_priv->cfg = *ctx->config.enc; |
679 ctx->config.enc = &ctx->priv->alg_priv->cfg; | 678 ctx->config.enc = &ctx->priv->alg_priv->cfg; |
680 } | 679 } |
681 | 680 |
(...skipping 29 matching lines...) Expand all Loading... |
711 return res; | 710 return res; |
712 } | 711 } |
713 | 712 |
714 static vpx_codec_err_t encoder_destroy(vpx_codec_alg_priv_t *ctx) { | 713 static vpx_codec_err_t encoder_destroy(vpx_codec_alg_priv_t *ctx) { |
715 free(ctx->cx_data); | 714 free(ctx->cx_data); |
716 vp9_remove_compressor(ctx->cpi); | 715 vp9_remove_compressor(ctx->cpi); |
717 free(ctx); | 716 free(ctx); |
718 return VPX_CODEC_OK; | 717 return VPX_CODEC_OK; |
719 } | 718 } |
720 | 719 |
721 static void pick_quickcompress_mode(vpx_codec_alg_priv_t *ctx, | 720 static void pick_quickcompress_mode(vpx_codec_alg_priv_t *ctx, |
722 unsigned long duration, | 721 unsigned long duration, |
723 unsigned long deadline) { | 722 unsigned long deadline) { |
724 // Use best quality mode if no deadline is given. | 723 MODE new_mode = BEST; |
725 MODE new_qc = ONE_PASS_BEST; | |
726 | 724 |
727 if (deadline) { | 725 switch (ctx->cfg.g_pass) { |
728 // Convert duration parameter from stream timebase to microseconds | 726 case VPX_RC_ONE_PASS: |
729 const uint64_t duration_us = (uint64_t)duration * 1000000 * | 727 if (deadline > 0) { |
730 (uint64_t)ctx->cfg.g_timebase.num / | 728 const vpx_codec_enc_cfg_t *const cfg = &ctx->cfg; |
731 (uint64_t)ctx->cfg.g_timebase.den; | |
732 | 729 |
733 // If the deadline is more that the duration this frame is to be shown, | 730 // Convert duration parameter from stream timebase to microseconds. |
734 // use good quality mode. Otherwise use realtime mode. | 731 const uint64_t duration_us = (uint64_t)duration * 1000000 * |
735 new_qc = (deadline > duration_us) ? ONE_PASS_GOOD : REALTIME; | 732 (uint64_t)cfg->g_timebase.num /(uint64_t)cfg->g_timebase.den; |
| 733 |
| 734 // If the deadline is more that the duration this frame is to be shown, |
| 735 // use good quality mode. Otherwise use realtime mode. |
| 736 new_mode = (deadline > duration_us) ? GOOD : REALTIME; |
| 737 } else { |
| 738 new_mode = BEST; |
| 739 } |
| 740 break; |
| 741 case VPX_RC_FIRST_PASS: |
| 742 break; |
| 743 case VPX_RC_LAST_PASS: |
| 744 new_mode = deadline > 0 ? GOOD : BEST; |
| 745 break; |
736 } | 746 } |
737 | 747 |
738 if (ctx->cfg.g_pass == VPX_RC_FIRST_PASS) | 748 if (ctx->oxcf.mode != new_mode) { |
739 new_qc = TWO_PASS_FIRST; | 749 ctx->oxcf.mode = new_mode; |
740 else if (ctx->cfg.g_pass == VPX_RC_LAST_PASS) | |
741 new_qc = (new_qc == ONE_PASS_BEST) ? TWO_PASS_SECOND_BEST | |
742 : TWO_PASS_SECOND_GOOD; | |
743 | |
744 if (ctx->oxcf.mode != new_qc) { | |
745 ctx->oxcf.mode = new_qc; | |
746 vp9_change_config(ctx->cpi, &ctx->oxcf); | 750 vp9_change_config(ctx->cpi, &ctx->oxcf); |
747 } | 751 } |
748 } | 752 } |
749 | 753 |
750 // Turn on to test if supplemental superframe data breaks decoding | 754 // Turn on to test if supplemental superframe data breaks decoding |
751 // #define TEST_SUPPLEMENTAL_SUPERFRAME_DATA | 755 // #define TEST_SUPPLEMENTAL_SUPERFRAME_DATA |
752 static int write_superframe_index(vpx_codec_alg_priv_t *ctx) { | 756 static int write_superframe_index(vpx_codec_alg_priv_t *ctx) { |
753 uint8_t marker = 0xc0; | 757 uint8_t marker = 0xc0; |
754 unsigned int mask; | 758 unsigned int mask; |
755 int mag, index_sz; | 759 int mag, index_sz; |
(...skipping 604 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1360 1, // 1 cfg map | 1364 1, // 1 cfg map |
1361 encoder_usage_cfg_map, // vpx_codec_enc_cfg_map_t | 1365 encoder_usage_cfg_map, // vpx_codec_enc_cfg_map_t |
1362 encoder_encode, // vpx_codec_encode_fn_t | 1366 encoder_encode, // vpx_codec_encode_fn_t |
1363 encoder_get_cxdata, // vpx_codec_get_cx_data_fn_t | 1367 encoder_get_cxdata, // vpx_codec_get_cx_data_fn_t |
1364 encoder_set_config, // vpx_codec_enc_config_set_fn_t | 1368 encoder_set_config, // vpx_codec_enc_config_set_fn_t |
1365 NOT_IMPLEMENTED, // vpx_codec_get_global_headers_fn_t | 1369 NOT_IMPLEMENTED, // vpx_codec_get_global_headers_fn_t |
1366 encoder_get_preview, // vpx_codec_get_preview_frame_fn_t | 1370 encoder_get_preview, // vpx_codec_get_preview_frame_fn_t |
1367 NOT_IMPLEMENTED // vpx_codec_enc_mr_get_mem_loc_fn_t | 1371 NOT_IMPLEMENTED // vpx_codec_enc_mr_get_mem_loc_fn_t |
1368 } | 1372 } |
1369 }; | 1373 }; |
OLD | NEW |