Skip to content

Commit

Permalink
Order subsambling before effort (#4)
Browse files Browse the repository at this point in the history
  • Loading branch information
y-guyon authored Jul 22, 2024
1 parent 7910cc0 commit 0163fc9
Show file tree
Hide file tree
Showing 12 changed files with 135 additions and 120 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## v0.1.3

Swap the order of the effort and chroma subsampling parameters everywhere.

## v0.1.2

Add 4:2:0 chroma subsampling support for codecs that also support lossy 4:4:4.
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.20)
project(
codec-compare-gen
LANGUAGES CXX
VERSION 0.1.2)
VERSION 0.1.3)
set(CMAKE_CXX_STANDARD 17)

option(BUILD_SHARED_LIBS "Build the shared codec-compare-gen library" ON)
Expand Down
4 changes: 2 additions & 2 deletions src/codec_combination.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ StatusOr<WP2::Data> EncodeCodecCombination(
WP2::Data data;
for (int i = 0; i < kMaxNumCodecs; ++i) {
const TaskInput specialized_input = {
{combination[i].codec, combination[i].effort,
input.codec_settings.chroma_subsampling, input.codec_settings.quality},
{combination[i].codec, input.codec_settings.chroma_subsampling,
combination[i].effort, input.codec_settings.quality},
input.image_path};
if (specialized_input.codec_settings.effort == kNone.effort) break;

Expand Down
8 changes: 4 additions & 4 deletions src/framework.cc
Original file line number Diff line number Diff line change
Expand Up @@ -250,8 +250,6 @@ Status RemoveCompletedTasksFromRemainingTasks(
bool operator()(const TaskInput& a, const TaskInput& b) const {
if (a.codec_settings.codec < b.codec_settings.codec) return true;
if (a.codec_settings.codec > b.codec_settings.codec) return false;
if (a.codec_settings.effort < b.codec_settings.effort) return true;
if (a.codec_settings.effort > b.codec_settings.effort) return false;
if (a.codec_settings.chroma_subsampling <
b.codec_settings.chroma_subsampling) {
return true;
Expand All @@ -260,6 +258,8 @@ Status RemoveCompletedTasksFromRemainingTasks(
b.codec_settings.chroma_subsampling) {
return false;
}
if (a.codec_settings.effort < b.codec_settings.effort) return true;
if (a.codec_settings.effort > b.codec_settings.effort) return false;
if (a.codec_settings.quality < b.codec_settings.quality) return true;
if (a.codec_settings.quality > b.codec_settings.quality) return false;
return a.image_path < b.image_path;
Expand Down Expand Up @@ -380,8 +380,8 @@ Status Compare(const std::vector<std::string>& image_paths,
tasks.front().task_input.codec_settings;
const std::string batch_name =
CodecName(codec_settings.codec) + "_" +
std::to_string(codec_settings.effort) + "_" +
SubsamplingToString(codec_settings.chroma_subsampling);
SubsamplingToString(codec_settings.chroma_subsampling) + "_" +
std::to_string(codec_settings.effort);
OK_OR_RETURN(TasksToJson(
batch_name, codec_settings, tasks, settings.quiet,
std::filesystem::path(results_folder_path) / (batch_name + ".json")));
Expand Down
2 changes: 1 addition & 1 deletion src/framework.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ namespace codec_compare_gen {

struct CodecSettings {
Codec codec;
int effort;
Subsampling chroma_subsampling;
int effort;
int quality; // kQualityLossless or in [0:100] (exact range depends on codec)
};

Expand Down
21 changes: 14 additions & 7 deletions src/result_json.cc
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ Status TasksToJson(const std::string& batch_name, CodecSettings settings,
const CodecSettings& codec_settings = tasks[i].task_input.codec_settings;
CHECK_OR_RETURN(
codec_settings.codec == settings.codec &&
codec_settings.effort == settings.effort &&
codec_settings.chroma_subsampling == settings.chroma_subsampling,
codec_settings.chroma_subsampling == settings.chroma_subsampling &&
codec_settings.effort == settings.effort,
quiet)
<< "Codec settings do not match";
lossless &= codec_settings.quality == kQualityLossless;
Expand All @@ -101,8 +101,9 @@ Status TasksToJson(const std::string& batch_name, CodecSettings settings,
GetImagePathCommonPrefix(tasks, /*get_encoded_path=*/false);
const std::string encoding_cmd =
"codec_compare_gen ${original_path} --codec " +
CodecName(settings.codec) + " " + std::to_string(settings.effort) + " " +
SubsamplingToString(settings.chroma_subsampling);
CodecName(settings.codec) + " " +
SubsamplingToString(settings.chroma_subsampling) + " " +
std::to_string(settings.effort);
const std::string encoded_prefix =
GetImagePathCommonPrefix(tasks, /*get_encoded_path=*/true);

Expand Down Expand Up @@ -154,11 +155,15 @@ Status TasksToJson(const std::string& batch_name, CodecSettings settings,
"field_descriptions": [
{"original_name": "Original image file name"},
{"width": "Pixel columns in the original image"},
{"height": "Pixel rows in the original image"},
{"height": "Pixel rows in the original image"},)json";
if (!lossless) {
file << R"json(
{"chroma_subsampling": "Compression chroma subsampling parameter"},)json";
}
file << R"json(
{"effort": "Compression effort parameter"},)json";
if (!lossless) {
file << R"json(
{"chroma_subsampling": "Compression chroma subsampling parameter"},
{"quality": "Compression quality parameter"},)json";
}
if (has_encoded_path) {
Expand Down Expand Up @@ -194,11 +199,13 @@ Status TasksToJson(const std::string& batch_name, CodecSettings settings,
<< ",";
file << task.image_width << ",";
file << task.image_height << ",";
file << task.task_input.codec_settings.effort << ",";
if (!lossless) {
file << SubsamplingToString(
task.task_input.codec_settings.chroma_subsampling)
<< ",";
}
file << task.task_input.codec_settings.effort << ",";
if (!lossless) {
file << task.task_input.codec_settings.quality << ",";
}
if (has_encoded_path) {
Expand Down
33 changes: 18 additions & 15 deletions src/task.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ std::string GetEncodedFilePath(const std::string& folder_path,
if (codec_settings.quality != kQualityLossless ||
codec_settings.chroma_subsampling != Subsampling::k444) {
// 444/420 could be prepended by "yuv" but it makes the file name longer and
// it could be misleading for RGB 444. Just make it appear before the "e" of
// effort instead.
// it could be misleading for RGB 444.
ext << SubsamplingToString(codec_settings.chroma_subsampling);
}
ext << "e" << codec_settings.effort;
Expand All @@ -64,8 +63,8 @@ std::string GetEncodedFilePath(const std::string& folder_path,
}

bool operator==(const CodecSettings& a, const CodecSettings& b) {
return a.codec == b.codec && a.effort == b.effort &&
a.chroma_subsampling == b.chroma_subsampling && a.quality == b.quality;
return a.codec == b.codec && a.chroma_subsampling == b.chroma_subsampling &&
a.effort == b.effort && a.quality == b.quality;
}

} // namespace
Expand All @@ -81,9 +80,9 @@ bool operator==(const TaskInput& a, const TaskInput& b) {
std::string TaskOutput::Serialize() const {
std::stringstream ss;
ss << Escape(CodecName(task_input.codec_settings.codec)) << ", "
<< task_input.codec_settings.effort << ", "
<< SubsamplingToString(task_input.codec_settings.chroma_subsampling)
<< ", " << task_input.codec_settings.quality << ", "
<< ", " << task_input.codec_settings.effort << ", "
<< task_input.codec_settings.quality << ", "
<< Escape(task_input.image_path) << ", " << image_width << ", "
<< image_height << ", " << Escape(task_input.encoded_path) << ", "
<< encoded_size << ", " << encoding_duration << ", " << decoding_duration
Expand Down Expand Up @@ -113,13 +112,13 @@ StatusOr<TaskOutput> UnserializeNoDistortion(
ASSIGN_OR_RETURN(task.task_input.codec_settings.codec,
CodecFromName(codec_name, quiet));

ASSIGN_OR_RETURN(task.task_input.codec_settings.chroma_subsampling,
SubsamplingFromString(tokens[t++], quiet));

task.task_input.codec_settings.effort = std::stoul(tokens[t++]);
CHECK_OR_RETURN(task.task_input.codec_settings.effort <= 10, quiet)
<< "Unknown effort in \"" << serialized_task << "\"";

ASSIGN_OR_RETURN(task.task_input.codec_settings.chroma_subsampling,
SubsamplingFromString(tokens[t++], quiet));

task.task_input.codec_settings.quality = std::stoi(tokens[t++]);
CHECK_OR_RETURN(task.task_input.codec_settings.quality == kQualityLossless ||
(task.task_input.codec_settings.quality >= 0 &&
Expand Down Expand Up @@ -287,10 +286,14 @@ SplitByCodecSettingsAndAggregateByImageAndQuality(

auto cmp = [](const CodecSettings& a, const CodecSettings& b) {
// Multiple qualities can coexist in the same aggregate (meaning in the same
// output JSON single file). Only split by codec and effort.
return a.codec < b.codec || (a.codec == b.codec && a.effort < b.effort) ||
(a.codec == b.codec && a.effort == b.effort &&
a.chroma_subsampling < b.chroma_subsampling);
// output JSON single file). Only split by codec, chroma subsampling and
// effort.
return a.codec < b.codec ||
(a.codec == b.codec &&
a.chroma_subsampling < b.chroma_subsampling) ||
(a.codec == b.codec &&
a.chroma_subsampling == b.chroma_subsampling &&
a.effort < b.effort);
};
std::map<CodecSettings, std::vector<TaskOutput>, decltype(cmp)> map(cmp);
for (const TaskOutput& result : results) {
Expand All @@ -304,8 +307,8 @@ SplitByCodecSettingsAndAggregateByImageAndQuality(
ASSIGN_OR_RETURN(aggregate,
AggregateResultsByImageAndQuality(results, quiet));

// codec and effort are the same in these results so only sort by original
// image name and quality.
// codec, chroma subsampling and effort are the same in these results so
// only sort by original image name and quality.
std::sort(aggregate.begin(), aggregate.end(),
[](const TaskOutput& a, const TaskOutput& b) {
return a.task_input.image_path < b.task_input.image_path ||
Expand Down
Loading

0 comments on commit 0163fc9

Please sign in to comment.