Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(107)

Side by Side Diff: source/libvpx/vpx/src/svc_encodeframe.c

Issue 232133009: libvpx: Pull from upstream (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « source/libvpx/vpx/exports_enc ('k') | source/libvpx/vpx/src/vpx_encoder.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
11 /** 11 /**
12 * @file 12 * @file
13 * VP9 SVC encoding support via libvpx 13 * VP9 SVC encoding support via libvpx
14 */ 14 */
15 15
16 #include <assert.h>
16 #include <math.h> 17 #include <math.h>
17 #include <stdarg.h> 18 #include <stdarg.h>
18 #include <stdio.h> 19 #include <stdio.h>
19 #include <stdlib.h> 20 #include <stdlib.h>
20 #include <string.h> 21 #include <string.h>
21 #define VPX_DISABLE_CTRL_TYPECHECKS 1 22 #define VPX_DISABLE_CTRL_TYPECHECKS 1
22 #define VPX_CODEC_DISABLE_COMPAT 1 23 #define VPX_CODEC_DISABLE_COMPAT 1
23 #include "vpx/svc_context.h" 24 #include "vpx/svc_context.h"
24 #include "vpx/vp8cx.h" 25 #include "vpx/vp8cx.h"
25 #include "vpx/vpx_encoder.h" 26 #include "vpx/vpx_encoder.h"
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 int frame_within_gop; 75 int frame_within_gop;
75 vpx_enc_frame_flags_t enc_frame_flags; 76 vpx_enc_frame_flags_t enc_frame_flags;
76 int layers; 77 int layers;
77 int layer; 78 int layer;
78 int is_keyframe; 79 int is_keyframe;
79 80
80 size_t frame_size; 81 size_t frame_size;
81 size_t buffer_size; 82 size_t buffer_size;
82 void *buffer; 83 void *buffer;
83 84
85 char *rc_stats_buf;
86 size_t rc_stats_buf_size;
87 size_t rc_stats_buf_used;
88
84 char message_buffer[2048]; 89 char message_buffer[2048];
85 vpx_codec_ctx_t *codec_ctx; 90 vpx_codec_ctx_t *codec_ctx;
86 } SvcInternal; 91 } SvcInternal;
87 92
88 // Superframe is used to generate an index of individual frames (i.e., layers) 93 // Superframe is used to generate an index of individual frames (i.e., layers)
89 struct Superframe { 94 struct Superframe {
90 int count; 95 int count;
91 uint32_t sizes[SUPERFRAME_SLOTS]; 96 uint32_t sizes[SUPERFRAME_SLOTS];
92 uint32_t magnitude; 97 uint32_t magnitude;
93 uint8_t buffer[SUPERFRAME_BUFFER_SIZE]; 98 uint8_t buffer[SUPERFRAME_BUFFER_SIZE];
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
512 si->kf_dist = enc_cfg->kf_max_dist; 517 si->kf_dist = enc_cfg->kf_max_dist;
513 518
514 if (svc_ctx->spatial_layers == 0) 519 if (svc_ctx->spatial_layers == 0)
515 svc_ctx->spatial_layers = VPX_SS_DEFAULT_LAYERS; 520 svc_ctx->spatial_layers = VPX_SS_DEFAULT_LAYERS;
516 if (svc_ctx->spatial_layers < 1 || 521 if (svc_ctx->spatial_layers < 1 ||
517 svc_ctx->spatial_layers > VPX_SS_MAX_LAYERS) { 522 svc_ctx->spatial_layers > VPX_SS_MAX_LAYERS) {
518 svc_log(svc_ctx, SVC_LOG_ERROR, "spatial layers: invalid value: %d\n", 523 svc_log(svc_ctx, SVC_LOG_ERROR, "spatial layers: invalid value: %d\n",
519 svc_ctx->spatial_layers); 524 svc_ctx->spatial_layers);
520 return VPX_CODEC_INVALID_PARAM; 525 return VPX_CODEC_INVALID_PARAM;
521 } 526 }
522 // use SvcInternal value for number of layers to enable forcing single layer
523 // for first frame
524 si->layers = svc_ctx->spatial_layers;
525 527
526 res = parse_quantizer_values(svc_ctx, si->quantizers, 0); 528 res = parse_quantizer_values(svc_ctx, si->quantizers, 0);
527 if (res != VPX_CODEC_OK) return res; 529 if (res != VPX_CODEC_OK) return res;
528 530
529 res = parse_quantizer_values(svc_ctx, si->quantizers_keyframe, 1); 531 res = parse_quantizer_values(svc_ctx, si->quantizers_keyframe, 1);
530 if (res != VPX_CODEC_OK) 532 if (res != VPX_CODEC_OK)
531 memcpy(si->quantizer_keyframe, si->quantizer, sizeof(si->quantizer)); 533 memcpy(si->quantizer_keyframe, si->quantizer, sizeof(si->quantizer));
532 534
533 res = parse_scale_factors(svc_ctx, si->scale_factors); 535 res = parse_scale_factors(svc_ctx, si->scale_factors);
534 if (res != VPX_CODEC_OK) return res; 536 if (res != VPX_CODEC_OK) return res;
535 537
536 // parse aggregate command line options 538 // Parse aggregate command line options. Options must start with
539 // "layers=xx" then followed by other options
537 res = parse_options(svc_ctx, si->options); 540 res = parse_options(svc_ctx, si->options);
538 if (res != VPX_CODEC_OK) return res; 541 if (res != VPX_CODEC_OK) return res;
539 542
543 si->layers = svc_ctx->spatial_layers;
544
540 // Assign target bitrate for each layer. We calculate the ratio 545 // Assign target bitrate for each layer. We calculate the ratio
541 // from the resolution for now. 546 // from the resolution for now.
542 // TODO(Minghai): Optimize the mechanism of allocating bits after 547 // TODO(Minghai): Optimize the mechanism of allocating bits after
543 // implementing svc two pass rate control. 548 // implementing svc two pass rate control.
544 if (si->layers > 1) { 549 if (si->layers > 1) {
545 int i; 550 int i;
546 float total = 0; 551 float total = 0;
547 float alloc_ratio[VPX_SS_MAX_LAYERS] = {0}; 552 float alloc_ratio[VPX_SS_MAX_LAYERS] = {0};
548 553
554 assert(si->layers <= VPX_SS_MAX_LAYERS);
549 for (i = 0; i < si->layers; ++i) { 555 for (i = 0; i < si->layers; ++i) {
550 int pos = i + VPX_SS_MAX_LAYERS - svc_ctx->spatial_layers; 556 int pos = i + VPX_SS_MAX_LAYERS - svc_ctx->spatial_layers;
551 if (pos < VPX_SS_MAX_LAYERS && si->scaling_factor_den[pos] > 0) { 557 if (pos < VPX_SS_MAX_LAYERS && si->scaling_factor_den[pos] > 0) {
552 alloc_ratio[i] = (float)(si->scaling_factor_num[pos] * 1.0 / 558 alloc_ratio[i] = (float)(si->scaling_factor_num[pos] * 1.0 /
553 si->scaling_factor_den[pos]); 559 si->scaling_factor_den[pos]);
554 560
555 alloc_ratio[i] *= alloc_ratio[i]; 561 alloc_ratio[i] *= alloc_ratio[i];
556 total += alloc_ratio[i]; 562 total += alloc_ratio[i];
557 } 563 }
558 } 564 }
559 565
560 for (i = 0; i < si->layers; ++i) { 566 for (i = 0; i < si->layers; ++i) {
561 if (total > 0) { 567 if (total > 0) {
562 enc_cfg->ss_target_bitrate[i] = (unsigned int) 568 enc_cfg->ss_target_bitrate[i] = (unsigned int)
563 (enc_cfg->rc_target_bitrate * alloc_ratio[i] / total); 569 (enc_cfg->rc_target_bitrate * alloc_ratio[i] / total);
564 } 570 }
565 } 571 }
566 } 572 }
567 573
568 // modify encoder configuration 574 // modify encoder configuration
569 enc_cfg->ss_number_layers = si->layers; 575 enc_cfg->ss_number_layers = si->layers;
570 enc_cfg->ts_number_layers = 1; // Temporal layers not used in this encoder. 576 enc_cfg->ts_number_layers = 1; // Temporal layers not used in this encoder.
571 enc_cfg->kf_mode = VPX_KF_DISABLED; 577 enc_cfg->kf_mode = VPX_KF_DISABLED;
572 enc_cfg->g_pass = VPX_RC_ONE_PASS;
573 // Lag in frames not currently supported 578 // Lag in frames not currently supported
574 enc_cfg->g_lag_in_frames = 0; 579 enc_cfg->g_lag_in_frames = 0;
575 580
576 // TODO(ivanmaltz): determine if these values need to be set explicitly for 581 // TODO(ivanmaltz): determine if these values need to be set explicitly for
577 // svc, or if the normal default/override mechanism can be used 582 // svc, or if the normal default/override mechanism can be used
578 enc_cfg->rc_dropframe_thresh = 0; 583 enc_cfg->rc_dropframe_thresh = 0;
579 enc_cfg->rc_end_usage = VPX_CBR; 584 enc_cfg->rc_end_usage = VPX_CBR;
580 enc_cfg->rc_resize_allowed = 0; 585 enc_cfg->rc_resize_allowed = 0;
581 enc_cfg->rc_min_quantizer = 33; 586
582 enc_cfg->rc_max_quantizer = 33; 587 if (enc_cfg->g_pass == VPX_RC_ONE_PASS) {
588 enc_cfg->rc_min_quantizer = 33;
589 enc_cfg->rc_max_quantizer = 33;
590 }
591
583 enc_cfg->rc_undershoot_pct = 100; 592 enc_cfg->rc_undershoot_pct = 100;
584 enc_cfg->rc_overshoot_pct = 15; 593 enc_cfg->rc_overshoot_pct = 15;
585 enc_cfg->rc_buf_initial_sz = 500; 594 enc_cfg->rc_buf_initial_sz = 500;
586 enc_cfg->rc_buf_optimal_sz = 600; 595 enc_cfg->rc_buf_optimal_sz = 600;
587 enc_cfg->rc_buf_sz = 1000; 596 enc_cfg->rc_buf_sz = 1000;
588 enc_cfg->g_error_resilient = 1; 597 enc_cfg->g_error_resilient = 1;
589 598
590 // Initialize codec 599 // Initialize codec
591 res = vpx_codec_enc_init(codec_ctx, iface, enc_cfg, VPX_CODEC_USE_PSNR); 600 res = vpx_codec_enc_init(codec_ctx, iface, enc_cfg, VPX_CODEC_USE_PSNR);
592 if (res != VPX_CODEC_OK) { 601 if (res != VPX_CODEC_OK) {
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
772 layer += 1; 781 layer += 1;
773 } 782 }
774 } 783 }
775 if (VPX_CODEC_OK != vpx_svc_get_layer_resolution(svc_ctx, layer, 784 if (VPX_CODEC_OK != vpx_svc_get_layer_resolution(svc_ctx, layer,
776 &svc_params.width, 785 &svc_params.width,
777 &svc_params.height)) { 786 &svc_params.height)) {
778 svc_log(svc_ctx, SVC_LOG_ERROR, "vpx_svc_get_layer_resolution failed\n"); 787 svc_log(svc_ctx, SVC_LOG_ERROR, "vpx_svc_get_layer_resolution failed\n");
779 } 788 }
780 layer_index = layer + VPX_SS_MAX_LAYERS - si->layers; 789 layer_index = layer + VPX_SS_MAX_LAYERS - si->layers;
781 790
782 if (vpx_svc_is_keyframe(svc_ctx)) { 791 if (codec_ctx->config.enc->g_pass == VPX_RC_ONE_PASS) {
783 svc_params.min_quantizer = si->quantizer_keyframe[layer_index]; 792 if (vpx_svc_is_keyframe(svc_ctx)) {
784 svc_params.max_quantizer = si->quantizer_keyframe[layer_index]; 793 svc_params.min_quantizer = si->quantizer_keyframe[layer_index];
794 svc_params.max_quantizer = si->quantizer_keyframe[layer_index];
795 } else {
796 svc_params.min_quantizer = si->quantizer[layer_index];
797 svc_params.max_quantizer = si->quantizer[layer_index];
798 }
785 } else { 799 } else {
786 svc_params.min_quantizer = si->quantizer[layer_index]; 800 svc_params.min_quantizer = codec_ctx->config.enc->rc_min_quantizer;
787 svc_params.max_quantizer = si->quantizer[layer_index]; 801 svc_params.max_quantizer = codec_ctx->config.enc->rc_max_quantizer;
788 } 802 }
789 803
790 svc_params.distance_from_i_frame = si->frame_within_gop; 804 svc_params.distance_from_i_frame = si->frame_within_gop;
791 805
792 // Use buffer i for layer i LST 806 // Use buffer i for layer i LST
793 svc_params.lst_fb_idx = si->layer; 807 svc_params.lst_fb_idx = si->layer;
794 808
795 // Use buffer i-1 for layer i Alt (Inter-layer prediction) 809 // Use buffer i-1 for layer i Alt (Inter-layer prediction)
796 if (si->layer != 0) { 810 if (si->layer != 0) {
797 const int use_higher_layer = 811 const int use_higher_layer =
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
838 vpx_codec_err_t vpx_svc_encode(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx, 852 vpx_codec_err_t vpx_svc_encode(SvcContext *svc_ctx, vpx_codec_ctx_t *codec_ctx,
839 struct vpx_image *rawimg, vpx_codec_pts_t pts, 853 struct vpx_image *rawimg, vpx_codec_pts_t pts,
840 int64_t duration, int deadline) { 854 int64_t duration, int deadline) {
841 vpx_codec_err_t res; 855 vpx_codec_err_t res;
842 vpx_codec_iter_t iter; 856 vpx_codec_iter_t iter;
843 const vpx_codec_cx_pkt_t *cx_pkt; 857 const vpx_codec_cx_pkt_t *cx_pkt;
844 struct LayerData *cx_layer_list = NULL; 858 struct LayerData *cx_layer_list = NULL;
845 struct LayerData *layer_data; 859 struct LayerData *layer_data;
846 struct Superframe superframe; 860 struct Superframe superframe;
847 SvcInternal *const si = get_svc_internal(svc_ctx); 861 SvcInternal *const si = get_svc_internal(svc_ctx);
848 if (svc_ctx == NULL || codec_ctx == NULL || rawimg == NULL || si == NULL) { 862 if (svc_ctx == NULL || codec_ctx == NULL || si == NULL) {
849 return VPX_CODEC_INVALID_PARAM; 863 return VPX_CODEC_INVALID_PARAM;
850 } 864 }
851 865
852 memset(&superframe, 0, sizeof(superframe)); 866 memset(&superframe, 0, sizeof(superframe));
853 svc_log_reset(svc_ctx); 867 svc_log_reset(svc_ctx);
868 si->rc_stats_buf_used = 0;
854 869
855 si->layers = svc_ctx->spatial_layers; 870 si->layers = svc_ctx->spatial_layers;
856 if (si->frame_within_gop >= si->kf_dist || 871 if (si->frame_within_gop >= si->kf_dist ||
857 si->encode_frame_count == 0) { 872 si->encode_frame_count == 0) {
858 si->frame_within_gop = 0; 873 si->frame_within_gop = 0;
859 } 874 }
860 si->is_keyframe = (si->frame_within_gop == 0); 875 si->is_keyframe = (si->frame_within_gop == 0);
861 si->frame_size = 0; 876 si->frame_size = 0;
862 877
863 svc_log(svc_ctx, SVC_LOG_DEBUG, 878 if (rawimg != NULL) {
864 "vpx_svc_encode layers: %d, frame_count: %d, frame_within_gop: %d\n", 879 svc_log(svc_ctx, SVC_LOG_DEBUG,
865 si->layers, si->encode_frame_count, si->frame_within_gop); 880 "vpx_svc_encode layers: %d, frame_count: %d, "
881 "frame_within_gop: %d\n", si->layers, si->encode_frame_count,
882 si->frame_within_gop);
883 }
866 884
867 // encode each layer 885 // encode each layer
868 for (si->layer = 0; si->layer < si->layers; ++si->layer) { 886 for (si->layer = 0; si->layer < si->layers; ++si->layer) {
869 if (svc_ctx->encoding_mode == ALT_INTER_LAYER_PREDICTION_IP && 887 if (svc_ctx->encoding_mode == ALT_INTER_LAYER_PREDICTION_IP &&
870 si->is_keyframe && (si->layer == 1 || si->layer == 3)) { 888 si->is_keyframe && (si->layer == 1 || si->layer == 3)) {
871 svc_log(svc_ctx, SVC_LOG_DEBUG, "Skip encoding layer %d\n", si->layer); 889 svc_log(svc_ctx, SVC_LOG_DEBUG, "Skip encoding layer %d\n", si->layer);
872 continue; 890 continue;
873 } 891 }
874 calculate_enc_frame_flags(svc_ctx);
875 892
876 set_svc_parameters(svc_ctx, codec_ctx); 893 if (rawimg != NULL) {
894 calculate_enc_frame_flags(svc_ctx);
895 set_svc_parameters(svc_ctx, codec_ctx);
896 }
877 897
878 res = vpx_codec_encode(codec_ctx, rawimg, pts, (uint32_t)duration, 898 res = vpx_codec_encode(codec_ctx, rawimg, pts, (uint32_t)duration,
879 si->enc_frame_flags, deadline); 899 si->enc_frame_flags, deadline);
880 if (res != VPX_CODEC_OK) { 900 if (res != VPX_CODEC_OK) {
881 return res; 901 return res;
882 } 902 }
883 // save compressed data 903 // save compressed data
884 iter = NULL; 904 iter = NULL;
885 while ((cx_pkt = vpx_codec_get_cx_data(codec_ctx, &iter))) { 905 while ((cx_pkt = vpx_codec_get_cx_data(codec_ctx, &iter))) {
886 switch (cx_pkt->kind) { 906 switch (cx_pkt->kind) {
(...skipping 29 matching lines...) Expand all
916 "%2.3f %2.3f %2.3f %2.3f \n", 936 "%2.3f %2.3f %2.3f %2.3f \n",
917 si->encode_frame_count, si->layer, 937 si->encode_frame_count, si->layer,
918 cx_pkt->data.psnr.sse[0], cx_pkt->data.psnr.sse[1], 938 cx_pkt->data.psnr.sse[0], cx_pkt->data.psnr.sse[1],
919 cx_pkt->data.psnr.sse[2], cx_pkt->data.psnr.sse[3]); 939 cx_pkt->data.psnr.sse[2], cx_pkt->data.psnr.sse[3]);
920 for (i = 0; i < COMPONENTS; i++) { 940 for (i = 0; i < COMPONENTS; i++) {
921 si->psnr_sum[si->layer][i] += cx_pkt->data.psnr.psnr[i]; 941 si->psnr_sum[si->layer][i] += cx_pkt->data.psnr.psnr[i];
922 si->sse_sum[si->layer][i] += cx_pkt->data.psnr.sse[i]; 942 si->sse_sum[si->layer][i] += cx_pkt->data.psnr.sse[i];
923 } 943 }
924 break; 944 break;
925 } 945 }
946 case VPX_CODEC_STATS_PKT: {
947 size_t new_size = si->rc_stats_buf_used +
948 cx_pkt->data.twopass_stats.sz;
949
950 if (new_size > si->rc_stats_buf_size) {
951 char *p = (char*)realloc(si->rc_stats_buf, new_size);
952 if (p == NULL) {
953 svc_log(svc_ctx, SVC_LOG_ERROR, "Error allocating stats buf\n");
954 break;
955 }
956 si->rc_stats_buf = p;
957 si->rc_stats_buf_size = new_size;
958 }
959
960 memcpy(si->rc_stats_buf + si->rc_stats_buf_used,
961 cx_pkt->data.twopass_stats.buf, cx_pkt->data.twopass_stats.sz);
962 si->rc_stats_buf_used += cx_pkt->data.twopass_stats.sz;
963 break;
964 }
926 default: { 965 default: {
927 break; 966 break;
928 } 967 }
929 } 968 }
930 } 969 }
970 if (rawimg == NULL) {
971 break;
972 }
931 } 973 }
932 // add superframe index to layer data list 974 if (codec_ctx->config.enc->g_pass != VPX_RC_FIRST_PASS) {
933 sf_create_index(&superframe); 975 // add superframe index to layer data list
934 layer_data = ld_create(superframe.buffer, superframe.index_size); 976 sf_create_index(&superframe);
935 ld_list_add(&cx_layer_list, layer_data); 977 layer_data = ld_create(superframe.buffer, superframe.index_size);
978 ld_list_add(&cx_layer_list, layer_data);
936 979
937 // get accumulated size of layer data 980 // get accumulated size of layer data
938 si->frame_size = ld_list_get_buffer_size(cx_layer_list); 981 si->frame_size = ld_list_get_buffer_size(cx_layer_list);
939 if (si->frame_size == 0) return VPX_CODEC_ERROR; 982 if (si->frame_size > 0) {
983 // all layers encoded, create single buffer with concatenated layers
984 if (si->frame_size > si->buffer_size) {
985 free(si->buffer);
986 si->buffer = malloc(si->frame_size);
987 if (si->buffer == NULL) {
988 ld_list_free(cx_layer_list);
989 return VPX_CODEC_MEM_ERROR;
990 }
991 si->buffer_size = si->frame_size;
992 }
993 // copy layer data into packet
994 ld_list_copy_to_buffer(cx_layer_list, (uint8_t *)si->buffer);
940 995
941 // all layers encoded, create single buffer with concatenated layers
942 if (si->frame_size > si->buffer_size) {
943 free(si->buffer);
944 si->buffer = malloc(si->frame_size);
945 if (si->buffer == NULL) {
946 ld_list_free(cx_layer_list); 996 ld_list_free(cx_layer_list);
947 return VPX_CODEC_MEM_ERROR; 997
998 svc_log(svc_ctx, SVC_LOG_DEBUG, "SVC frame: %d, kf: %d, size: %d, "
999 "pts: %d\n", si->encode_frame_count, si->is_keyframe,
1000 (int)si->frame_size, (int)pts);
948 } 1001 }
949 si->buffer_size = si->frame_size;
950 } 1002 }
951 // copy layer data into packet
952 ld_list_copy_to_buffer(cx_layer_list, (uint8_t *)si->buffer);
953
954 ld_list_free(cx_layer_list);
955
956 svc_log(svc_ctx, SVC_LOG_DEBUG, "SVC frame: %d, kf: %d, size: %d, pts: %d\n",
957 si->encode_frame_count, si->is_keyframe, (int)si->frame_size,
958 (int)pts);
959 ++si->frame_within_gop; 1003 ++si->frame_within_gop;
960 ++si->encode_frame_count; 1004 ++si->encode_frame_count;
961 1005
962 return VPX_CODEC_OK; 1006 return VPX_CODEC_OK;
963 } 1007 }
964 1008
965 const char *vpx_svc_get_message(const SvcContext *svc_ctx) { 1009 const char *vpx_svc_get_message(const SvcContext *svc_ctx) {
966 const SvcInternal *const si = get_const_svc_internal(svc_ctx); 1010 const SvcInternal *const si = get_const_svc_internal(svc_ctx);
967 if (svc_ctx == NULL || si == NULL) return NULL; 1011 if (svc_ctx == NULL || si == NULL) return NULL;
968 return si->message_buffer; 1012 return si->message_buffer;
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
1070 } 1114 }
1071 1115
1072 void vpx_svc_release(SvcContext *svc_ctx) { 1116 void vpx_svc_release(SvcContext *svc_ctx) {
1073 SvcInternal *si; 1117 SvcInternal *si;
1074 if (svc_ctx == NULL) return; 1118 if (svc_ctx == NULL) return;
1075 // do not use get_svc_internal as it will unnecessarily allocate an 1119 // do not use get_svc_internal as it will unnecessarily allocate an
1076 // SvcInternal if it was not already allocated 1120 // SvcInternal if it was not already allocated
1077 si = (SvcInternal *)svc_ctx->internal; 1121 si = (SvcInternal *)svc_ctx->internal;
1078 if (si != NULL) { 1122 if (si != NULL) {
1079 free(si->buffer); 1123 free(si->buffer);
1124 if (si->rc_stats_buf) {
1125 free(si->rc_stats_buf);
1126 }
1080 free(si); 1127 free(si);
1081 svc_ctx->internal = NULL; 1128 svc_ctx->internal = NULL;
1082 } 1129 }
1083 } 1130 }
1131
1132 size_t vpx_svc_get_rc_stats_buffer_size(const SvcContext *svc_ctx) {
1133 const SvcInternal *const si = get_const_svc_internal(svc_ctx);
1134 if (svc_ctx == NULL || si == NULL) return 0;
1135 return si->rc_stats_buf_used;
1136 }
1137
1138 char *vpx_svc_get_rc_stats_buffer(const SvcContext *svc_ctx) {
1139 const SvcInternal *const si = get_const_svc_internal(svc_ctx);
1140 if (svc_ctx == NULL || si == NULL) return NULL;
1141 return si->rc_stats_buf;
1142 }
1143
1144
OLDNEW
« no previous file with comments | « source/libvpx/vpx/exports_enc ('k') | source/libvpx/vpx/src/vpx_encoder.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698