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