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 |