Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allows per output xml and cc files #924

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 37 additions & 16 deletions Source/CLI/CommandLine_Parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,15 +172,14 @@ return_value Parse(Core &C, int argc, const char* argv_ansi[], const MediaInfoNa
return_value ReturnValue = ReturnValue_OK;
bool ClearInput = false;
caption_kind CaptionKind = Caption_Unknown;
const char* Xml_OutputFileName = nullptr;
const char* Webvtt_OutputFileName = nullptr;
const char* MergeInfo_OutputFileName = nullptr;
const char* Merge_Rewind_BaseName = nullptr;
bitset<Flag_Max> Flags;
bool OutputFrames_Speed = false;
bool OutputFrames_Speed_StdOut = false;
bool OutputFrames_Concealed = false;
bool OutputFrames_Concealed_StdOut = false;
bool OutputFrames_Speed = true;
bool OutputFrames_Speed_StdOut = true;
bool OutputFrames_Concealed = true;
bool OutputFrames_Concealed_StdOut = true;

// Commands in priority
for (int i = 1; i < argc; i++)
Expand Down Expand Up @@ -318,7 +317,9 @@ return_value Parse(Core &C, int argc, const char* argv_ansi[], const MediaInfoNa
CurrentCaptionKind = CaptionKind;
CaptionKind = Caption_Unknown;
}
C.CaptionsFileNames[CurrentCaptionKind] = move(CurrentFileName);
Core::OutFile CaptionFile;
CaptionFile.Name = move(CurrentFileName);
C.CaptionsFileNames[CurrentCaptionKind].push_back(CaptionFile);
}
else if (!strcmp(argv_ansi[i], "--capture") || !strcmp(argv_ansi[i], "-capture"))
{
Expand Down Expand Up @@ -357,6 +358,15 @@ return_value Parse(Core &C, int argc, const char* argv_ansi[], const MediaInfoNa
OutputFrames_Speeds.push_back(OutputFrames_Speed);
OutputFrames_Concealeds.push_back(OutputFrames_Concealed);
}

if (!C.XmlFiles.empty() && C.XmlFiles.back().Merge_OutputFileName.empty())
C.XmlFiles.back().Merge_OutputFileName = argv_ansi[i];

for (auto& CaptionFileNames : C.CaptionsFileNames)
{
if (CaptionFileNames.second.back().Merge_OutputFileName.empty())
CaptionFileNames.second.back().Merge_OutputFileName = argv_ansi[i];
}
}
else if (!strcmp(argv_ansi[i], "--merge-log"))
{
Expand Down Expand Up @@ -719,7 +729,10 @@ return_value Parse(Core &C, int argc, const char* argv_ansi[], const MediaInfoNa
*C.Err << "Error: missing XML output file name after " << argv_ansi[i-1] << ".\n";
return ReturnValue_ERROR;
}
Xml_OutputFileName = argv_ansi[i];

Core::OutFile XmlFile;
XmlFile.Name = argv_ansi[i];
C.XmlFiles.push_back(XmlFile);
}
else if (!strcmp(argv_ansi[i], "-n"))
{
Expand Down Expand Up @@ -779,7 +792,7 @@ return_value Parse(Core &C, int argc, const char* argv_ansi[], const MediaInfoNa
}
else
{
if (Webvtt_OutputFileName || Xml_OutputFileName || !Merge_OutputFileNames.empty() || Merge_OutputFileNames_IncludesStdOut)
if (Webvtt_OutputFileName || !C.XmlFiles.empty() || !Merge_OutputFileNames.empty() || Merge_OutputFileNames_IncludesStdOut)
{
if (C.Err)
*C.Err << "Error: in order to avoid mistakes, provide output file names after input file names.\n";
Expand Down Expand Up @@ -904,16 +917,13 @@ return_value Parse(Core &C, int argc, const char* argv_ansi[], const MediaInfoNa
Merge_Out.push_back(Temp);
}

for (Core::OutFile& OutputFile : C.XmlFiles)
OutputFiles_OpenError |= OpenTruncateFile(OutputFile.File, OutputFile.Name.c_str(), C, Flags);

if ((OutputFiles_OpenError)
|| (Xml_OutputFileName && OpenTruncateFile(C.XmlFile, Xml_OutputFileName, C, Flags))
|| (Webvtt_OutputFileName && OpenTruncateFile(C.WebvttFile, Webvtt_OutputFileName, C, Flags))
|| (MergeInfo_OutputFileName && OpenTruncateFile(MergeInfo_Out, MergeInfo_OutputFileName, C, Flags)))
{
if (C.XmlFile)
{
delete C.XmlFile;
remove(Xml_OutputFileName);
}
if (C.WebvttFile)
{
delete C.WebvttFile;
Expand All @@ -925,6 +935,14 @@ return_value Parse(Core &C, int argc, const char* argv_ansi[], const MediaInfoNa
remove(MergeInfo_OutputFileName);
}

for (Core::OutFile& OutputFile : C.XmlFiles)
{
if (OutputFile.File && OutputFile.File != C.Out)
delete OutputFile.File;
remove(OutputFile.Name.c_str());
}
C.XmlFiles.clear();

for (FILE* OutputFile : Merge_Out)
fclose(OutputFile);
Merge_Out.clear();
Expand Down Expand Up @@ -986,6 +1004,9 @@ void Clean(Core& C)
// We previously set some output file pointers, deleting them
if (C.WebvttFile != C.Out)
delete C.WebvttFile;
if (C.XmlFile != C.Out)
delete C.XmlFile;
for (Core::OutFile& OutputFile : C.XmlFiles)
{
if (OutputFile.File && OutputFile.File != C.Out)
delete OutputFile.File;
}
}
41 changes: 23 additions & 18 deletions Source/Common/Core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,18 +81,23 @@ return_value Core::Process()
if (!Merge_Out.empty())
{
PerFile[0]->Merge_Finish();
if (!XmlFile)
if (XmlFiles.empty())
return ToReturn;
}

// Set output defaults
if (!XmlFile)
XmlFile = Out;
if (XmlFiles.empty())
{
//TODO: select first output, last output or input in that case?
OutFile XmlFile;
XmlFile.File = Out;
XmlFiles.push_back(XmlFile);
}

// XML
if (XmlFile)
for (OutFile& XmlFile : XmlFiles)
{
if (auto ToReturn2 = Output_Xml(*XmlFile, PerFile, Options, Err))
if (auto ToReturn2 = Output_Xml(XmlFile, PerFile, Options, Err))
ToReturn = ToReturn2;
}

Expand All @@ -104,23 +109,23 @@ return_value Core::Process()
}

// Closed Captions
if (!CaptionsFileNames.empty())
for (const auto& Caption : CaptionsFileNames)
{
// SCC
auto SccFileName = CaptionsFileNames.find(Caption_Scc);
if (SccFileName != CaptionsFileNames.end())
if (Caption.first == Caption_Scc)
{
if (auto ToReturn2 = Output_Captions_Scc(SccFileName->second, OffsetTimeCode, PerFile, Err))
ToReturn = ToReturn2;
for (const auto& OutFile : Caption.second)
{
if (auto ToReturn2 = Output_Captions_Scc(OutFile, OffsetTimeCode, PerFile, Err))
ToReturn = ToReturn2;
}
}

// Decode (Screen or SRT)
auto ScreenFileName = CaptionsFileNames.find(Caption_Screen);
auto SrtFileName = CaptionsFileNames.find(Caption_Srt);
if (ScreenFileName != CaptionsFileNames.end() || SrtFileName != CaptionsFileNames.end())
else if (Caption.first == Caption_Screen || Caption.first == Caption_Srt)
{
if (auto ToReturn2 = Output_Captions_Caption(ScreenFileName != CaptionsFileNames.end() ? ScreenFileName->second : string(), SrtFileName != CaptionsFileNames.end() ? SrtFileName->second : string(), OffsetTimeCode, PerFile, Err))
ToReturn = ToReturn2;
for (const auto& OutFile : Caption.second)
{
if (auto ToReturn2 = Output_Captions_Caption(Caption.first == Caption_Screen ? OutFile : Core::OutFile(), Caption.first == Caption_Srt ? OutFile : Core::OutFile(), OffsetTimeCode, PerFile, Err))
ToReturn = ToReturn2;
}
}
}

Expand Down
14 changes: 12 additions & 2 deletions Source/Common/Core.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,26 @@ enum caption_kind
class Core
{
public:
//Object
struct OutFile
{
ostream* File = nullptr;
string Name;

// Reference file, input if empty
string Merge_OutputFileName;
};

// Constructor/Destructor
Core();
~Core();

// Input
vector<String> Inputs;
map<caption_kind, string> CaptionsFileNames; // We don't directly open an ostream because file name may change if cc are not same and/or 2nd field and/or no cc
map<caption_kind, vector<OutFile>> CaptionsFileNames; // We don't directly open an ostream because file name may change if cc are not same and/or 2nd field and/or no cc
TimeCode* OffsetTimeCode = nullptr;
ostream* WebvttFile = nullptr;
ostream* XmlFile = nullptr;
vector<OutFile> XmlFiles;
ostream* Out = nullptr;
ostream* Err = nullptr;
bitset<Option_Max> Options;
Expand Down
46 changes: 41 additions & 5 deletions Source/Common/Output_Captions_Decode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "ccdecoder_line21.h"
#include "ccdecoder_subrip.h"
#include "ccdecoder_onscreen.h"
#include <algorithm>
#include <fstream>
//---------------------------------------------------------------------------

Expand Down Expand Up @@ -172,7 +173,7 @@ struct decoded_data
//***************************************************************************

//---------------------------------------------------------------------------
static return_value Output_Captions_Decode(const string& ScreenOutName, const string& SrtOutName, const vector<file::captions_fielddata>& PerFrame_Captions, int Field, ostream* Err)
static return_value Output_Captions_Decode(const string& ScreenOutName, const string& SrtOutName, const vector<file::captions_fielddata>& PerFrame_Captions, const vector<size_t>& IgnoredFrames, int Field, ostream* Err)
{
auto ToReturn = ReturnValue_OK;

Expand All @@ -185,6 +186,9 @@ static return_value Output_Captions_Decode(const string& ScreenOutName, const st
// By Frame - For each line
for (const auto& Frame : PerFrame_Captions)
{
if (find(IgnoredFrames.begin(), IgnoredFrames.end(), Frame.StartFrameNumber) != IgnoredFrames.end())
continue;

for (size_t i = 0; i < Frame.Captions.size(); i++)
{
const auto& Caption = Frame.Captions[i];
Expand Down Expand Up @@ -279,28 +283,60 @@ static return_value Output_Captions_Decode(const string& ScreenOutName, const st
}

//---------------------------------------------------------------------------
return_value Output_Captions_Caption(const string& ScreenOutName, const string& SrtOutName, const TimeCode* OffsetTimeCode, std::vector<file*>& PerFile, ostream* Err)
return_value Output_Captions_Caption(const Core::OutFile& ScreenOut, const Core::OutFile& SrtOut, const TimeCode* OffsetTimeCode, std::vector<file*>& PerFile, ostream* Err)
{
auto ToReturn = ReturnValue_OK;

bool OutputFrames_Speed = true;
bool OutputFrames_Concealed = true;

auto It = find(Merge_OutputFileNames.begin(), Merge_OutputFileNames.end(), ScreenOut.Merge_OutputFileName.size() ? ScreenOut.Merge_OutputFileName : SrtOut.Merge_OutputFileName);
if (It != Merge_OutputFileNames.end())
{
size_t Pos = It - Merge_OutputFileNames.begin();
OutputFrames_Speed = OutputFrames_Speeds[Pos];
OutputFrames_Concealed = OutputFrames_Concealeds[Pos];
}

for (const auto& File : PerFile)
{
if (File->PerFrame_Captions_PerSeq_PerField.empty())
continue; // Show the file only if there is some captions content

// filter
vector<size_t> IgnoredFrames;
if (!OutputFrames_Speed || !OutputFrames_Concealed)
{
for (auto Frame = File->PerFrame.begin(); Frame < File->PerFrame.end(); ++Frame)
{
coherency_flags Coherency(*Frame);
if (!OutputFrames_Concealed && Coherency.full_conceal())
{
IgnoredFrames.push_back(Frame - File->PerFrame.begin());
continue;
}

if (!OutputFrames_Speed && !GetDvSpeedIsNormalPlayback(GetDvSpeed(**Frame)))
{
IgnoredFrames.push_back(Frame - File->PerFrame.begin());
continue;
}
}
}

// Per Dseq
for (size_t i = 0; i < File->PerFrame_Captions_PerSeq_PerField.size(); i++) // Per Dseq
{
for (int j = 0; j < 2; j++) // Per field
{
string ScreenOutNameWithDseq(ScreenOutName);
string ScreenOutNameWithDseq(ScreenOut.Name);
if (!ScreenOutNameWithDseq.empty() && File->PerFrame_Captions_PerSeq_PerField.size() > 1)
InjectBeforeExtension(ScreenOutNameWithDseq, ".dseq", i);
string SrtOutNameWithDseq(SrtOutName);
string SrtOutNameWithDseq(SrtOut.Name);
if (!SrtOutNameWithDseq.empty() && File->PerFrame_Captions_PerSeq_PerField.size() > 1)
InjectBeforeExtension(SrtOutNameWithDseq, ".dseq", i);

if (!File->PerFrame_Captions_PerSeq_PerField[i].FieldData[j].empty() && !Output_Captions_Decode(ScreenOutNameWithDseq, SrtOutNameWithDseq, File->PerFrame_Captions_PerSeq_PerField[i].FieldData[j], j, Err))
if (!File->PerFrame_Captions_PerSeq_PerField[i].FieldData[j].empty() && !Output_Captions_Decode(ScreenOutNameWithDseq, SrtOutNameWithDseq, File->PerFrame_Captions_PerSeq_PerField[i].FieldData[j], IgnoredFrames, j, Err))
ToReturn = ReturnValue_ERROR;
}
}
Expand Down
3 changes: 2 additions & 1 deletion Source/Common/Output_Captions_Decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
#pragma once
#include <vector>
#include <ostream>
#include "Common/Core.h"
using namespace std;
class file;
//---------------------------------------------------------------------------

return_value Output_Captions_Caption(const string& ScreenOutName, const string& SrtOutName, const TimeCode* OffsetTimeCode, vector<file*>& PerFile, ostream* Err = nullptr);
return_value Output_Captions_Caption(const Core::OutFile& ScreenOut, const Core::OutFile& SrtOut, const TimeCode* OffsetTimeCode, vector<file*>& PerFile, ostream* Err = nullptr);
Loading
Loading