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 |