/* * Copyright (c) 2019, Alliance for Open Media. All rights reserved. * * This source code is subject to the terms of the BSD 2 Clause License and * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License * was not distributed with this source code in the LICENSE file, you can * obtain it at www.aomedia.org/license/software. If the Alliance for Open * Media Patent License 1.0 was not distributed with this source code in the * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
staticvoid ref_config_rps(aom_svc_ref_frame_config_t *ref_frame_config, int frame_cnt, int rps_recovery_frame) { // Pattern of 3 references with (ALTREF and GOLDEN) trailing // LAST by 4 and 8 frame, with some switching logic to // only predict from longer-term reference. int last_idx = 0; int last_idx_refresh = 0; int gld_idx = 0; int alt_ref_idx = 0; constint lag_alt = 4; constint lag_gld = 8; constint sh = 8; // slots 0 - 7. // Moving index slot for last: 0 - (sh - 1) if (frame_cnt > 1) last_idx = (frame_cnt - 1) % sh; // Moving index for refresh of last: one ahead for next frame.
last_idx_refresh = frame_cnt % sh; // Moving index for gld_ref, lag behind current by lag_gld if (frame_cnt > lag_gld) gld_idx = (frame_cnt - lag_gld) % sh; // Moving index for alt_ref, lag behind LAST by lag_alt frames. if (frame_cnt > lag_alt) alt_ref_idx = (frame_cnt - lag_alt) % sh; // Set the ref_idx. // Default all references (7) to slot for last. // LAST_FRAME (0), LAST2_FRAME(1), LAST3_FRAME(2), GOLDEN_FRAME(3), // BWDREF_FRAME(4), ALTREF2_FRAME(5), ALTREF_FRAME(6). for (int i = 0; i < INTER_REFS_PER_FRAME; i++)
ref_frame_config->ref_idx[i] = last_idx; // Set the ref_idx for the relevant references.
ref_frame_config->ref_idx[0] = last_idx;
ref_frame_config->ref_idx[1] = last_idx_refresh;
ref_frame_config->ref_idx[3] = gld_idx;
ref_frame_config->ref_idx[6] = alt_ref_idx; // Refresh this slot, which will become LAST on next frame.
ref_frame_config->refresh[last_idx_refresh] = 1; // Reference LAST, ALTREF, and GOLDEN
ref_frame_config->reference[0] = 1;
ref_frame_config->reference[6] = 1;
ref_frame_config->reference[3] = 1; if (frame_cnt == rps_recovery_frame) { // Switch to only reference GOLDEN at recovery_frame.
ref_frame_config->reference[0] = 0;
ref_frame_config->reference[6] = 0;
ref_frame_config->reference[3] = 1;
} elseif (frame_cnt > rps_recovery_frame &&
frame_cnt < rps_recovery_frame + 8) { // Go back to predicting from LAST, and after // 8 frames (GOLDEN is 8 frames aways) go back // to predicting off GOLDEN and ALTREF.
ref_frame_config->reference[0] = 1;
ref_frame_config->reference[6] = 0;
ref_frame_config->reference[3] = 0;
}
}
// Simulcast mode for 3 spatial and 3 temporal layers. // No inter-layer predicton, only prediction is temporal and single // reference (LAST). // No overlap in buffer slots between spatial layers. So for example, // SL0 only uses slots 0 and 1. // SL1 only uses slots 2 and 3. // SL2 only uses slots 4 and 5. // All 7 references for each inter-frame must only access buffer slots // for that spatial layer. // On key (super)frames: SL1 and SL2 must have no references set // and must refresh all the slots for that layer only (so 2 and 3 // for SL1, 4 and 5 for SL2). The base SL0 will be labelled internally // as a Key frame (refresh all slots). SL1/SL2 will be labelled // internally as Intra-only frames that allow that stream to be decoded. // These conditions will allow for each spatial stream to be // independently decodeable. staticvoid ref_config_simulcast3SL3TL(
aom_svc_ref_frame_config_t *ref_frame_config,
aom_svc_layer_id_t *layer_id, int is_key_frame, int superframe_cnt) { int i; // Initialize all references to 0 (don't use reference). for (i = 0; i < INTER_REFS_PER_FRAME; i++)
ref_frame_config->reference[i] = 0; // Initialize as no refresh/update for all slots. for (i = 0; i < REF_FRAMES; i++) ref_frame_config->refresh[i] = 0; for (i = 0; i < INTER_REFS_PER_FRAME; i++) ref_frame_config->ref_idx[i] = 0;
if (is_key_frame) { if (layer_id->spatial_layer_id == 0) { // Assign LAST/GOLDEN to slot 0/1. // Refesh slots 0 and 1 for SL0. // SL0: this will get set to KEY frame internally.
ref_frame_config->ref_idx[0] = 0;
ref_frame_config->ref_idx[3] = 1;
ref_frame_config->refresh[0] = 1;
ref_frame_config->refresh[1] = 1;
} elseif (layer_id->spatial_layer_id == 1) { // Assign LAST/GOLDEN to slot 2/3. // Refesh slots 2 and 3 for SL1. // This will get set to Intra-only frame internally.
ref_frame_config->ref_idx[0] = 2;
ref_frame_config->ref_idx[3] = 3;
ref_frame_config->refresh[2] = 1;
ref_frame_config->refresh[3] = 1;
} elseif (layer_id->spatial_layer_id == 2) { // Assign LAST/GOLDEN to slot 4/5. // Refresh slots 4 and 5 for SL2. // This will get set to Intra-only frame internally.
ref_frame_config->ref_idx[0] = 4;
ref_frame_config->ref_idx[3] = 5;
ref_frame_config->refresh[4] = 1;
ref_frame_config->refresh[5] = 1;
}
} elseif (superframe_cnt % 4 == 0) { // Base temporal layer: TL0
layer_id->temporal_layer_id = 0; if (layer_id->spatial_layer_id == 0) { // SL0 // Reference LAST. Assign all references to either slot // 0 or 1. Here we assign LAST to slot 0, all others to 1. // Update slot 0 (LAST).
ref_frame_config->reference[0] = 1; for (i = 0; i < INTER_REFS_PER_FRAME; i++)
ref_frame_config->ref_idx[i] = 1;
ref_frame_config->ref_idx[0] = 0;
ref_frame_config->refresh[0] = 1;
} elseif (layer_id->spatial_layer_id == 1) { // SL1 // Reference LAST. Assign all references to either slot // 2 or 3. Here we assign LAST to slot 2, all others to 3. // Update slot 2 (LAST).
ref_frame_config->reference[0] = 1; for (i = 0; i < INTER_REFS_PER_FRAME; i++)
ref_frame_config->ref_idx[i] = 3;
ref_frame_config->ref_idx[0] = 2;
ref_frame_config->refresh[2] = 1;
} elseif (layer_id->spatial_layer_id == 2) { // SL2 // Reference LAST. Assign all references to either slot // 4 or 5. Here we assign LAST to slot 4, all others to 5. // Update slot 4 (LAST).
ref_frame_config->reference[0] = 1; for (i = 0; i < INTER_REFS_PER_FRAME; i++)
ref_frame_config->ref_idx[i] = 5;
ref_frame_config->ref_idx[0] = 4;
ref_frame_config->refresh[4] = 1;
}
} elseif ((superframe_cnt - 1) % 4 == 0) { // First top temporal enhancement layer: TL2
layer_id->temporal_layer_id = 2; if (layer_id->spatial_layer_id == 0) { // SL0 // Reference LAST (slot 0). Assign other references to slot 1. // No update/refresh on any slots.
ref_frame_config->reference[0] = 1; for (i = 0; i < INTER_REFS_PER_FRAME; i++)
ref_frame_config->ref_idx[i] = 1;
ref_frame_config->ref_idx[0] = 0;
} elseif (layer_id->spatial_layer_id == 1) { // SL1 // Reference LAST (slot 2). Assign other references to slot 3. // No update/refresh on any slots.
ref_frame_config->reference[0] = 1; for (i = 0; i < INTER_REFS_PER_FRAME; i++)
ref_frame_config->ref_idx[i] = 3;
ref_frame_config->ref_idx[0] = 2;
} elseif (layer_id->spatial_layer_id == 2) { // SL2 // Reference LAST (slot 4). Assign other references to slot 4. // No update/refresh on any slots.
ref_frame_config->reference[0] = 1; for (i = 0; i < INTER_REFS_PER_FRAME; i++)
ref_frame_config->ref_idx[i] = 5;
ref_frame_config->ref_idx[0] = 4;
}
} elseif ((superframe_cnt - 2) % 4 == 0) { // Middle temporal enhancement layer: TL1
layer_id->temporal_layer_id = 1; if (layer_id->spatial_layer_id == 0) { // SL0 // Reference LAST (slot 0). // Set GOLDEN to slot 1 and update slot 1. // This will be used as reference for next TL2.
ref_frame_config->reference[0] = 1; for (i = 0; i < INTER_REFS_PER_FRAME; i++)
ref_frame_config->ref_idx[i] = 1;
ref_frame_config->ref_idx[0] = 0;
ref_frame_config->refresh[1] = 1;
} elseif (layer_id->spatial_layer_id == 1) { // SL1 // Reference LAST (slot 2). // Set GOLDEN to slot 3 and update slot 3. // This will be used as reference for next TL2.
ref_frame_config->reference[0] = 1; for (i = 0; i < INTER_REFS_PER_FRAME; i++)
ref_frame_config->ref_idx[i] = 3;
ref_frame_config->ref_idx[0] = 2;
ref_frame_config->refresh[3] = 1;
} elseif (layer_id->spatial_layer_id == 2) { // SL2 // Reference LAST (slot 4). // Set GOLDEN to slot 5 and update slot 5. // This will be used as reference for next TL2.
ref_frame_config->reference[0] = 1; for (i = 0; i < INTER_REFS_PER_FRAME; i++)
ref_frame_config->ref_idx[i] = 5;
ref_frame_config->ref_idx[0] = 4;
ref_frame_config->refresh[5] = 1;
}
} elseif ((superframe_cnt - 3) % 4 == 0) { // Second top temporal enhancement layer: TL2
layer_id->temporal_layer_id = 2; if (layer_id->spatial_layer_id == 0) { // SL0 // Reference LAST (slot 1). Assign other references to slot 0. // No update/refresh on any slots.
ref_frame_config->reference[0] = 1; for (i = 0; i < INTER_REFS_PER_FRAME; i++)
ref_frame_config->ref_idx[i] = 0;
ref_frame_config->ref_idx[0] = 1;
} elseif (layer_id->spatial_layer_id == 1) { // SL1 // Reference LAST (slot 3). Assign other references to slot 2. // No update/refresh on any slots.
ref_frame_config->reference[0] = 1; for (i = 0; i < INTER_REFS_PER_FRAME; i++)
ref_frame_config->ref_idx[i] = 2;
ref_frame_config->ref_idx[0] = 3;
} elseif (layer_id->spatial_layer_id == 2) { // SL2 // Reference LAST (slot 5). Assign other references to slot 4. // No update/refresh on any slots.
ref_frame_config->reference[0] = 1; for (i = 0; i < INTER_REFS_PER_FRAME; i++)
ref_frame_config->ref_idx[i] = 4;
ref_frame_config->ref_idx[0] = 5;
}
}
}
// 3 spatial and 3 temporal layer. // Overlap in the buffer slot updates: the slots 3 and 4 updated by // first TL2 are reused for update in TL1 superframe. staticvoid ref_config_3SL3TL(aom_svc_ref_frame_config_t *ref_frame_config,
aom_svc_layer_id_t *layer_id, int is_key_frame, int superframe_cnt) { if (superframe_cnt % 4 == 0) { // Base temporal layer.
layer_id->temporal_layer_id = 0; if (layer_id->spatial_layer_id == 0) { // Reference LAST, update LAST. // Set all buffer_idx to 0. for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 0;
ref_frame_config->refresh[0] = 1;
} elseif (layer_id->spatial_layer_id == 1) { // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 1, // GOLDEN (and all other refs) to slot 0. // Update slot 1 (LAST). for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 0;
ref_frame_config->ref_idx[0] = 1;
ref_frame_config->refresh[1] = 1;
} elseif (layer_id->spatial_layer_id == 2) { // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 2, // GOLDEN (and all other refs) to slot 1. // Update slot 2 (LAST). for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 1;
ref_frame_config->ref_idx[0] = 2;
ref_frame_config->refresh[2] = 1;
}
} elseif ((superframe_cnt - 1) % 4 == 0) { // First top temporal enhancement layer.
layer_id->temporal_layer_id = 2; if (layer_id->spatial_layer_id == 0) { // Reference LAST (slot 0). // Set GOLDEN to slot 3 and update slot 3. // Set all other buffer_idx to slot 0. for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 0;
ref_frame_config->ref_idx[3] = 3;
ref_frame_config->refresh[3] = 1;
} elseif (layer_id->spatial_layer_id == 1) { // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 1, // GOLDEN (and all other refs) to slot 3. // Set LAST2 to slot 4 and Update slot 4. for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 3;
ref_frame_config->ref_idx[0] = 1;
ref_frame_config->ref_idx[1] = 4;
ref_frame_config->refresh[4] = 1;
} elseif (layer_id->spatial_layer_id == 2) { // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 2, // GOLDEN (and all other refs) to slot 4. // No update. for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 4;
ref_frame_config->ref_idx[0] = 2;
}
} elseif ((superframe_cnt - 2) % 4 == 0) { // Middle temporal enhancement layer.
layer_id->temporal_layer_id = 1; if (layer_id->spatial_layer_id == 0) { // Reference LAST. // Set all buffer_idx to 0. // Set GOLDEN to slot 3 and update slot 3. for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 0;
ref_frame_config->ref_idx[3] = 3;
ref_frame_config->refresh[3] = 1;
} elseif (layer_id->spatial_layer_id == 1) { // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 1, // GOLDEN (and all other refs) to slot 3. // Set LAST2 to slot 4 and update slot 4. for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 3;
ref_frame_config->ref_idx[0] = 1;
ref_frame_config->ref_idx[2] = 4;
ref_frame_config->refresh[4] = 1;
} elseif (layer_id->spatial_layer_id == 2) { // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 2, // GOLDEN (and all other refs) to slot 4. // Set LAST2 to slot 5 and update slot 5. for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 4;
ref_frame_config->ref_idx[0] = 2;
ref_frame_config->ref_idx[2] = 5;
ref_frame_config->refresh[5] = 1;
}
} elseif ((superframe_cnt - 3) % 4 == 0) { // Second top temporal enhancement layer.
layer_id->temporal_layer_id = 2; if (layer_id->spatial_layer_id == 0) { // Set LAST to slot 3 and reference LAST. // Set GOLDEN to slot 3 and update slot 3. // Set all other buffer_idx to 0. for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 0;
ref_frame_config->ref_idx[0] = 3;
ref_frame_config->ref_idx[3] = 3;
ref_frame_config->refresh[3] = 1;
} elseif (layer_id->spatial_layer_id == 1) { // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 4, // GOLDEN to slot 3. Set LAST2 to slot 4 and update slot 4. for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 0;
ref_frame_config->ref_idx[0] = 4;
ref_frame_config->ref_idx[3] = 3;
ref_frame_config->ref_idx[1] = 4;
ref_frame_config->refresh[4] = 1;
} elseif (layer_id->spatial_layer_id == 2) { // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 5, // GOLDEN to slot 4. No update. for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 0;
ref_frame_config->ref_idx[0] = 5;
ref_frame_config->ref_idx[3] = 4;
}
} if (layer_id->spatial_layer_id > 0) { // Always reference GOLDEN (inter-layer prediction).
ref_frame_config->reference[3] = 1; if (is_key_frame && layer_id->spatial_layer_id > 0) { // On superframes whose base is key: remove LAST since GOLDEN // is used as reference.
ref_frame_config->reference[0] = 0;
}
}
}
// Layer pattern configuration. virtualint set_layer_pattern( int frame_cnt, aom_svc_layer_id_t *layer_id,
aom_svc_ref_frame_config_t *ref_frame_config,
aom_svc_ref_frame_comp_pred_t *ref_frame_comp_pred, int spatial_layer, int multi_ref, int comp_pred, int is_key_frame, int dynamic_enable_disable_mode, int rps_mode, int rps_recovery_frame, int simulcast_mode, bool use_last_as_scaled, bool use_last_as_scaled_single_ref) { int lag_index = 0; int base_count = frame_cnt >> 2;
layer_id->spatial_layer_id = spatial_layer; // Set the reference map buffer idx for the 7 references: // LAST_FRAME (0), LAST2_FRAME(1), LAST3_FRAME(2), GOLDEN_FRAME(3), // BWDREF_FRAME(4), ALTREF2_FRAME(5), ALTREF_FRAME(6). for (int i = 0; i < INTER_REFS_PER_FRAME; i++) {
ref_frame_config->ref_idx[i] = i;
ref_frame_config->reference[i] = 0;
} for (int i = 0; i < REF_FRAMES; i++) ref_frame_config->refresh[i] = 0; if (comp_pred) {
ref_frame_comp_pred->use_comp_pred[0] = 1; // GOLDEN_LAST
ref_frame_comp_pred->use_comp_pred[1] = 1; // LAST2_LAST
ref_frame_comp_pred->use_comp_pred[2] = 1; // ALTREF_LAST
} // Set layer_flags to 0 when using ref_frame_config->reference. int layer_flags = 0; // Always reference LAST.
ref_frame_config->reference[0] = 1; if (number_temporal_layers_ == 1 && number_spatial_layers_ == 1) {
layer_id->temporal_layer_id = 0;
ref_frame_config->refresh[0] = 1; if (rps_mode)
ref_config_rps(ref_frame_config, frame_cnt, rps_recovery_frame); if (intra_only_single_layer_) { // This repros the crash in Bug: 363016123.
ref_frame_config->ref_idx[0] = 0;
ref_frame_config->ref_idx[3] = 1;
ref_frame_config->ref_idx[6] = 2; if (frame_cnt == 1) { for (int i = 0; i < INTER_REFS_PER_FRAME; i++)
ref_frame_config->reference[i] = 0;
}
}
} if (number_temporal_layers_ == 2 && number_spatial_layers_ == 1) { // 2-temporal layer. // 1 3 5 // 0 2 4 // Keep golden fixed at slot 3.
base_count = frame_cnt >> 1;
ref_frame_config->ref_idx[3] = 3; // Cyclically refresh slots 5, 6, 7, for lag alt ref.
lag_index = 5; if (base_count > 0) {
lag_index = 5 + (base_count % 3); if (frame_cnt % 2 != 0) lag_index = 5 + ((base_count + 1) % 3);
} // Set the altref slot to lag_index.
ref_frame_config->ref_idx[6] = lag_index; if (frame_cnt % 2 == 0) {
layer_id->temporal_layer_id = 0; // Update LAST on layer 0, reference LAST.
ref_frame_config->refresh[0] = 1;
ref_frame_config->reference[0] = 1; // Refresh lag_index slot, needed for lagging golen.
ref_frame_config->refresh[lag_index] = 1; // Refresh GOLDEN every x base layer frames. if (base_count % 32 == 0) ref_frame_config->refresh[3] = 1;
} else {
layer_id->temporal_layer_id = 1; // No updates on layer 1, reference LAST (TL0).
ref_frame_config->reference[0] = 1;
} // Always reference golden and altref on TL0. if (layer_id->temporal_layer_id == 0) {
ref_frame_config->reference[3] = 1;
ref_frame_config->reference[6] = 1;
}
} elseif (number_temporal_layers_ == 3 && number_spatial_layers_ == 1) { // 3-layer: // 1 3 5 7 // 2 6 // 0 4 8 if (multi_ref) { // Keep golden fixed at slot 3.
ref_frame_config->ref_idx[3] = 3; // Cyclically refresh slots 4, 5, 6, 7, for lag altref.
lag_index = 4 + (base_count % 4); // Set the altref slot to lag_index.
ref_frame_config->ref_idx[6] = lag_index;
} if (frame_cnt % 4 == 0) { // Base layer.
layer_id->temporal_layer_id = 0; // Update LAST on layer 0, reference LAST and GF.
ref_frame_config->refresh[0] = 1;
ref_frame_config->reference[3] = 1; if (multi_ref) { // Refresh GOLDEN every x ~10 base layer frames. if (base_count % 10 == 0) ref_frame_config->refresh[3] = 1; // Refresh lag_index slot, needed for lagging altref.
ref_frame_config->refresh[lag_index] = 1;
}
} elseif ((frame_cnt - 1) % 4 == 0) {
layer_id->temporal_layer_id = 2; // First top layer: no updates, only reference LAST (TL0).
} elseif ((frame_cnt - 2) % 4 == 0) {
layer_id->temporal_layer_id = 1; // Middle layer (TL1): update LAST2, only reference LAST (TL0).
ref_frame_config->refresh[1] = 1;
} elseif ((frame_cnt - 3) % 4 == 0) {
layer_id->temporal_layer_id = 2; // Second top layer: no updates, only reference LAST. // Set buffer idx for LAST to slot 1, since that was the slot // updated in previous frame. So LAST is TL1 frame.
ref_frame_config->ref_idx[0] = 1;
ref_frame_config->ref_idx[1] = 0;
} if (multi_ref) { // Every frame can reference GOLDEN AND ALTREF.
ref_frame_config->reference[3] = 1;
ref_frame_config->reference[6] = 1;
}
} elseif (number_temporal_layers_ == 1 && number_spatial_layers_ == 2) {
layer_id->temporal_layer_id = 0; if (layer_id->spatial_layer_id == 0) { // Reference LAST, update LAST. Keep LAST and GOLDEN in slots 0 and 3.
ref_frame_config->ref_idx[0] = 0;
ref_frame_config->ref_idx[3] = 3;
ref_frame_config->refresh[0] = 1;
} elseif (layer_id->spatial_layer_id == 1) { // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 3 // and GOLDEN to slot 0. Update slot 3 (LAST).
ref_frame_config->ref_idx[0] = 3;
ref_frame_config->ref_idx[3] = 0;
ref_frame_config->refresh[3] = 1;
} // Reference GOLDEN. if (layer_id->spatial_layer_id > 0) ref_frame_config->reference[3] = 1;
} elseif (number_temporal_layers_ == 1 && number_spatial_layers_ == 3) { // 3 spatial layers, 1 temporal. // Note for this case , we set the buffer idx for all references to be // either LAST or GOLDEN, which are always valid references, since decoder // will check if any of the 7 references is valid scale in // valid_ref_frame_size().
layer_id->temporal_layer_id = 0; if (layer_id->spatial_layer_id == 0) { // Reference LAST, update LAST. Set all other buffer_idx to 0. for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 0;
ref_frame_config->refresh[0] = 1;
} elseif (layer_id->spatial_layer_id == 1) { // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 1 // and GOLDEN (and all other refs) to slot 0. // Update slot 1 (LAST). for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 0;
ref_frame_config->ref_idx[0] = 1; if (use_last_as_scaled) { for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 1;
ref_frame_config->ref_idx[0] = 0;
ref_frame_config->ref_idx[3] = 1;
}
ref_frame_config->refresh[1] = 1;
} elseif (layer_id->spatial_layer_id == 2) { // Reference LAST and GOLDEN. Set buffer_idx for LAST to slot 2 // and GOLDEN (and all other refs) to slot 1. // Update slot 2 (LAST). for (int i = 0; i < 7; i++) ref_frame_config->ref_idx[i] = 1;
ref_frame_config->ref_idx[0] = 2;
ref_frame_config->refresh[2] = 1; if (multi_ref) {
ref_frame_config->ref_idx[6] = 7;
ref_frame_config->reference[6] = 1; if (base_count % 10 == 0) ref_frame_config->refresh[7] = 1;
}
} // Reference GOLDEN. if (layer_id->spatial_layer_id > 0) { if (use_last_as_scaled_single_ref)
ref_frame_config->reference[3] = 0; else
ref_frame_config->reference[3] = 1;
}
} elseif (number_temporal_layers_ == 3 && number_spatial_layers_ == 3) { if (simulcast_mode) {
ref_config_simulcast3SL3TL(ref_frame_config, layer_id, is_key_frame,
superframe_cnt_);
} else {
ref_config_3SL3TL(ref_frame_config, layer_id, is_key_frame,
superframe_cnt_); // Allow for top spatial layer to use additional temporal reference. // Additional reference is only updated on base temporal layer, every // 10 TL0 frames here. if (multi_ref && layer_id->spatial_layer_id == 2) {
ref_frame_config->ref_idx[6] = 7; if (!is_key_frame) ref_frame_config->reference[6] = 1; if (base_count % 10 == 0 && layer_id->temporal_layer_id == 0)
ref_frame_config->refresh[7] = 1;
}
}
} // If the top spatial layer is first-time encoded in mid-sequence // (i.e., dynamic_enable_disable_mode = 1), then don't predict from LAST, // since it will have been last updated on first key frame (SL0) and so // be different resolution from SL2. if (dynamic_enable_disable_mode == 1 &&
layer_id->spatial_layer_id == number_spatial_layers_ - 1)
ref_frame_config->reference[0] = 0; return layer_flags;
}
::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352,
288, 30, 1, 0, 300); constint bitrate_array[2] = { 200, 550 };
cfg_.rc_target_bitrate = bitrate_array[GET_PARAM(4)];
ResetModel();
number_temporal_layers_ = 3;
target_layer_bitrate_[0] = 50 * cfg_.rc_target_bitrate / 100;
target_layer_bitrate_[1] = 70 * cfg_.rc_target_bitrate / 100;
target_layer_bitrate_[2] = cfg_.rc_target_bitrate;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); for (int i = 0; i < number_temporal_layers_ * number_spatial_layers_; i++) {
ASSERT_GE(effective_datarate_tl[i], target_layer_bitrate_[i] * 0.60)
<< " The datarate for the file is lower than target by too much!";
ASSERT_LE(effective_datarate_tl[i], target_layer_bitrate_[i] * 1.60)
<< " The datarate for the file is greater than target by too much!";
} #if CONFIG_AV1_DECODER // Top temporal layers are non_reference, so exlcude them from // mismatch count, since loopfilter/cdef is not applied for these on // encoder side, but is always applied on decoder. // This means 150 = #frames(300) - #TL2_frames(150).
EXPECT_EQ((int)GetMismatchFrames(), 150); #endif
}
constint bitrate_array[2] = { 1000, 1500 };
cfg_.rc_target_bitrate = bitrate_array[GET_PARAM(4)];
ResetModel();
screen_mode_ = 1;
number_temporal_layers_ = 3;
number_spatial_layers_ = 1;
target_layer_bitrate_[0] = 50 * cfg_.rc_target_bitrate / 100;
target_layer_bitrate_[1] = 70 * cfg_.rc_target_bitrate / 100;
target_layer_bitrate_[2] = cfg_.rc_target_bitrate;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); for (int i = 0; i < number_temporal_layers_ * number_spatial_layers_; i++) {
ASSERT_GE(effective_datarate_tl[i], target_layer_bitrate_[i] * 0.40)
<< " The datarate for the file is lower than target by too much!";
ASSERT_LE(effective_datarate_tl[i], target_layer_bitrate_[i] * 2.0)
<< " The datarate for the file is greater than target by too much!";
} #if CONFIG_AV1_DECODER // Top temporal layers are non_reference, so exlcude them from // mismatch count, since loopfilter/cdef is not applied for these on // encoder side, but is always applied on decoder. // This means 30 = #frames(60) - #TL2_frames(30). // We use LE for screen since loopfilter level can become very small // or zero and then the frame is not a mismatch.
EXPECT_LE((int)GetMismatchFrames(), 30); #endif
}
constint bitrate_array[2] = { 60, 100 };
cfg_.rc_target_bitrate = bitrate_array[GET_PARAM(4)];
ResetModel();
screen_mode_ = 1;
number_temporal_layers_ = 2;
number_spatial_layers_ = 1;
target_layer_bitrate_[0] = 60 * cfg_.rc_target_bitrate / 100;
target_layer_bitrate_[1] = cfg_.rc_target_bitrate;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); for (int i = 0; i < number_temporal_layers_ * number_spatial_layers_; i++) {
ASSERT_GE(effective_datarate_tl[i], target_layer_bitrate_[i] * 0.75)
<< " The datarate for the file is lower than target by too much!";
ASSERT_LE(effective_datarate_tl[i], target_layer_bitrate_[i] * 1.8)
<< " The datarate for the file is greater than target by too much!";
} #if CONFIG_AV1_DECODER // Top temporal layers are non_reference, so exlcude them from // mismatch count, since loopfilter/cdef is not applied for these on // encoder side, but is always applied on decoder. // This means 300 = #frames(300) - #TL2_frames(150). // We use LE for screen since loopfilter level can become very small // or zero and then the frame is not a mismatch.
EXPECT_LE((int)GetMismatchFrames(), 150); #endif
}
constint bitrate_array[2] = { 200, 500 };
cfg_.rc_target_bitrate = bitrate_array[GET_PARAM(4)];
ResetModel();
screen_mode_ = 1;
number_temporal_layers_ = 1;
number_spatial_layers_ = 1;
target_layer_bitrate_[0] = cfg_.rc_target_bitrate;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); for (int i = 0; i < number_temporal_layers_ * number_spatial_layers_; i++) {
ASSERT_GE(effective_datarate_tl[i], target_layer_bitrate_[i] * 0.40)
<< " The datarate for the file is lower than target by too much!";
ASSERT_LE(effective_datarate_tl[i], target_layer_bitrate_[i] * 1.7)
<< " The datarate for the file is greater than target by too much!";
} #if CONFIG_AV1_DECODER
EXPECT_EQ((int)GetMismatchFrames(), 0); #endif
}
::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352,
288, 30, 1, 0, 300); constint bitrate_array[2] = { 300, 600 };
cfg_.rc_target_bitrate = bitrate_array[GET_PARAM(4)];
ResetModel();
intra_only_single_layer_ = true;
number_temporal_layers_ = 1;
number_spatial_layers_ = 1;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
ASSERT_GE(effective_datarate_tl[0], cfg_.rc_target_bitrate * 0.80)
<< " The datarate for the file is lower than target by too much!";
ASSERT_LE(effective_datarate_tl[0], cfg_.rc_target_bitrate * 1.60)
<< " The datarate for the file is greater than target by too much!";
}
::libaom_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60); constint bitrate_array[2] = { 600, 1200 };
cfg_.rc_target_bitrate = bitrate_array[GET_PARAM(4)];
ResetModel();
auto_tiles_ = 1;
number_temporal_layers_ = 2;
number_spatial_layers_ = 1;
target_layer_bitrate_[0] = 60 * cfg_.rc_target_bitrate / 100;
target_layer_bitrate_[1] = cfg_.rc_target_bitrate;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); for (int i = 0; i < number_temporal_layers_ * number_spatial_layers_; i++) {
ASSERT_GE(effective_datarate_tl[i], target_layer_bitrate_[i] * 0.70)
<< " The datarate for the file is lower than target by too much!";
ASSERT_LE(effective_datarate_tl[i], target_layer_bitrate_[i] * 1.45)
<< " The datarate for the file is greater than target by too much!";
}
}
::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352,
288, 30, 1, 0, 300); constint bitrate_array[2] = { 200, 550 };
cfg_.rc_target_bitrate = bitrate_array[GET_PARAM(4)];
ResetModel(); // Set error_resilience at frame level, with codec control, // on/1 for enahancement layers and off/0 for base layer frames.
set_frame_level_er_ = 1;
// Drop TL1 and TL2: #frames(300) - #TL0.
drop_frames_ = 300 - 300 / 4; int n = 0; for (int i = 0; i < 300; i++) { if (i % 4 != 0) {
drop_frames_list_[n] = i;
n++;
}
}
number_temporal_layers_ = 3;
target_layer_bitrate_[0] = 50 * cfg_.rc_target_bitrate / 100;
target_layer_bitrate_[1] = 70 * cfg_.rc_target_bitrate / 100;
target_layer_bitrate_[2] = cfg_.rc_target_bitrate;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); for (int i = 0; i < number_temporal_layers_ * number_spatial_layers_; i++) {
ASSERT_GE(effective_datarate_tl[i], target_layer_bitrate_[i] * 0.60)
<< " The datarate for the file is lower than target by too much!";
ASSERT_LE(effective_datarate_tl[i], target_layer_bitrate_[i] * 1.60)
<< " The datarate for the file is greater than target by too much!";
} #if CONFIG_AV1_DECODER // Test that no mismatches have been found.
std::cout << " Decoded frames: " << GetDecodedFrames() << "\n";
std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n";
EXPECT_EQ(300 - GetDecodedFrames(), drop_frames_);
EXPECT_EQ((int)GetMismatchFrames(), 0); #endif
}
::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352,
288, 30, 1, 0, 300); constint bitrate_array[2] = { 200, 550 };
cfg_.rc_target_bitrate = bitrate_array[GET_PARAM(4)];
ResetModel(); // Set error_resilience at frame level, with codec control, // on/1 for enahancement layers and off/0 for base layer frames.
set_frame_level_er_ = 1;
// Drop TL1 and TL2: for part of sequence. Start at first TL2 at // frame 101, and end at second T2 at frame 199. Frame 200 is TL0, // so we can continue decoding without mismatch (since LAST is the // only reference and error_resilient = 1 on TL1/TL2 frames). int n = 0; #if CONFIG_AV1_DECODER int num_nonref = 300 / 2; #endif for (int i = 101; i < 200; i++) { if (i % 4 != 0) {
drop_frames_list_[n] = i;
n++; #if CONFIG_AV1_DECODER if (i % 2 != 0) num_nonref -= 1; #endif
}
}
drop_frames_ = n;
number_temporal_layers_ = 3;
target_layer_bitrate_[0] = 50 * cfg_.rc_target_bitrate / 100;
target_layer_bitrate_[1] = 70 * cfg_.rc_target_bitrate / 100;
target_layer_bitrate_[2] = cfg_.rc_target_bitrate;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); for (int i = 0; i < number_temporal_layers_ * number_spatial_layers_; i++) {
ASSERT_GE(effective_datarate_tl[i], target_layer_bitrate_[i] * 0.60)
<< " The datarate for the file is lower than target by too much!";
ASSERT_LE(effective_datarate_tl[i], target_layer_bitrate_[i] * 1.60)
<< " The datarate for the file is greater than target by too much!";
} #if CONFIG_AV1_DECODER // Test that no mismatches have been found.
std::cout << " Decoded frames: " << GetDecodedFrames() << "\n";
std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n";
EXPECT_EQ(300 - GetDecodedFrames(), drop_frames_);
EXPECT_EQ((int)GetMismatchFrames(), num_nonref); #endif
}
// Set error_resilience off.
cfg_.g_error_resilient = 0;
// Drop TL1: for part of sequence. Start at first TL1 at // frame 101, and end at frame 199. Frame 200 is TL0, // so we can continue decoding without mismatch (since LAST is the // only reference). int n = 0; #if CONFIG_AV1_DECODER int num_nonref = 300 / 2; #endif for (int i = 101; i < 200; i++) { if (i % 2 != 0) {
drop_frames_list_[n] = i;
n++; #if CONFIG_AV1_DECODER if (i % 2 != 0) num_nonref -= 1; #endif
}
}
drop_frames_ = n;
number_temporal_layers_ = 2;
target_layer_bitrate_[0] = 70 * cfg_.rc_target_bitrate / 100;
target_layer_bitrate_[1] = cfg_.rc_target_bitrate;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); for (int i = 0; i < number_temporal_layers_ * number_spatial_layers_; i++) {
ASSERT_GE(effective_datarate_tl[i], target_layer_bitrate_[i] * 0.60)
<< " The datarate for the file is lower than target by too much!";
ASSERT_LE(effective_datarate_tl[i], target_layer_bitrate_[i] * 1.60)
<< " The datarate for the file is greater than target by too much!";
} #if CONFIG_AV1_DECODER // Test that no mismatches have been found.
std::cout << " Decoded frames: " << GetDecodedFrames() << "\n";
std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n";
EXPECT_EQ(300 - GetDecodedFrames(), drop_frames_);
EXPECT_EQ((int)GetMismatchFrames(), num_nonref); #endif
}
// Set error_resilience off.
cfg_.g_error_resilient = 0;
// Drop TL1 and TL2: for part of sequence. Start at first TL2 at // frame 101, and end at second T2 at frame 199. Frame 200 is TL0, // so we can continue decoding without mismatch (since LAST is the // only reference). int n = 0; #if CONFIG_AV1_DECODER int num_nonref = 300 / 2; #endif for (int i = 101; i < 200; i++) { if (i % 4 != 0) {
drop_frames_list_[n] = i;
n++; #if CONFIG_AV1_DECODER if (i % 2 != 0) num_nonref -= 1; #endif
}
}
drop_frames_ = n;
number_temporal_layers_ = 3;
target_layer_bitrate_[0] = 50 * cfg_.rc_target_bitrate / 100;
target_layer_bitrate_[1] = 70 * cfg_.rc_target_bitrate / 100;
target_layer_bitrate_[2] = cfg_.rc_target_bitrate;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); for (int i = 0; i < number_temporal_layers_ * number_spatial_layers_; i++) {
ASSERT_GE(effective_datarate_tl[i], target_layer_bitrate_[i] * 0.60)
<< " The datarate for the file is lower than target by too much!";
ASSERT_LE(effective_datarate_tl[i], target_layer_bitrate_[i] * 1.60)
<< " The datarate for the file is greater than target by too much!";
} #if CONFIG_AV1_DECODER // Test that no mismatches have been found.
std::cout << " Decoded frames: " << GetDecodedFrames() << "\n";
std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n";
EXPECT_EQ(300 - GetDecodedFrames(), drop_frames_);
EXPECT_EQ((int)GetMismatchFrames(), num_nonref); #endif
}
virtualvoid BasicRateTargetingSVC3TL3SLDropSetEnhER0Test() {
cfg_.rc_buf_initial_sz = 500;
cfg_.rc_buf_optimal_sz = 500;
cfg_.rc_buf_sz = 1000;
cfg_.rc_dropframe_thresh = 0;
cfg_.rc_min_quantizer = 0;
cfg_.rc_max_quantizer = 63;
cfg_.rc_end_usage = AOM_CBR;
cfg_.g_lag_in_frames = 0;
::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352,
288, 30, 1, 0, 300); constint bitrate_array[2] = { 200, 550 };
cfg_.rc_target_bitrate = bitrate_array[GET_PARAM(4)];
ResetModel(); // Set error_resilience off.
cfg_.g_error_resilient = 0; // Drop TL1 and TL2: for part of sequence. Start at first TL2 at // frame 101, and end at second T2 at frame 199. Frame 200 is TL0, // so we can continue decoding without mismatch (since LAST is the // only reference). // Drop here means drop whole superframe. int n = 0; #if CONFIG_AV1_DECODER int num_nonref = 300 / 2; #endif for (int i = 101; i < 200; i++) { if (i % 4 != 0) {
drop_frames_list_[n] = i;
n++; #if CONFIG_AV1_DECODER if (i % 2 != 0) num_nonref -= 1; #endif
}
}
number_temporal_layers_ = 3;
number_spatial_layers_ = 3;
multi_ref_ = 1;
drop_frames_ = n * number_spatial_layers_; // SL0 constint bitrate_sl0 = 1 * cfg_.rc_target_bitrate / 8;
target_layer_bitrate_[0] = 50 * bitrate_sl0 / 100;
target_layer_bitrate_[1] = 70 * bitrate_sl0 / 100;
target_layer_bitrate_[2] = bitrate_sl0; // SL1 constint bitrate_sl1 = 3 * cfg_.rc_target_bitrate / 8;
target_layer_bitrate_[3] = 50 * bitrate_sl1 / 100;
target_layer_bitrate_[4] = 70 * bitrate_sl1 / 100;
target_layer_bitrate_[5] = bitrate_sl1; // SL2 constint bitrate_sl2 = 4 * cfg_.rc_target_bitrate / 8;
target_layer_bitrate_[6] = 50 * bitrate_sl2 / 100;
target_layer_bitrate_[7] = 70 * bitrate_sl2 / 100;
target_layer_bitrate_[8] = bitrate_sl2;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); for (int i = 0; i < number_temporal_layers_ * number_spatial_layers_; i++) {
ASSERT_GE(effective_datarate_tl[i], target_layer_bitrate_[i] * 0.60)
<< " The datarate for the file is lower than target by too much!";
ASSERT_LE(effective_datarate_tl[i], target_layer_bitrate_[i] * 1.60)
<< " The datarate for the file is greater than target by too much!";
} #if CONFIG_AV1_DECODER // Test that no mismatches have been found.
std::cout << " Decoded frames: " << GetDecodedFrames() << "\n";
std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n";
EXPECT_EQ(300 * number_spatial_layers_ - GetDecodedFrames(), drop_frames_);
EXPECT_EQ((int)GetMismatchFrames(), num_nonref); #endif
}
::libaom_test::I420VideoSource video("niklas_640_480_30.yuv", 640, 480, 30,
1, 0, 400); constint bitrate_array[2] = { 500, 1000 };
cfg_.rc_target_bitrate = bitrate_array[GET_PARAM(4)];
ResetModel();
number_temporal_layers_ = 1;
number_spatial_layers_ = 3;
target_layer_bitrate_[0] = 1 * cfg_.rc_target_bitrate / 8;
target_layer_bitrate_[1] = 3 * cfg_.rc_target_bitrate / 8;
target_layer_bitrate_[2] = 4 * cfg_.rc_target_bitrate / 8;
dynamic_enable_disable_mode_ = 1;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); // No need to check RC on top layer which is disabled part of the time. for (int i = 0; i < number_spatial_layers_ - 1; i++) {
ASSERT_GE(effective_datarate_tl[i], target_layer_bitrate_[i] * 0.80)
<< " The datarate for the file is lower than target by too much!";
ASSERT_LE(effective_datarate_tl[i], target_layer_bitrate_[i] * 1.38)
<< " The datarate for the file is greater than target by too much!";
}
}
::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352,
288, 30, 1, 0, 300); constint bitrate_array[2] = { 500, 1000 };
cfg_.rc_target_bitrate = bitrate_array[GET_PARAM(4)];
ResetModel();
number_temporal_layers_ = 1;
number_spatial_layers_ = 3;
target_layer_bitrate_[0] = 1 * cfg_.rc_target_bitrate / 8;
target_layer_bitrate_[1] = 3 * cfg_.rc_target_bitrate / 8;
target_layer_bitrate_[2] = 4 * cfg_.rc_target_bitrate / 8;
dynamic_enable_disable_mode_ = 2;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); // No need to check RC on top layer which is disabled part of the time. for (int i = 0; i < number_spatial_layers_ - 1; i++) {
ASSERT_GE(effective_datarate_tl[i], target_layer_bitrate_[i] * 0.80)
<< " The datarate for the file is lower than target by too much!";
ASSERT_LE(effective_datarate_tl[i], target_layer_bitrate_[i] * 1.38)
<< " The datarate for the file is greater than target by too much!";
}
}
::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352,
288, 30, 1, 0, 300); constint bitrate_array[2] = { 100, 300 };
cfg_.rc_target_bitrate = bitrate_array[GET_PARAM(4)];
ResetModel();
rps_mode_ = 1;
rps_recovery_frame_ = 100;
cfg_.g_error_resilient = 0; // Drop x frames before the recovery frames (where the reference // is switched to an older reference (golden or altref). // GOLDEN is 8 frames behind (for the rps pattern example) so we can't // drop more than 8 frames recovery frame, so choose x = 7. int n = 0; for (int i = rps_recovery_frame_ - 7; i < rps_recovery_frame_; i++) {
drop_frames_list_[n] = i;
n++;
}
drop_frames_ = n;
number_spatial_layers_ = 1;
number_temporal_layers_ = 1;
target_layer_bitrate_[0] = cfg_.rc_target_bitrate;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); for (int i = 0; i < number_temporal_layers_ * number_spatial_layers_; i++) {
ASSERT_GE(effective_datarate_tl[i], target_layer_bitrate_[i] * 0.60)
<< " The datarate for the file is lower than target by too much!";
ASSERT_LE(effective_datarate_tl[i], target_layer_bitrate_[i] * 1.60)
<< " The datarate for the file is greater than target by too much!";
} #if CONFIG_AV1_DECODER // Test that no mismatches have been found.
std::cout << " Decoded frames: " << GetDecodedFrames() << "\n";
std::cout << " Mismatch frames: " << GetMismatchFrames() << "\n";
EXPECT_EQ(300 - GetDecodedFrames(), drop_frames_);
EXPECT_EQ((int)GetMismatchFrames(), 0); #endif
}
int layer_frame_cnt_; int superframe_cnt_; int number_temporal_layers_; int number_spatial_layers_; // Allow for up to 3 temporal layers. int target_layer_bitrate_[AOM_MAX_LAYERS];
aom_svc_params_t svc_params_;
aom_svc_ref_frame_config_t ref_frame_config_;
aom_svc_ref_frame_comp_pred_t ref_frame_comp_pred_;
aom_svc_layer_id_t layer_id_; double effective_datarate_tl[AOM_MAX_LAYERS]; unsignedint drop_frames_; unsignedint drop_frames_list_[1000]; unsignedint mismatch_nframes_; unsignedint decoded_nframes_; double mismatch_psnr_; int set_frame_level_er_; int multi_ref_; int use_fixed_mode_svc_; int comp_pred_; int dynamic_enable_disable_mode_; int intra_only_; int intra_only_single_layer_; unsignedint frame_to_start_decoding_; unsignedint layer_to_decode_; unsignedint frame_sync_; unsignedint current_video_frame_; int screen_mode_; int rps_mode_; int rps_recovery_frame_; int simulcast_mode_; bool use_last_as_scaled_; bool use_last_as_scaled_single_ref_;
int user_define_frame_qp_; int frame_qp_; int total_frame_; bool set_speed_per_layer_;
libaom_test::ACMRandom rnd_;
};
// Check basic rate targeting for CBR, for 3 temporal layers, 1 spatial.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL1SL) {
BasicRateTargetingSVC3TL1SLTest();
}
// Check basic rate targeting for CBR, for 3 temporal layers, 1 spatial // for screen mode.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL1SLScreen) {
BasicRateTargetingSVC3TL1SLScreenTest();
}
// Check basic rate targeting for CBR, for 2 temporal layers, 1 spatial // for screen mode, with frame dropper on at low bitrates. Use small // values of rc_buf_initial/optimal/sz to trigger postencode frame drop.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC2TL1SLScreenDropFrame) {
BasicRateTargetingSVC2TL1SLScreenDropFrameTest();
}
// Check basic rate targeting for CBR, for 3 spatial layers, 1 temporal // for screen mode.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC1TL3SLScreen) {
BasicRateTargetingSVC1TL3SLScreenTest();
}
// Check basic rate targeting for CBR, for 1 temporal layer, 1 spatial // for screen mode, with source with many scene cuts and motion.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC1TL1SLScreenScCutsMotion) {
BasicRateTargetingSVC1TL1SLScreenScCutsMotionTest();
}
// Check basic rate targeting for CBR, for 3 temporal layers, 1 spatial, // with dynamic resize on. Encode at very low bitrate and check that // there is at least one resize (down) event.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL1SLResize) {
BasicRateTargetingSVC3TL1SLResizeTest();
}
// Check basic rate targeting for CBR, for 2 spatial layers, 1 temporal.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC1TL2SL) {
BasicRateTargetingSVC1TL2SLTest();
}
// Check basic rate targeting for CBR, for 3 spatial layers, 3 temporal, // with Intra-only frame inserted in the stream. Verify that we can start // decoding the SL0 stream at the intra_only frame in mid-sequence.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL3SLIntraStartDecodeBaseMidSeq) {
BasicRateTargetingSVC3TL3SLIntraStartDecodeBaseMidSeq();
}
// Check basic rate targeting for CBR, for 3spatial layers, 3 temporal, // with Intra-only frame inserted in the stream. Verify that we can // decode all frames and layers with no mismatch.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL3SLIntraMidSeqDecodeAll) {
BasicRateTargetingSVC3TL3SLIntraMidSeqDecodeAll();
}
// Check simulcast mode for 3 spatial layers, 3 temporal, // Key frame is inserted on base SLO in mid-stream, and verify that the // top spatial layer (SL2) case be decoded, starting with an Intra-only frame. // Verify that we can decode all frames for SL2 with no mismatch.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL3SLSimulcast) {
BasicRateTargetingSVC3TL3SLSimulcast();
}
// Check basic rate targeting for CBR, for 2 spatial layers, 1 temporal, // with Intra-only frame inserted in the stream.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC1TL2SLIntraOnly) {
BasicRateTargetingSVC1TL2SLIntraOnlyTest();
}
// Check basic rate targeting for CBR, for 1 spatial layers, 1 temporal, // with Intra-only frame (frame with no references) inserted in the stream.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC1TL1SLIntraOnly) {
BasicRateTargetingSVC1TL1SLIntraOnlyTest();
}
// Check basic rate targeting for CBR, for 3 spatial layers, 1 temporal.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC1TL3SL) {
BasicRateTargetingSVC1TL3SLTest();
}
// Check basic rate targeting for CBR, for 3 spatial layers, 1 temporal. // Force the spatial reference to be LAST, with a second temporal // reference (GOLDEN).
TEST_P(DatarateTestSVC, BasicRateTargetingSVC1TL3SLLastIsScaled) {
BasicRateTargetingSVC1TL3SLLastIsScaledTest();
}
// Check basic rate targeting for CBR, for 3 spatial layers, 1 temporal. // Force the spatial reference to be LAST, and force only 1 reference.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC1TL3SLastIsScaledSingleRef) {
BasicRateTargetingSVC1TL3SLLastIsScaledSingleRefTest();
}
// Check basic rate targeting for CBR, for 3 spatial layers, 1 temporal, // with additional temporal reference for top spatial layer.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC1TL3SLMultiRef) {
BasicRateTargetingSVC1TL3SLMultiRefTest();
}
// Check basic rate targeting for CBR, for 3 spatial, 3 temporal layers.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL3SL) {
BasicRateTargetingSVC3TL3SLTest();
}
// Check basic rate targeting for CBR, for 3 spatial, 3 temporal layers.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL3SLHD) {
BasicRateTargetingSVC3TL3SLHDTest();
}
// Check basic rate targeting for CBR, for 3 spatial, 3 temporal layers, // for fixed mode SVC.
TEST_P(DatarateTestSVC, BasicRateTargetingFixedModeSVC3TL3SLHD) {
BasicRateTargetingFixedModeSVC3TL3SLHDTest();
}
// Check basic rate targeting for CBR, for 3 spatial, 3 temporal layers, // for 2 threads, 2 tile_columns, row-mt enabled, and different speed // per layer.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL3SLMultiThreadSpeedPerLayer) {
BasicRateTargetingSVC3TL3SLMultiThreadSpeedPerLayerTest();
}
// Check basic rate targeting for CBR, for 3 spatial, 3 temporal layers, // for 2 threads, 2 tile_columns, row-mt enabled.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL3SLHDMultiThread2) {
BasicRateTargetingSVC3TL3SLHDMultiThread2Test();
}
// Check basic rate targeting for CBR, for 1 spatial, 2 temporal layers, // for 4 threads, 2 tile_columns, 2 tiles_rows, row-mt enabled.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC2TL1SLHDMultiThread4) {
BasicRateTargetingSVC2TL1SLHDMultiThread4Test();
}
// Check basic rate targeting for CBR, for 1 spatial, 2 temporal layers, // for 4 threads, row-mt enabled, and auto_tiling enabled.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC2TL1SLHDMultiThread4AutoTiles) {
BasicRateTargetingSVC2TL1SLHDMultiThread4AutoTilesTest();
} // Check basic rate targeting for CBR, for 3 spatial, 3 temporal layers, // for 4 threads, 2 tile_columns, 2 tiles_rows, row-mt enabled.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL3SLHDMultiThread4) {
BasicRateTargetingSVC3TL3SLHDMultiThread4Test();
}
// Check basic rate targeting for CBR, for 3 spatial, 3 temporal layers, // with additional temporal reference for top spatial layer.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL3SLHDMultiRef) {
BasicRateTargetingSVC3TL3SLHDMultiRefTest();
}
// Check basic rate targeting for CBR, for 3 spatial, 3 temporal layers, // for auto key frame mode with short key frame period.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL3SLKf) {
BasicRateTargetingSVC3TL3SLKfTest();
}
// Check basic rate targeting for CBR, for 3 temporal layers, 1 spatial layer, // with dropping of all enhancement layers (TL 1 and TL2). Check that the base // layer (TL0) can still be decodeable (with no mismatch) with the // error_resilient flag set to 0. This test used the pattern with multiple // references (last, golden, and altref), updated on base layer.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL1SLMultiRefDropAllEnh) {
BasicRateTargetingSVC3TL1SLMultiRefDropAllEnhTest();
}
// Check basic rate targeting for CBR, for 3 temporal layers, 1 spatial layer, // with dropping of all enhancement layers (TL 1 and TL2). Check that the base // layer (TL0) can still be decodeable (with no mismatch) with the // error_resilient flag set to 0.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL1SLDropAllEnh) {
BasicRateTargetingSVC3TL1SLDropAllEnhTest();
}
// Check basic rate targeting for CBR, for 3 temporal layers, 1 spatial layer, // with dropping of the TL2 enhancement layer, which are non-reference // (droppble) frames. For the base layer (TL0) and TL1 to still be decodeable // (with no mismatch), the error_resilient_flag may be off (set to 0), // since TL2 are non-reference frames.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL1SLDropTL2Enh) {
BasicRateTargetingSVC3TL1SLDropTL2EnhTest();
}
// Check basic rate targeting for CBR, for 3 temporal layers, 1 spatial layer, // with dropping of all enhancement layers (TL 1 and TL2). Test that the // error_resilient flag can be set at frame level, with on/1 on // enhancement layers and off/0 on base layer. // This allows for successful decoding after dropping enhancement layer frames.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL1SLDropAllEnhFrameER) {
BasicRateTargetingSVC3TL1SLDropAllEnhFrameERTest();
}
// Check basic rate targeting for CBR, for 3 temporal layers, 1 spatial layer, // with dropping set of enhancement layers (TL 1 and TL2) in middle of sequence. // Test that the error_resilient flag can be set at frame level, with on/1 on // enhancement layers and off/0 on base layer. // This allows for successful decoding after dropping a set enhancement layer // frames in the sequence.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL1SLDropSetEnhFrameER) {
BasicRateTargetingSVC3TL1SLDropSetEnhFrameERTest();
}
// Check basic rate targeting for CBR, for 2 temporal layers, 1 spatial layer, // with dropping set of enhancement layers (TL 1) in middle of sequence. // Test that the error_resilient flag can be 0/off for all frames. // This allows for successful decoding after dropping a set enhancement layer // frames in the sequence.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC2TL1SLDropSetEnhER0) {
BasicRateTargetingSVC2TL1SLDropSetEnhER0Test();
}
// Check basic rate targeting for CBR, for 3 temporal layers, 1 spatial layer, // with dropping set of enhancement layers (TL 1 and TL2) in middle of sequence. // Test that the error_resilient flag can be 0/off for all frames. // This allows for successful decoding after dropping a set enhancement layer // frames in the sequence.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL1SLDropSetEnhER0) {
BasicRateTargetingSVC3TL1SLDropSetEnhER0Test();
}
// Check basic rate targeting for CBR, for 3 temporal layers, 3 spatial layers, // with dropping set of enhancement layers (superframe TL 1 and TL2) in middle // of sequence. Test that the error_resilient flag can be 0/off for all frames. // This allows for successful decoding after dropping a set enhancement layer // frames in the sequence.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL3SLDropSetEnhER0) {
BasicRateTargetingSVC3TL3SLDropSetEnhER0Test();
}
// Check basic rate targeting for CBR, for 3 temporal layers, 1 spatial layer, // with compound prediction on, for pattern with two additional refereces // (golden and altref), both updated on base TLO frames.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL1SLMultiRefCompound) {
BasicRateTargetingSVC3TL1SLMultiRefCompoundTest();
}
// Check basic rate targeting for CBR, for 3 spatial layers, 1 temporal, // with the top spatial layer starting disabled (0 bitrate) and then // dynamically enabled after x frames with nonzero bitrate.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC1TL3SLDynEnabl) {
BasicRateTargetingSVC1TL3SLDynEnablTest();
}
// Check basic rate targeting for CBR, for 3 spatial layers, 1 temporal, // with the top spatial layer dynamically disabled snd enabled during the // middle of the sequence.
TEST_P(DatarateTestSVC, BasicRateTargetingSVC1TL3SLDynDisEnabl) {
BasicRateTargetingSVC1TL3SLDynDisEnablTest();
}
// Check basic rate targeting and encoder/decodermismatch, for RPS // with 1 layer. A number of consecutive frames are lost midway in // sequence, and encoder resorts to a longer term reference to recovery // and continue decoding successfully.
TEST_P(DatarateTestSVC, BasicRateTargetingRPS1TL1SLDropFrames) {
BasicRateTargetingRPS1TL1SLDropFramesTest();
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.