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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
81 VP9_COMP *cpi; | 81 VP9_COMP *cpi; |
82 unsigned char *cx_data; | 82 unsigned char *cx_data; |
83 size_t cx_data_sz; | 83 size_t cx_data_sz; |
84 unsigned char *pending_cx_data; | 84 unsigned char *pending_cx_data; |
85 size_t pending_cx_data_sz; | 85 size_t pending_cx_data_sz; |
86 int pending_frame_count; | 86 int pending_frame_count; |
87 size_t pending_frame_sizes[8]; | 87 size_t pending_frame_sizes[8]; |
88 size_t pending_frame_magnitude; | 88 size_t pending_frame_magnitude; |
89 vpx_image_t preview_img; | 89 vpx_image_t preview_img; |
90 vp8_postproc_cfg_t preview_ppcfg; | 90 vp8_postproc_cfg_t preview_ppcfg; |
91 vpx_codec_pkt_list_decl(64) pkt_list; | 91 vpx_codec_pkt_list_decl(128) pkt_list; |
92 unsigned int fixed_kf_cntr; | 92 unsigned int fixed_kf_cntr; |
93 }; | 93 }; |
94 | 94 |
95 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) { |
96 switch (frame) { | 96 switch (frame) { |
97 case VP8_LAST_FRAME: | 97 case VP8_LAST_FRAME: |
98 return VP9_LAST_FLAG; | 98 return VP9_LAST_FLAG; |
99 case VP8_GOLD_FRAME: | 99 case VP8_GOLD_FRAME: |
100 return VP9_GOLD_FLAG; | 100 return VP9_GOLD_FLAG; |
101 case VP8_ALTR_FRAME: | 101 case VP8_ALTR_FRAME: |
102 return VP9_ALT_FLAG; | 102 return VP9_ALT_FLAG; |
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
788 pick_quickcompress_mode(ctx, duration, deadline); | 788 pick_quickcompress_mode(ctx, duration, deadline); |
789 vpx_codec_pkt_list_init(&ctx->pkt_list); | 789 vpx_codec_pkt_list_init(&ctx->pkt_list); |
790 | 790 |
791 // Handle Flags | 791 // Handle Flags |
792 if (((flags & VP8_EFLAG_NO_UPD_GF) && (flags & VP8_EFLAG_FORCE_GF)) || | 792 if (((flags & VP8_EFLAG_NO_UPD_GF) && (flags & VP8_EFLAG_FORCE_GF)) || |
793 ((flags & VP8_EFLAG_NO_UPD_ARF) && (flags & VP8_EFLAG_FORCE_ARF))) { | 793 ((flags & VP8_EFLAG_NO_UPD_ARF) && (flags & VP8_EFLAG_FORCE_ARF))) { |
794 ctx->base.err_detail = "Conflicting flags."; | 794 ctx->base.err_detail = "Conflicting flags."; |
795 return VPX_CODEC_INVALID_PARAM; | 795 return VPX_CODEC_INVALID_PARAM; |
796 } | 796 } |
797 | 797 |
798 if (flags & (VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_GF | | 798 vp9_apply_encoding_flags(ctx->cpi, flags); |
799 VP8_EFLAG_NO_REF_ARF)) { | |
800 int ref = 7; | |
801 | |
802 if (flags & VP8_EFLAG_NO_REF_LAST) | |
803 ref ^= VP9_LAST_FLAG; | |
804 | |
805 if (flags & VP8_EFLAG_NO_REF_GF) | |
806 ref ^= VP9_GOLD_FLAG; | |
807 | |
808 if (flags & VP8_EFLAG_NO_REF_ARF) | |
809 ref ^= VP9_ALT_FLAG; | |
810 | |
811 vp9_use_as_reference(ctx->cpi, ref); | |
812 } | |
813 | |
814 if (flags & (VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF | | |
815 VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_FORCE_GF | | |
816 VP8_EFLAG_FORCE_ARF)) { | |
817 int upd = 7; | |
818 | |
819 if (flags & VP8_EFLAG_NO_UPD_LAST) | |
820 upd ^= VP9_LAST_FLAG; | |
821 | |
822 if (flags & VP8_EFLAG_NO_UPD_GF) | |
823 upd ^= VP9_GOLD_FLAG; | |
824 | |
825 if (flags & VP8_EFLAG_NO_UPD_ARF) | |
826 upd ^= VP9_ALT_FLAG; | |
827 | |
828 vp9_update_reference(ctx->cpi, upd); | |
829 } | |
830 | |
831 if (flags & VP8_EFLAG_NO_UPD_ENTROPY) { | |
832 vp9_update_entropy(ctx->cpi, 0); | |
833 } | |
834 | 799 |
835 // Handle fixed keyframe intervals | 800 // Handle fixed keyframe intervals |
836 if (ctx->cfg.kf_mode == VPX_KF_AUTO && | 801 if (ctx->cfg.kf_mode == VPX_KF_AUTO && |
837 ctx->cfg.kf_min_dist == ctx->cfg.kf_max_dist) { | 802 ctx->cfg.kf_min_dist == ctx->cfg.kf_max_dist) { |
838 if (++ctx->fixed_kf_cntr > ctx->cfg.kf_min_dist) { | 803 if (++ctx->fixed_kf_cntr > ctx->cfg.kf_min_dist) { |
839 flags |= VPX_EFLAG_FORCE_KF; | 804 flags |= VPX_EFLAG_FORCE_KF; |
840 ctx->fixed_kf_cntr = 1; | 805 ctx->fixed_kf_cntr = 1; |
841 } | 806 } |
842 } | 807 } |
843 | 808 |
844 // Initialize the encoder instance on the first frame. | 809 // Initialize the encoder instance on the first frame. |
845 if (res == VPX_CODEC_OK && ctx->cpi != NULL) { | 810 if (res == VPX_CODEC_OK && ctx->cpi != NULL) { |
846 unsigned int lib_flags; | 811 unsigned int lib_flags = 0; |
847 YV12_BUFFER_CONFIG sd; | 812 YV12_BUFFER_CONFIG sd; |
848 int64_t dst_time_stamp, dst_end_time_stamp; | 813 int64_t dst_time_stamp, dst_end_time_stamp; |
849 size_t size, cx_data_sz; | 814 size_t size, cx_data_sz; |
850 unsigned char *cx_data; | 815 unsigned char *cx_data; |
851 | 816 |
852 // Set up internal flags | 817 // Set up internal flags |
853 if (ctx->base.init_flags & VPX_CODEC_USE_PSNR) | 818 if (ctx->base.init_flags & VPX_CODEC_USE_PSNR) |
854 ((VP9_COMP *)ctx->cpi)->b_calculate_psnr = 1; | 819 ((VP9_COMP *)ctx->cpi)->b_calculate_psnr = 1; |
855 | 820 |
856 // Convert API flags to internal codec lib flags | |
857 lib_flags = (flags & VPX_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0; | |
858 | |
859 /* vp9 use 10,000,000 ticks/second as time stamp */ | 821 /* vp9 use 10,000,000 ticks/second as time stamp */ |
860 dst_time_stamp = (pts * 10000000 * ctx->cfg.g_timebase.num) | 822 dst_time_stamp = (pts * 10000000 * ctx->cfg.g_timebase.num) |
861 / ctx->cfg.g_timebase.den; | 823 / ctx->cfg.g_timebase.den; |
862 dst_end_time_stamp = (pts + duration) * 10000000 * ctx->cfg.g_timebase.num / | 824 dst_end_time_stamp = (pts + duration) * 10000000 * ctx->cfg.g_timebase.num / |
863 ctx->cfg.g_timebase.den; | 825 ctx->cfg.g_timebase.den; |
864 | 826 |
865 if (img != NULL) { | 827 if (img != NULL) { |
866 res = image2yuvconfig(img, &sd); | 828 res = image2yuvconfig(img, &sd); |
867 | 829 |
868 if (vp9_receive_raw_frame(ctx->cpi, lib_flags, | 830 // Store the original flags in to the frame buffer. Will extract the |
| 831 // key frame flag when we actually encode this frame. |
| 832 if (vp9_receive_raw_frame(ctx->cpi, flags, |
869 &sd, dst_time_stamp, dst_end_time_stamp)) { | 833 &sd, dst_time_stamp, dst_end_time_stamp)) { |
870 VP9_COMP *cpi = (VP9_COMP *)ctx->cpi; | 834 VP9_COMP *cpi = (VP9_COMP *)ctx->cpi; |
871 res = update_error_state(ctx, &cpi->common.error); | 835 res = update_error_state(ctx, &cpi->common.error); |
872 } | 836 } |
873 } | 837 } |
874 | 838 |
875 cx_data = ctx->cx_data; | 839 cx_data = ctx->cx_data; |
876 cx_data_sz = ctx->cx_data_sz; | 840 cx_data_sz = ctx->cx_data_sz; |
877 lib_flags = 0; | |
878 | 841 |
879 /* Any pending invisible frames? */ | 842 /* Any pending invisible frames? */ |
880 if (ctx->pending_cx_data) { | 843 if (ctx->pending_cx_data) { |
881 memmove(cx_data, ctx->pending_cx_data, ctx->pending_cx_data_sz); | 844 memmove(cx_data, ctx->pending_cx_data, ctx->pending_cx_data_sz); |
882 ctx->pending_cx_data = cx_data; | 845 ctx->pending_cx_data = cx_data; |
883 cx_data += ctx->pending_cx_data_sz; | 846 cx_data += ctx->pending_cx_data_sz; |
884 cx_data_sz -= ctx->pending_cx_data_sz; | 847 cx_data_sz -= ctx->pending_cx_data_sz; |
885 | 848 |
886 /* TODO: this is a minimal check, the underlying codec doesn't respect | 849 /* TODO: this is a minimal check, the underlying codec doesn't respect |
887 * the buffer size anyway. | 850 * the buffer size anyway. |
888 */ | 851 */ |
889 if (cx_data_sz < ctx->cx_data_sz / 2) { | 852 if (cx_data_sz < ctx->cx_data_sz / 2) { |
890 ctx->base.err_detail = "Compressed data buffer too small"; | 853 ctx->base.err_detail = "Compressed data buffer too small"; |
891 return VPX_CODEC_ERROR; | 854 return VPX_CODEC_ERROR; |
892 } | 855 } |
893 } | 856 } |
894 | 857 |
895 while (cx_data_sz >= ctx->cx_data_sz / 2 && | 858 while (cx_data_sz >= ctx->cx_data_sz / 2 && |
896 -1 != vp9_get_compressed_data(ctx->cpi, &lib_flags, &size, | 859 -1 != vp9_get_compressed_data(ctx->cpi, &lib_flags, &size, |
897 cx_data, &dst_time_stamp, | 860 cx_data, &dst_time_stamp, |
898 &dst_end_time_stamp, !img)) { | 861 &dst_end_time_stamp, !img)) { |
899 if (size) { | 862 if (size) { |
900 vpx_codec_pts_t round, delta; | 863 vpx_codec_pts_t round, delta; |
901 vpx_codec_cx_pkt_t pkt; | 864 vpx_codec_cx_pkt_t pkt; |
902 VP9_COMP *const cpi = (VP9_COMP *)ctx->cpi; | 865 VP9_COMP *const cpi = (VP9_COMP *)ctx->cpi; |
903 | 866 |
904 // Pack invisible frames with the next visible frame | 867 // Pack invisible frames with the next visible frame |
905 if (cpi->common.show_frame == 0) { | 868 if (cpi->common.show_frame == 0 |
| 869 #ifdef CONFIG_SPATIAL_SVC |
| 870 || (cpi->use_svc && cpi->svc.number_temporal_layers == 1 && |
| 871 cpi->svc.spatial_layer_id < cpi->svc.number_spatial_layers - 1) |
| 872 #endif |
| 873 ) { |
906 if (ctx->pending_cx_data == 0) | 874 if (ctx->pending_cx_data == 0) |
907 ctx->pending_cx_data = cx_data; | 875 ctx->pending_cx_data = cx_data; |
908 ctx->pending_cx_data_sz += size; | 876 ctx->pending_cx_data_sz += size; |
909 ctx->pending_frame_sizes[ctx->pending_frame_count++] = size; | 877 ctx->pending_frame_sizes[ctx->pending_frame_count++] = size; |
910 ctx->pending_frame_magnitude |= size; | 878 ctx->pending_frame_magnitude |= size; |
911 cx_data += size; | 879 cx_data += size; |
912 cx_data_sz -= size; | 880 cx_data_sz -= size; |
913 continue; | 881 continue; |
914 } | 882 } |
915 | 883 |
916 // Add the frame packet to the list of returned packets. | 884 // Add the frame packet to the list of returned packets. |
917 round = (vpx_codec_pts_t)10000000 * ctx->cfg.g_timebase.num / 2 - 1; | 885 round = (vpx_codec_pts_t)10000000 * ctx->cfg.g_timebase.num / 2 - 1; |
918 delta = (dst_end_time_stamp - dst_time_stamp); | 886 delta = (dst_end_time_stamp - dst_time_stamp); |
919 pkt.kind = VPX_CODEC_CX_FRAME_PKT; | 887 pkt.kind = VPX_CODEC_CX_FRAME_PKT; |
920 pkt.data.frame.pts = | 888 pkt.data.frame.pts = |
921 (dst_time_stamp * ctx->cfg.g_timebase.den + round) | 889 (dst_time_stamp * ctx->cfg.g_timebase.den + round) |
922 / ctx->cfg.g_timebase.num / 10000000; | 890 / ctx->cfg.g_timebase.num / 10000000; |
923 pkt.data.frame.duration = (unsigned long) | 891 pkt.data.frame.duration = (unsigned long) |
924 ((delta * ctx->cfg.g_timebase.den + round) | 892 ((delta * ctx->cfg.g_timebase.den + round) |
925 / ctx->cfg.g_timebase.num / 10000000); | 893 / ctx->cfg.g_timebase.num / 10000000); |
926 pkt.data.frame.flags = lib_flags << 16; | 894 pkt.data.frame.flags = lib_flags << 16; |
927 | 895 |
928 if (lib_flags & FRAMEFLAGS_KEY) | 896 if (lib_flags & FRAMEFLAGS_KEY |
| 897 #ifdef CONFIG_SPATIAL_SVC |
| 898 || (cpi->use_svc && cpi->svc.number_temporal_layers == 1 && |
| 899 cpi->svc.layer_context[0].is_key_frame) |
| 900 #endif |
| 901 ) |
929 pkt.data.frame.flags |= VPX_FRAME_IS_KEY; | 902 pkt.data.frame.flags |= VPX_FRAME_IS_KEY; |
930 | 903 |
931 if (cpi->common.show_frame == 0) { | 904 if (cpi->common.show_frame == 0) { |
932 pkt.data.frame.flags |= VPX_FRAME_IS_INVISIBLE; | 905 pkt.data.frame.flags |= VPX_FRAME_IS_INVISIBLE; |
933 | 906 |
934 // This timestamp should be as close as possible to the | 907 // This timestamp should be as close as possible to the |
935 // prior PTS so that if a decoder uses pts to schedule when | 908 // prior PTS so that if a decoder uses pts to schedule when |
936 // to do this, we start right after last frame was decoded. | 909 // to do this, we start right after last frame was decoded. |
937 // Invisible frames have no duration. | 910 // Invisible frames have no duration. |
938 pkt.data.frame.pts = ((cpi->last_time_stamp_seen | 911 pkt.data.frame.pts = ((cpi->last_time_stamp_seen |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1158 return VPX_CODEC_INVALID_PARAM; | 1131 return VPX_CODEC_INVALID_PARAM; |
1159 } | 1132 } |
1160 return VPX_CODEC_OK; | 1133 return VPX_CODEC_OK; |
1161 } | 1134 } |
1162 | 1135 |
1163 static vpx_codec_err_t ctrl_set_svc_parameters(vpx_codec_alg_priv_t *ctx, | 1136 static vpx_codec_err_t ctrl_set_svc_parameters(vpx_codec_alg_priv_t *ctx, |
1164 va_list args) { | 1137 va_list args) { |
1165 VP9_COMP *const cpi = ctx->cpi; | 1138 VP9_COMP *const cpi = ctx->cpi; |
1166 vpx_svc_parameters_t *const params = va_arg(args, vpx_svc_parameters_t *); | 1139 vpx_svc_parameters_t *const params = va_arg(args, vpx_svc_parameters_t *); |
1167 | 1140 |
1168 if (params == NULL) | 1141 if (params == NULL || params->spatial_layer < 0 || |
| 1142 params->spatial_layer >= cpi->svc.number_spatial_layers) |
1169 return VPX_CODEC_INVALID_PARAM; | 1143 return VPX_CODEC_INVALID_PARAM; |
1170 | 1144 |
1171 cpi->svc.spatial_layer_id = params->spatial_layer; | 1145 if (params->spatial_layer == 0) { |
1172 cpi->svc.temporal_layer_id = params->temporal_layer; | 1146 int i; |
| 1147 for (i = 0; i < cpi->svc.number_spatial_layers; ++i) { |
| 1148 cpi->svc.layer_context[i].svc_params_received.spatial_layer = -1; |
| 1149 } |
| 1150 } |
1173 | 1151 |
1174 cpi->lst_fb_idx = params->lst_fb_idx; | 1152 cpi->svc.layer_context[params->spatial_layer].svc_params_received = |
1175 cpi->gld_fb_idx = params->gld_fb_idx; | 1153 *params; |
1176 cpi->alt_fb_idx = params->alt_fb_idx; | |
1177 | |
1178 if (vp9_set_size_literal(ctx->cpi, params->width, params->height) != 0) | |
1179 return VPX_CODEC_INVALID_PARAM; | |
1180 | |
1181 ctx->cfg.rc_max_quantizer = params->max_quantizer; | |
1182 ctx->cfg.rc_min_quantizer = params->min_quantizer; | |
1183 | |
1184 set_encoder_config(&ctx->oxcf, &ctx->cfg, &ctx->extra_cfg); | |
1185 vp9_change_config(ctx->cpi, &ctx->oxcf); | |
1186 | 1154 |
1187 return VPX_CODEC_OK; | 1155 return VPX_CODEC_OK; |
1188 } | 1156 } |
1189 | 1157 |
1190 static vpx_codec_ctrl_fn_map_t encoder_ctrl_maps[] = { | 1158 static vpx_codec_ctrl_fn_map_t encoder_ctrl_maps[] = { |
1191 {VP8_COPY_REFERENCE, ctrl_copy_reference}, | 1159 {VP8_COPY_REFERENCE, ctrl_copy_reference}, |
1192 {VP8E_UPD_ENTROPY, ctrl_update_entropy}, | 1160 {VP8E_UPD_ENTROPY, ctrl_update_entropy}, |
1193 {VP8E_UPD_REFERENCE, ctrl_update_reference}, | 1161 {VP8E_UPD_REFERENCE, ctrl_update_reference}, |
1194 {VP8E_USE_REFERENCE, ctrl_use_reference}, | 1162 {VP8E_USE_REFERENCE, ctrl_use_reference}, |
1195 | 1163 |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1313 { // NOLINT | 1281 { // NOLINT |
1314 encoder_usage_cfg_map, // vpx_codec_enc_cfg_map_t | 1282 encoder_usage_cfg_map, // vpx_codec_enc_cfg_map_t |
1315 encoder_encode, // vpx_codec_encode_fn_t | 1283 encoder_encode, // vpx_codec_encode_fn_t |
1316 encoder_get_cxdata, // vpx_codec_get_cx_data_fn_t | 1284 encoder_get_cxdata, // vpx_codec_get_cx_data_fn_t |
1317 encoder_set_config, // vpx_codec_enc_config_set_fn_t | 1285 encoder_set_config, // vpx_codec_enc_config_set_fn_t |
1318 NOT_IMPLEMENTED, // vpx_codec_get_global_headers_fn_t | 1286 NOT_IMPLEMENTED, // vpx_codec_get_global_headers_fn_t |
1319 encoder_get_preview, // vpx_codec_get_preview_frame_fn_t | 1287 encoder_get_preview, // vpx_codec_get_preview_frame_fn_t |
1320 NOT_IMPLEMENTED // vpx_codec_enc_mr_get_mem_loc_fn_t | 1288 NOT_IMPLEMENTED // vpx_codec_enc_mr_get_mem_loc_fn_t |
1321 } | 1289 } |
1322 }; | 1290 }; |
OLD | NEW |