| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2013 The WebM project authors. All Rights Reserved. | 2 * Copyright (c) 2013 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 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 88 | 88 |
| 89 // One encoded frame layer | 89 // One encoded frame layer |
| 90 struct LayerData { | 90 struct LayerData { |
| 91 void *buf; // compressed data buffer | 91 void *buf; // compressed data buffer |
| 92 size_t size; // length of compressed data | 92 size_t size; // length of compressed data |
| 93 struct LayerData *next; | 93 struct LayerData *next; |
| 94 }; | 94 }; |
| 95 | 95 |
| 96 // create LayerData from encoder output | 96 // create LayerData from encoder output |
| 97 static struct LayerData *ld_create(void *buf, size_t size) { | 97 static struct LayerData *ld_create(void *buf, size_t size) { |
| 98 struct LayerData *const layer_data = malloc(sizeof(*layer_data)); | 98 struct LayerData *const layer_data = |
| 99 (struct LayerData *)malloc(sizeof(*layer_data)); |
| 99 if (layer_data == NULL) { | 100 if (layer_data == NULL) { |
| 100 return NULL; | 101 return NULL; |
| 101 } | 102 } |
| 102 layer_data->buf = malloc(size); | 103 layer_data->buf = malloc(size); |
| 103 if (layer_data->buf == NULL) { | 104 if (layer_data->buf == NULL) { |
| 104 free(layer_data); | 105 free(layer_data); |
| 105 return NULL; | 106 return NULL; |
| 106 } | 107 } |
| 107 memcpy(layer_data->buf, buf, size); | 108 memcpy(layer_data->buf, buf, size); |
| 108 layer_data->size = size; | 109 layer_data->size = size; |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 *bufp++ = this_sz & 0xff; | 195 *bufp++ = this_sz & 0xff; |
| 195 this_sz >>= 8; | 196 this_sz >>= 8; |
| 196 } | 197 } |
| 197 } | 198 } |
| 198 *bufp++ = marker; | 199 *bufp++ = marker; |
| 199 } | 200 } |
| 200 | 201 |
| 201 static SvcInternal *get_svc_internal(SvcContext *svc_ctx) { | 202 static SvcInternal *get_svc_internal(SvcContext *svc_ctx) { |
| 202 if (svc_ctx == NULL) return NULL; | 203 if (svc_ctx == NULL) return NULL; |
| 203 if (svc_ctx->internal == NULL) { | 204 if (svc_ctx->internal == NULL) { |
| 204 SvcInternal *const si = malloc(sizeof(*si)); | 205 SvcInternal *const si = (SvcInternal *)malloc(sizeof(*si)); |
| 205 if (si != NULL) { | 206 if (si != NULL) { |
| 206 memset(si, 0, sizeof(*si)); | 207 memset(si, 0, sizeof(*si)); |
| 207 } | 208 } |
| 208 svc_ctx->internal = si; | 209 svc_ctx->internal = si; |
| 209 } | 210 } |
| 210 return svc_ctx->internal; | 211 return (SvcInternal *)svc_ctx->internal; |
| 211 } | 212 } |
| 212 | 213 |
| 213 static const SvcInternal *get_const_svc_internal(const SvcContext *svc_ctx) { | 214 static const SvcInternal *get_const_svc_internal(const SvcContext *svc_ctx) { |
| 214 if (svc_ctx == NULL) return NULL; | 215 if (svc_ctx == NULL) return NULL; |
| 215 return svc_ctx->internal; | 216 return (const SvcInternal *)svc_ctx->internal; |
| 216 } | 217 } |
| 217 | 218 |
| 218 static void svc_log_reset(SvcContext *svc_ctx) { | 219 static void svc_log_reset(SvcContext *svc_ctx) { |
| 219 SvcInternal *const si = (SvcInternal *)svc_ctx->internal; | 220 SvcInternal *const si = (SvcInternal *)svc_ctx->internal; |
| 220 si->message_buffer[0] = '\0'; | 221 si->message_buffer[0] = '\0'; |
| 221 } | 222 } |
| 222 | 223 |
| 223 static int svc_log(SvcContext *svc_ctx, int level, const char *fmt, ...) { | 224 static int svc_log(SvcContext *svc_ctx, int level, const char *fmt, ...) { |
| 224 char buf[512]; | 225 char buf[512]; |
| 225 int retval = 0; | 226 int retval = 0; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 } | 266 } |
| 266 | 267 |
| 267 static vpx_codec_err_t parse_quantizer_values(SvcContext *svc_ctx, | 268 static vpx_codec_err_t parse_quantizer_values(SvcContext *svc_ctx, |
| 268 const char *quantizer_values) { | 269 const char *quantizer_values) { |
| 269 char *input_string; | 270 char *input_string; |
| 270 char *token; | 271 char *token; |
| 271 const char *delim = ","; | 272 const char *delim = ","; |
| 272 char *save_ptr; | 273 char *save_ptr; |
| 273 int found = 0; | 274 int found = 0; |
| 274 int i, q; | 275 int i, q; |
| 275 int res = VPX_CODEC_OK; | 276 vpx_codec_err_t res = VPX_CODEC_OK; |
| 276 SvcInternal *const si = get_svc_internal(svc_ctx); | 277 SvcInternal *const si = get_svc_internal(svc_ctx); |
| 277 | 278 |
| 278 if (quantizer_values == NULL || strlen(quantizer_values) == 0) { | 279 if (quantizer_values == NULL || strlen(quantizer_values) == 0) { |
| 279 input_string = strdup(DEFAULT_QUANTIZER_VALUES); | 280 input_string = strdup(DEFAULT_QUANTIZER_VALUES); |
| 280 } else { | 281 } else { |
| 281 input_string = strdup(quantizer_values); | 282 input_string = strdup(quantizer_values); |
| 282 } | 283 } |
| 283 | 284 |
| 284 token = strtok_r(input_string, delim, &save_ptr); | 285 token = strtok_r(input_string, delim, &save_ptr); |
| 285 for (i = 0; i < svc_ctx->spatial_layers; ++i) { | 286 for (i = 0; i < svc_ctx->spatial_layers; ++i) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 315 | 316 |
| 316 static vpx_codec_err_t parse_scale_factors(SvcContext *svc_ctx, | 317 static vpx_codec_err_t parse_scale_factors(SvcContext *svc_ctx, |
| 317 const char *scale_factors) { | 318 const char *scale_factors) { |
| 318 char *input_string; | 319 char *input_string; |
| 319 char *token; | 320 char *token; |
| 320 const char *delim = ","; | 321 const char *delim = ","; |
| 321 char *save_ptr; | 322 char *save_ptr; |
| 322 int found = 0; | 323 int found = 0; |
| 323 int i; | 324 int i; |
| 324 int64_t num, den; | 325 int64_t num, den; |
| 325 int res = VPX_CODEC_OK; | 326 vpx_codec_err_t res = VPX_CODEC_OK; |
| 326 SvcInternal *const si = get_svc_internal(svc_ctx); | 327 SvcInternal *const si = get_svc_internal(svc_ctx); |
| 327 | 328 |
| 328 if (scale_factors == NULL || strlen(scale_factors) == 0) { | 329 if (scale_factors == NULL || strlen(scale_factors) == 0) { |
| 329 input_string = strdup(DEFAULT_SCALE_FACTORS); | 330 input_string = strdup(DEFAULT_SCALE_FACTORS); |
| 330 } else { | 331 } else { |
| 331 input_string = strdup(scale_factors); | 332 input_string = strdup(scale_factors); |
| 332 } | 333 } |
| 333 token = strtok_r(input_string, delim, &save_ptr); | 334 token = strtok_r(input_string, delim, &save_ptr); |
| 334 for (i = 0; i < svc_ctx->spatial_layers; ++i) { | 335 for (i = 0; i < svc_ctx->spatial_layers; ++i) { |
| 335 num = den = 0; | 336 num = den = 0; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 374 * Format: encoding-mode=<svc_mode>,layers=<layer_count> | 375 * Format: encoding-mode=<svc_mode>,layers=<layer_count> |
| 375 * scale-factors=<n1>/<d1>,<n2>/<d2>,... | 376 * scale-factors=<n1>/<d1>,<n2>/<d2>,... |
| 376 * quantizers=<q1>,<q2>,... | 377 * quantizers=<q1>,<q2>,... |
| 377 * svc_mode = [i|ip|alt_ip|gf] | 378 * svc_mode = [i|ip|alt_ip|gf] |
| 378 */ | 379 */ |
| 379 static vpx_codec_err_t parse_options(SvcContext *svc_ctx, const char *options) { | 380 static vpx_codec_err_t parse_options(SvcContext *svc_ctx, const char *options) { |
| 380 char *input_string; | 381 char *input_string; |
| 381 char *option_name; | 382 char *option_name; |
| 382 char *option_value; | 383 char *option_value; |
| 383 char *input_ptr; | 384 char *input_ptr; |
| 384 int res = VPX_CODEC_OK; | 385 vpx_codec_err_t res = VPX_CODEC_OK; |
| 385 | 386 |
| 386 if (options == NULL) return VPX_CODEC_OK; | 387 if (options == NULL) return VPX_CODEC_OK; |
| 387 input_string = strdup(options); | 388 input_string = strdup(options); |
| 388 | 389 |
| 389 // parse option name | 390 // parse option name |
| 390 option_name = strtok_r(input_string, "=", &input_ptr); | 391 option_name = strtok_r(input_string, "=", &input_ptr); |
| 391 while (option_name != NULL) { | 392 while (option_name != NULL) { |
| 392 // parse option value | 393 // parse option value |
| 393 option_value = strtok_r(NULL, " ", &input_ptr); | 394 option_value = strtok_r(NULL, " ", &input_ptr); |
| 394 if (option_value == NULL) { | 395 if (option_value == NULL) { |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 492 | 493 |
| 493 res = parse_scale_factors(svc_ctx, si->scale_factors); | 494 res = parse_scale_factors(svc_ctx, si->scale_factors); |
| 494 if (res != VPX_CODEC_OK) return res; | 495 if (res != VPX_CODEC_OK) return res; |
| 495 | 496 |
| 496 // parse aggregate command line options | 497 // parse aggregate command line options |
| 497 res = parse_options(svc_ctx, si->options); | 498 res = parse_options(svc_ctx, si->options); |
| 498 if (res != VPX_CODEC_OK) return res; | 499 if (res != VPX_CODEC_OK) return res; |
| 499 | 500 |
| 500 // modify encoder configuration | 501 // modify encoder configuration |
| 501 enc_cfg->ss_number_layers = si->layers; | 502 enc_cfg->ss_number_layers = si->layers; |
| 503 enc_cfg->ts_number_layers = 1; // Temporal layers not used in this encoder. |
| 502 enc_cfg->kf_mode = VPX_KF_DISABLED; | 504 enc_cfg->kf_mode = VPX_KF_DISABLED; |
| 503 enc_cfg->g_pass = VPX_RC_ONE_PASS; | 505 enc_cfg->g_pass = VPX_RC_ONE_PASS; |
| 504 // Lag in frames not currently supported | 506 // Lag in frames not currently supported |
| 505 enc_cfg->g_lag_in_frames = 0; | 507 enc_cfg->g_lag_in_frames = 0; |
| 506 | 508 |
| 507 // TODO(ivanmaltz): determine if these values need to be set explicitly for | 509 // TODO(ivanmaltz): determine if these values need to be set explicitly for |
| 508 // svc, or if the normal default/override mechanism can be used | 510 // svc, or if the normal default/override mechanism can be used |
| 509 enc_cfg->rc_dropframe_thresh = 0; | 511 enc_cfg->rc_dropframe_thresh = 0; |
| 510 enc_cfg->rc_end_usage = VPX_CBR; | 512 enc_cfg->rc_end_usage = VPX_CBR; |
| 511 enc_cfg->rc_resize_allowed = 0; | 513 enc_cfg->rc_resize_allowed = 0; |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 return VPX_CODEC_OK; | 686 return VPX_CODEC_OK; |
| 685 } | 687 } |
| 686 | 688 |
| 687 static void set_svc_parameters(SvcContext *svc_ctx, | 689 static void set_svc_parameters(SvcContext *svc_ctx, |
| 688 vpx_codec_ctx_t *codec_ctx) { | 690 vpx_codec_ctx_t *codec_ctx) { |
| 689 int layer, layer_index; | 691 int layer, layer_index; |
| 690 vpx_svc_parameters_t svc_params; | 692 vpx_svc_parameters_t svc_params; |
| 691 SvcInternal *const si = get_svc_internal(svc_ctx); | 693 SvcInternal *const si = get_svc_internal(svc_ctx); |
| 692 | 694 |
| 693 memset(&svc_params, 0, sizeof(svc_params)); | 695 memset(&svc_params, 0, sizeof(svc_params)); |
| 694 svc_params.layer = si->layer; | 696 svc_params.temporal_layer = 0; |
| 697 svc_params.spatial_layer = si->layer; |
| 695 svc_params.flags = si->enc_frame_flags; | 698 svc_params.flags = si->enc_frame_flags; |
| 696 | 699 |
| 697 layer = si->layer; | 700 layer = si->layer; |
| 698 if (svc_ctx->encoding_mode == ALT_INTER_LAYER_PREDICTION_IP && | 701 if (svc_ctx->encoding_mode == ALT_INTER_LAYER_PREDICTION_IP && |
| 699 si->frame_within_gop == 0) { | 702 si->frame_within_gop == 0) { |
| 700 // layers 1 & 3 don't exist in this mode, use the higher one | 703 // layers 1 & 3 don't exist in this mode, use the higher one |
| 701 if (layer == 0 || layer == 2) { | 704 if (layer == 0 || layer == 2) { |
| 702 layer += 1; | 705 layer += 1; |
| 703 } | 706 } |
| 704 } | 707 } |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 810 case VPX_CODEC_CX_FRAME_PKT: { | 813 case VPX_CODEC_CX_FRAME_PKT: { |
| 811 const uint32_t frame_pkt_size = (uint32_t)(cx_pkt->data.frame.sz); | 814 const uint32_t frame_pkt_size = (uint32_t)(cx_pkt->data.frame.sz); |
| 812 si->bytes_in_layer[si->layer] += frame_pkt_size; | 815 si->bytes_in_layer[si->layer] += frame_pkt_size; |
| 813 svc_log(svc_ctx, SVC_LOG_DEBUG, | 816 svc_log(svc_ctx, SVC_LOG_DEBUG, |
| 814 "SVC frame: %d, layer: %d, size: %u\n", | 817 "SVC frame: %d, layer: %d, size: %u\n", |
| 815 si->encode_frame_count, si->layer, frame_pkt_size); | 818 si->encode_frame_count, si->layer, frame_pkt_size); |
| 816 layer_data = | 819 layer_data = |
| 817 ld_create(cx_pkt->data.frame.buf, (size_t)frame_pkt_size); | 820 ld_create(cx_pkt->data.frame.buf, (size_t)frame_pkt_size); |
| 818 if (layer_data == NULL) { | 821 if (layer_data == NULL) { |
| 819 svc_log(svc_ctx, SVC_LOG_ERROR, "Error allocating LayerData\n"); | 822 svc_log(svc_ctx, SVC_LOG_ERROR, "Error allocating LayerData\n"); |
| 820 return 0; | 823 return VPX_CODEC_OK; |
| 821 } | 824 } |
| 822 ld_list_add(&cx_layer_list, layer_data); | 825 ld_list_add(&cx_layer_list, layer_data); |
| 823 | 826 |
| 824 // save layer size in superframe index | 827 // save layer size in superframe index |
| 825 superframe.sizes[superframe.count++] = frame_pkt_size; | 828 superframe.sizes[superframe.count++] = frame_pkt_size; |
| 826 superframe.magnitude |= frame_pkt_size; | 829 superframe.magnitude |= frame_pkt_size; |
| 827 break; | 830 break; |
| 828 } | 831 } |
| 829 case VPX_CODEC_PSNR_PKT: { | 832 case VPX_CODEC_PSNR_PKT: { |
| 830 svc_log(svc_ctx, SVC_LOG_DEBUG, | 833 svc_log(svc_ctx, SVC_LOG_DEBUG, |
| (...skipping 24 matching lines...) Expand all Loading... |
| 855 if (si->frame_size > si->buffer_size) { | 858 if (si->frame_size > si->buffer_size) { |
| 856 free(si->buffer); | 859 free(si->buffer); |
| 857 si->buffer = malloc(si->frame_size); | 860 si->buffer = malloc(si->frame_size); |
| 858 if (si->buffer == NULL) { | 861 if (si->buffer == NULL) { |
| 859 ld_list_free(cx_layer_list); | 862 ld_list_free(cx_layer_list); |
| 860 return VPX_CODEC_MEM_ERROR; | 863 return VPX_CODEC_MEM_ERROR; |
| 861 } | 864 } |
| 862 si->buffer_size = si->frame_size; | 865 si->buffer_size = si->frame_size; |
| 863 } | 866 } |
| 864 // copy layer data into packet | 867 // copy layer data into packet |
| 865 ld_list_copy_to_buffer(cx_layer_list, si->buffer); | 868 ld_list_copy_to_buffer(cx_layer_list, (uint8_t *)si->buffer); |
| 866 | 869 |
| 867 ld_list_free(cx_layer_list); | 870 ld_list_free(cx_layer_list); |
| 868 | 871 |
| 869 svc_log(svc_ctx, SVC_LOG_DEBUG, "SVC frame: %d, kf: %d, size: %d, pts: %d\n", | 872 svc_log(svc_ctx, SVC_LOG_DEBUG, "SVC frame: %d, kf: %d, size: %d, pts: %d\n", |
| 870 si->encode_frame_count, si->is_keyframe, (int)si->frame_size, | 873 si->encode_frame_count, si->is_keyframe, (int)si->frame_size, |
| 871 (int)pts); | 874 (int)pts); |
| 872 ++si->frame_within_gop; | 875 ++si->frame_within_gop; |
| 873 ++si->encode_frame_count; | 876 ++si->encode_frame_count; |
| 874 | 877 |
| 875 return VPX_CODEC_OK; | 878 return VPX_CODEC_OK; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 953 if (svc_ctx == NULL) return; | 956 if (svc_ctx == NULL) return; |
| 954 // do not use get_svc_internal as it will unnecessarily allocate an | 957 // do not use get_svc_internal as it will unnecessarily allocate an |
| 955 // SvcInternal if it was not already allocated | 958 // SvcInternal if it was not already allocated |
| 956 si = (SvcInternal *)svc_ctx->internal; | 959 si = (SvcInternal *)svc_ctx->internal; |
| 957 if (si != NULL) { | 960 if (si != NULL) { |
| 958 free(si->buffer); | 961 free(si->buffer); |
| 959 free(si); | 962 free(si); |
| 960 svc_ctx->internal = NULL; | 963 svc_ctx->internal = NULL; |
| 961 } | 964 } |
| 962 } | 965 } |
| OLD | NEW |