diff --git a/libvmaf/src/feature/feature_collector.c b/libvmaf/src/feature/feature_collector.c index 42f4e340f..7b98100cd 100644 --- a/libvmaf/src/feature/feature_collector.c +++ b/libvmaf/src/feature/feature_collector.c @@ -355,61 +355,61 @@ int vmaf_feature_collector_append(VmafFeatureCollector *feature_collector, VmafPredictModel *model_iter = feature_collector->models; - while (model_iter) { - VmafModel *model = model_iter->model; - bool needs_computation = false; +while (model_iter) { + VmafModel *model = model_iter->model; + bool needs_computation = false; - // Check if current score needs computation + // Check if current score needs computation + pthread_mutex_unlock(&(feature_collector->lock)); + res = vmaf_feature_collector_get_score(feature_collector, model->name, &score, picture_index); + needs_computation = (res != 0); + pthread_mutex_lock(&(feature_collector->lock)); + + if (needs_computation) { + // Compute the current frame's score pthread_mutex_unlock(&(feature_collector->lock)); - res = vmaf_feature_collector_get_score(feature_collector, model->name, &score, picture_index); - needs_computation = (res != 0); + res = vmaf_predict_score_at_index(model, feature_collector, picture_index, &score, true, true, 0); pthread_mutex_lock(&(feature_collector->lock)); - if (needs_computation) { - // Compute the current frame's score - pthread_mutex_unlock(&(feature_collector->lock)); - res = vmaf_predict_score_at_index(model, feature_collector, picture_index, &score, true, true, 0); - pthread_mutex_lock(&(feature_collector->lock)); - - if (!res) { - // Process all pending frames up to current index in order - unsigned process_index = feature_collector->metadata->last_seen_lowest_index; - feature_collector->metadata->last_seen_highest_index = MAX(picture_index, feature_collector->metadata->last_seen_highest_index); - - while (process_index <= feature_collector->metadata->last_seen_highest_index) { - bool frame_ready = true; - - // First check if this frame's score is ready - pthread_mutex_unlock(&(feature_collector->lock)); - if (vmaf_feature_collector_get_score(feature_collector, model->name, &score, process_index) != 0) { - frame_ready = false; - } - pthread_mutex_lock(&(feature_collector->lock)); - - if (!frame_ready) break; // Stop at first unready frame - - // Frame is ready, trigger callbacks for all features - for (unsigned j = 0; j < feature_collector->cnt; j++) { - VmafMetadata data = { - .feature_name = feature_collector->feature_vector[j]->name, - .picture_index = process_index, - .score = feature_collector->feature_vector[j]->score[process_index].value, - }; - - // Call all metadata callbacks - feature_collector->metadata->head->metadata_cfg.callback( - feature_collector->metadata->head->metadata_cfg.data, &data); - } - - process_index++; - feature_collector->metadata->last_seen_lowest_index = process_index; + if (!res) { + // Process all pending frames up to current index in order + unsigned process_index = feature_collector->metadata->last_seen_lowest_index; + feature_collector->metadata->last_seen_highest_index = MAX(picture_index, feature_collector->metadata->last_seen_highest_index); + + while (process_index <= feature_collector->metadata->last_seen_highest_index) { + bool frame_ready = true; + + // First check if this frame's score is ready + pthread_mutex_unlock(&(feature_collector->lock)); + if (vmaf_feature_collector_get_score(feature_collector, model->name, &score, process_index) != 0) { + frame_ready = false; } + pthread_mutex_lock(&(feature_collector->lock)); + + if (!frame_ready) break; // Stop at first unready frame + + // Frame is ready, trigger callbacks for all features + for (unsigned j = 0; j < feature_collector->cnt; j++) { + VmafMetadata data = { + .feature_name = feature_collector->feature_vector[j]->name, + .picture_index = process_index, + .score = feature_collector->feature_vector[j]->score[process_index].value, + }; + + // Call all metadata callbacks + feature_collector->metadata->head->metadata_cfg.callback( + feature_collector->metadata->head->metadata_cfg.data, &data); + } + + process_index++; + feature_collector->metadata->last_seen_lowest_index = process_index; } } - - model_iter = model_iter->next; } + model_iter = model_iter->next; +} + unlock: feature_collector->timer.end = clock(); pthread_mutex_unlock(&(feature_collector->lock));