| 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 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 VP9EncoderConfig oxcf; | 76 VP9EncoderConfig oxcf; |
| 77 VP9_COMP *cpi; | 77 VP9_COMP *cpi; |
| 78 unsigned char *cx_data; | 78 unsigned char *cx_data; |
| 79 size_t cx_data_sz; | 79 size_t cx_data_sz; |
| 80 unsigned char *pending_cx_data; | 80 unsigned char *pending_cx_data; |
| 81 size_t pending_cx_data_sz; | 81 size_t pending_cx_data_sz; |
| 82 int pending_frame_count; | 82 int pending_frame_count; |
| 83 size_t pending_frame_sizes[8]; | 83 size_t pending_frame_sizes[8]; |
| 84 size_t pending_frame_magnitude; | 84 size_t pending_frame_magnitude; |
| 85 vpx_image_t preview_img; | 85 vpx_image_t preview_img; |
| 86 vpx_enc_frame_flags_t next_frame_flags; |
| 86 vp8_postproc_cfg_t preview_ppcfg; | 87 vp8_postproc_cfg_t preview_ppcfg; |
| 87 vpx_codec_pkt_list_decl(256) pkt_list; | 88 vpx_codec_pkt_list_decl(256) pkt_list; |
| 88 unsigned int fixed_kf_cntr; | 89 unsigned int fixed_kf_cntr; |
| 89 vpx_codec_priv_output_cx_pkt_cb_pair_t output_cx_pkt_cb; | 90 vpx_codec_priv_output_cx_pkt_cb_pair_t output_cx_pkt_cb; |
| 91 // BufferPool that holds all reference frames. |
| 92 BufferPool *buffer_pool; |
| 90 }; | 93 }; |
| 91 | 94 |
| 92 static VP9_REFFRAME ref_frame_to_vp9_reframe(vpx_ref_frame_type_t frame) { | 95 static VP9_REFFRAME ref_frame_to_vp9_reframe(vpx_ref_frame_type_t frame) { |
| 93 switch (frame) { | 96 switch (frame) { |
| 94 case VP8_LAST_FRAME: | 97 case VP8_LAST_FRAME: |
| 95 return VP9_LAST_FLAG; | 98 return VP9_LAST_FLAG; |
| 96 case VP8_GOLD_FRAME: | 99 case VP8_GOLD_FRAME: |
| 97 return VP9_GOLD_FLAG; | 100 return VP9_GOLD_FLAG; |
| 98 case VP8_ALTR_FRAME: | 101 case VP8_ALTR_FRAME: |
| 99 return VP9_ALT_FLAG; | 102 return VP9_ALT_FLAG; |
| (...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 517 printf("error resilient: %d\n", oxcf->error_resilient_mode); | 520 printf("error resilient: %d\n", oxcf->error_resilient_mode); |
| 518 printf("frame parallel detokenization: %d\n", | 521 printf("frame parallel detokenization: %d\n", |
| 519 oxcf->frame_parallel_decoding_mode); | 522 oxcf->frame_parallel_decoding_mode); |
| 520 */ | 523 */ |
| 521 return VPX_CODEC_OK; | 524 return VPX_CODEC_OK; |
| 522 } | 525 } |
| 523 | 526 |
| 524 static vpx_codec_err_t encoder_set_config(vpx_codec_alg_priv_t *ctx, | 527 static vpx_codec_err_t encoder_set_config(vpx_codec_alg_priv_t *ctx, |
| 525 const vpx_codec_enc_cfg_t *cfg) { | 528 const vpx_codec_enc_cfg_t *cfg) { |
| 526 vpx_codec_err_t res; | 529 vpx_codec_err_t res; |
| 530 int force_key = 0; |
| 527 | 531 |
| 528 if (cfg->g_w != ctx->cfg.g_w || cfg->g_h != ctx->cfg.g_h) | 532 if (cfg->g_w != ctx->cfg.g_w || cfg->g_h != ctx->cfg.g_h) { |
| 529 ERROR("Cannot change width or height after initialization"); | 533 if (cfg->g_lag_in_frames > 1 || cfg->g_pass != VPX_RC_ONE_PASS) |
| 534 ERROR("Cannot change width or height after initialization"); |
| 535 if (!valid_ref_frame_size(ctx->cfg.g_w, ctx->cfg.g_h, cfg->g_w, cfg->g_h) || |
| 536 (ctx->cpi->initial_width && (int)cfg->g_w > ctx->cpi->initial_width) || |
| 537 (ctx->cpi->initial_height && (int)cfg->g_h > ctx->cpi->initial_height)) |
| 538 force_key = 1; |
| 539 } |
| 530 | 540 |
| 531 // Prevent increasing lag_in_frames. This check is stricter than it needs | 541 // Prevent increasing lag_in_frames. This check is stricter than it needs |
| 532 // to be -- the limit is not increasing past the first lag_in_frames | 542 // to be -- the limit is not increasing past the first lag_in_frames |
| 533 // value, but we don't track the initial config, only the last successful | 543 // value, but we don't track the initial config, only the last successful |
| 534 // config. | 544 // config. |
| 535 if (cfg->g_lag_in_frames > ctx->cfg.g_lag_in_frames) | 545 if (cfg->g_lag_in_frames > ctx->cfg.g_lag_in_frames) |
| 536 ERROR("Cannot increase lag_in_frames"); | 546 ERROR("Cannot increase lag_in_frames"); |
| 537 | 547 |
| 538 res = validate_config(ctx, cfg, &ctx->extra_cfg); | 548 res = validate_config(ctx, cfg, &ctx->extra_cfg); |
| 539 | 549 |
| 540 if (res == VPX_CODEC_OK) { | 550 if (res == VPX_CODEC_OK) { |
| 541 ctx->cfg = *cfg; | 551 ctx->cfg = *cfg; |
| 542 set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg); | 552 set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg); |
| 543 vp9_change_config(ctx->cpi, &ctx->oxcf); | 553 vp9_change_config(ctx->cpi, &ctx->oxcf); |
| 544 } | 554 } |
| 545 | 555 |
| 556 if (force_key) |
| 557 ctx->next_frame_flags |= VPX_EFLAG_FORCE_KF; |
| 558 |
| 546 return res; | 559 return res; |
| 547 } | 560 } |
| 548 | 561 |
| 549 static vpx_codec_err_t ctrl_get_quantizer(vpx_codec_alg_priv_t *ctx, | 562 static vpx_codec_err_t ctrl_get_quantizer(vpx_codec_alg_priv_t *ctx, |
| 550 va_list args) { | 563 va_list args) { |
| 551 int *const arg = va_arg(args, int *); | 564 int *const arg = va_arg(args, int *); |
| 552 if (arg == NULL) | 565 if (arg == NULL) |
| 553 return VPX_CODEC_INVALID_PARAM; | 566 return VPX_CODEC_INVALID_PARAM; |
| 554 *arg = vp9_get_quantizer(ctx->cpi); | 567 *arg = vp9_get_quantizer(ctx->cpi); |
| 555 return VPX_CODEC_OK; | 568 return VPX_CODEC_OK; |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 718 (void)data; | 731 (void)data; |
| 719 | 732 |
| 720 if (ctx->priv == NULL) { | 733 if (ctx->priv == NULL) { |
| 721 vpx_codec_alg_priv_t *const priv = vpx_calloc(1, sizeof(*priv)); | 734 vpx_codec_alg_priv_t *const priv = vpx_calloc(1, sizeof(*priv)); |
| 722 if (priv == NULL) | 735 if (priv == NULL) |
| 723 return VPX_CODEC_MEM_ERROR; | 736 return VPX_CODEC_MEM_ERROR; |
| 724 | 737 |
| 725 ctx->priv = (vpx_codec_priv_t *)priv; | 738 ctx->priv = (vpx_codec_priv_t *)priv; |
| 726 ctx->priv->init_flags = ctx->init_flags; | 739 ctx->priv->init_flags = ctx->init_flags; |
| 727 ctx->priv->enc.total_encoders = 1; | 740 ctx->priv->enc.total_encoders = 1; |
| 741 priv->buffer_pool = |
| 742 (BufferPool *)vpx_calloc(1, sizeof(BufferPool)); |
| 743 if (priv->buffer_pool == NULL) |
| 744 return VPX_CODEC_MEM_ERROR; |
| 745 |
| 746 #if CONFIG_MULTITHREAD |
| 747 if (pthread_mutex_init(&priv->buffer_pool->pool_mutex, NULL)) { |
| 748 return VPX_CODEC_MEM_ERROR; |
| 749 } |
| 750 #endif |
| 728 | 751 |
| 729 if (ctx->config.enc) { | 752 if (ctx->config.enc) { |
| 730 // Update the reference to the config structure to an internal copy. | 753 // Update the reference to the config structure to an internal copy. |
| 731 priv->cfg = *ctx->config.enc; | 754 priv->cfg = *ctx->config.enc; |
| 732 ctx->config.enc = &priv->cfg; | 755 ctx->config.enc = &priv->cfg; |
| 733 } | 756 } |
| 734 | 757 |
| 735 priv->extra_cfg = default_extra_cfg; | 758 priv->extra_cfg = default_extra_cfg; |
| 736 once(vp9_initialize_enc); | 759 once(vp9_initialize_enc); |
| 737 | 760 |
| 738 res = validate_config(priv, &priv->cfg, &priv->extra_cfg); | 761 res = validate_config(priv, &priv->cfg, &priv->extra_cfg); |
| 739 | 762 |
| 740 if (res == VPX_CODEC_OK) { | 763 if (res == VPX_CODEC_OK) { |
| 741 set_encoder_config(&priv->oxcf, &priv->cfg, &priv->extra_cfg); | 764 set_encoder_config(&priv->oxcf, &priv->cfg, &priv->extra_cfg); |
| 742 #if CONFIG_VP9_HIGHBITDEPTH | 765 #if CONFIG_VP9_HIGHBITDEPTH |
| 743 priv->oxcf.use_highbitdepth = | 766 priv->oxcf.use_highbitdepth = |
| 744 (ctx->init_flags & VPX_CODEC_USE_HIGHBITDEPTH) ? 1 : 0; | 767 (ctx->init_flags & VPX_CODEC_USE_HIGHBITDEPTH) ? 1 : 0; |
| 745 #endif | 768 #endif |
| 746 priv->cpi = vp9_create_compressor(&priv->oxcf); | 769 priv->cpi = vp9_create_compressor(&priv->oxcf, priv->buffer_pool); |
| 747 if (priv->cpi == NULL) | 770 if (priv->cpi == NULL) |
| 748 res = VPX_CODEC_MEM_ERROR; | 771 res = VPX_CODEC_MEM_ERROR; |
| 749 else | 772 else |
| 750 priv->cpi->output_pkt_list = &priv->pkt_list.head; | 773 priv->cpi->output_pkt_list = &priv->pkt_list.head; |
| 751 } | 774 } |
| 752 } | 775 } |
| 753 | 776 |
| 754 return res; | 777 return res; |
| 755 } | 778 } |
| 756 | 779 |
| 757 static vpx_codec_err_t encoder_destroy(vpx_codec_alg_priv_t *ctx) { | 780 static vpx_codec_err_t encoder_destroy(vpx_codec_alg_priv_t *ctx) { |
| 758 free(ctx->cx_data); | 781 free(ctx->cx_data); |
| 759 vp9_remove_compressor(ctx->cpi); | 782 vp9_remove_compressor(ctx->cpi); |
| 783 #if CONFIG_MULTITHREAD |
| 784 pthread_mutex_destroy(&ctx->buffer_pool->pool_mutex); |
| 785 #endif |
| 786 vpx_free(ctx->buffer_pool); |
| 760 vpx_free(ctx); | 787 vpx_free(ctx); |
| 761 return VPX_CODEC_OK; | 788 return VPX_CODEC_OK; |
| 762 } | 789 } |
| 763 | 790 |
| 764 static void pick_quickcompress_mode(vpx_codec_alg_priv_t *ctx, | 791 static void pick_quickcompress_mode(vpx_codec_alg_priv_t *ctx, |
| 765 unsigned long duration, | 792 unsigned long duration, |
| 766 unsigned long deadline) { | 793 unsigned long deadline) { |
| 767 MODE new_mode = BEST; | 794 MODE new_mode = BEST; |
| 768 | 795 |
| 769 switch (ctx->cfg.g_pass) { | 796 switch (ctx->cfg.g_pass) { |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 948 | 975 |
| 949 // Set up internal flags | 976 // Set up internal flags |
| 950 if (ctx->base.init_flags & VPX_CODEC_USE_PSNR) | 977 if (ctx->base.init_flags & VPX_CODEC_USE_PSNR) |
| 951 cpi->b_calculate_psnr = 1; | 978 cpi->b_calculate_psnr = 1; |
| 952 | 979 |
| 953 if (img != NULL) { | 980 if (img != NULL) { |
| 954 res = image2yuvconfig(img, &sd); | 981 res = image2yuvconfig(img, &sd); |
| 955 | 982 |
| 956 // Store the original flags in to the frame buffer. Will extract the | 983 // Store the original flags in to the frame buffer. Will extract the |
| 957 // key frame flag when we actually encode this frame. | 984 // key frame flag when we actually encode this frame. |
| 958 if (vp9_receive_raw_frame(cpi, flags, | 985 if (vp9_receive_raw_frame(cpi, flags | ctx->next_frame_flags, |
| 959 &sd, dst_time_stamp, dst_end_time_stamp)) { | 986 &sd, dst_time_stamp, dst_end_time_stamp)) { |
| 960 res = update_error_state(ctx, &cpi->common.error); | 987 res = update_error_state(ctx, &cpi->common.error); |
| 961 } | 988 } |
| 989 ctx->next_frame_flags = 0; |
| 962 } | 990 } |
| 963 | 991 |
| 964 cx_data = ctx->cx_data; | 992 cx_data = ctx->cx_data; |
| 965 cx_data_sz = ctx->cx_data_sz; | 993 cx_data_sz = ctx->cx_data_sz; |
| 966 | 994 |
| 967 /* Any pending invisible frames? */ | 995 /* Any pending invisible frames? */ |
| 968 if (ctx->pending_cx_data) { | 996 if (ctx->pending_cx_data) { |
| 969 memmove(cx_data, ctx->pending_cx_data, ctx->pending_cx_data_sz); | 997 memmove(cx_data, ctx->pending_cx_data, ctx->pending_cx_data_sz); |
| 970 ctx->pending_cx_data = cx_data; | 998 ctx->pending_cx_data = cx_data; |
| 971 cx_data += ctx->pending_cx_data_sz; | 999 cx_data += ctx->pending_cx_data_sz; |
| (...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1470 1, // 1 cfg map | 1498 1, // 1 cfg map |
| 1471 encoder_usage_cfg_map, // vpx_codec_enc_cfg_map_t | 1499 encoder_usage_cfg_map, // vpx_codec_enc_cfg_map_t |
| 1472 encoder_encode, // vpx_codec_encode_fn_t | 1500 encoder_encode, // vpx_codec_encode_fn_t |
| 1473 encoder_get_cxdata, // vpx_codec_get_cx_data_fn_t | 1501 encoder_get_cxdata, // vpx_codec_get_cx_data_fn_t |
| 1474 encoder_set_config, // vpx_codec_enc_config_set_fn_t | 1502 encoder_set_config, // vpx_codec_enc_config_set_fn_t |
| 1475 NULL, // vpx_codec_get_global_headers_fn_t | 1503 NULL, // vpx_codec_get_global_headers_fn_t |
| 1476 encoder_get_preview, // vpx_codec_get_preview_frame_fn_t | 1504 encoder_get_preview, // vpx_codec_get_preview_frame_fn_t |
| 1477 NULL // vpx_codec_enc_mr_get_mem_loc_fn_t | 1505 NULL // vpx_codec_enc_mr_get_mem_loc_fn_t |
| 1478 } | 1506 } |
| 1479 }; | 1507 }; |
| OLD | NEW |