Skip to content

Commit

Permalink
Merge pull request #29 from DSRCorporation/fix-unsync
Browse files Browse the repository at this point in the history
Fix unsync
  • Loading branch information
ashcherbakov authored Feb 17, 2017
2 parents 397d917 + 19df2e8 commit 932b59c
Show file tree
Hide file tree
Showing 22 changed files with 287 additions and 63 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,12 @@ metadata.xml file. After conversion done metadata.xml of resulting iTunes packag
Note 1:
* iTunes Package format requires special Audio Layout as defined in [iTunes Asset Guide](https://help.apple.com/itc/videoaudioassetguide/) for corresponding package type.
* Supported video formats can be found in wiki or documentation (docs/).
* To print all supported iTunes destination video formats run command with appropriate arguments:
* itunes
* --mode [-m] formats
```
imf-conversion-utility itunes -m formats
```
#### Prepare external tools used for conversion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public final class DppConversionConstants {
public static final String DYNAMIC_PARAM_OUTPUT_MXF = "output";
public static final String DYNAMIC_PARAM_TTML_TO_STL = "ttml-to-stl";
public static final String DYNAMIC_PARAM_METADATA_XML = "metadataXml";
public static final String DYNAMIC_PARAM_SAME_FPS = "sameFps";

// 1.3 dynamic parameters default values:
public static final String DYNAMIC_PARAM_VALUE_OUTPUT_MXF = "output";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,12 @@

import com.netflix.imfutility.AbstractFormatBuilder;
import com.netflix.imfutility.ConversionException;
import com.netflix.imfutility.conversion.templateParameter.ContextInfo;
import com.netflix.imfutility.conversion.templateParameter.ContextInfoBuilder;
import com.netflix.imfutility.conversion.templateParameter.context.DynamicTemplateParameterContext;
import com.netflix.imfutility.conversion.templateParameter.context.SequenceTemplateParameterContext;
import com.netflix.imfutility.conversion.templateParameter.context.parameters.DestContextParameters;
import com.netflix.imfutility.conversion.templateParameter.context.parameters.SequenceContextParameters;
import com.netflix.imfutility.cpl.uuid.SequenceUUID;
import com.netflix.imfutility.dpp.audio.AudioMapXmlProvider;
import com.netflix.imfutility.dpp.inputparameters.DppInputParameters;
Expand Down Expand Up @@ -51,6 +54,7 @@
import static com.netflix.imfutility.dpp.DppConversionConstants.DYNAMIC_PARAM_METADATA_XML;
import static com.netflix.imfutility.dpp.DppConversionConstants.DYNAMIC_PARAM_OUTPUT_MXF;
import static com.netflix.imfutility.dpp.DppConversionConstants.DYNAMIC_PARAM_PAN;
import static com.netflix.imfutility.dpp.DppConversionConstants.DYNAMIC_PARAM_SAME_FPS;
import static com.netflix.imfutility.dpp.DppConversionConstants.DYNAMIC_PARAM_TTML_TO_STL;
import static com.netflix.imfutility.dpp.DppConversionConstants.DYNAMIC_PARAM_UK_DPP_FILE;
import static com.netflix.imfutility.dpp.DppConversionConstants.DYNAMIC_PARAM_VALUE_OUTPUT_MXF;
Expand Down Expand Up @@ -131,6 +135,7 @@ protected void doBuildDynamicContextPostCpl() throws IOException, XmlParsingExce
dynamicContext.addParameter(DYNAMIC_PARAM_AS11_SEGM_FILE,
metadataXmlProvider.getBmxDppParameterFile(DMFramework.AS11Segmentation).getAbsolutePath(), true);

resolveSameFpsParameter();
}

@Override
Expand Down Expand Up @@ -187,6 +192,28 @@ private long getCplTotalDurationMs() {
return result;
}

private void resolveSameFpsParameter() {
ContextInfo contextInfo = new ContextInfoBuilder()
.setSequenceType(SequenceType.VIDEO)
.setSequenceUuid(getVideoSequenceUUID())
.build();

BigFraction seqFrameRate = ConversionHelper.parseEditRate(contextProvider.getSequenceContext().getParameterValue(
SequenceContextParameters.FRAME_RATE,
contextInfo));
BigFraction destFrameRate = ConversionHelper.parseEditRate(contextProvider.getDestContext().getParameterValue(
DestContextParameters.FRAME_RATE));

DynamicTemplateParameterContext dynamicContext = contextProvider.getDynamicContext();
dynamicContext.addParameter(DYNAMIC_PARAM_SAME_FPS, Boolean.toString(seqFrameRate.equals(destFrameRate)));
}

private SequenceUUID getVideoSequenceUUID() {
return contextProvider.getSequenceContext().getUuids(SequenceType.VIDEO).stream()
.findFirst()
.orElseThrow(() -> new ConversionException("Source must have at least one video sequence"));
}

@Override
protected void postConvert() throws IOException, XmlParsingException {
logger.info("Conversion output:");
Expand Down
17 changes: 15 additions & 2 deletions dpp-conversion/src/main/resources/xml/dpp-conversion.xml
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,25 @@
-t %{resource.durationTC} -an
-i "%{resource.essence}" -map 0:0
-vf
"scale=iw*sar*min(%{dest.width}/(iw*sar)\,%{dest.height}/ih):ih*min(%{dest.width}/(iw*sar)\,%{dest.height}/ih),pad=%{dest.width}:%{dest.height}:(ow-iw)/2:(oh-ih)/2,fps=%{dest.frameRate}"
"scale=iw*sar*min(%{dest.width}/(iw*sar)\,%{dest.height}/ih):ih*min(%{dest.width}/(iw*sar)\,%{dest.height}/ih),pad=%{dest.width}:%{dest.height}:(ow-iw)/2:(oh-ih)/2"
-pix_fmt %{dest.pixelFormat} -f rawvideo -
</execOnce>
</execEachSegment>

</cycle>

<execOnce name="change_fps" unless="%{dynamic.sameFps}">
%{tool.ffmpeg} -y
-f rawvideo
-pixel_format %{dest.pixelFormat}
-video_size %{dest.width}x%{dest.height}
-framerate %{seq.frame_rate}
-i -
-vf fps=%{dest.frameRate}
-pix_fmt %{dest.pixelFormat}
-f rawvideo
-
</execOnce>

<execOnce name="encode_video">
"%{tool.x264}" --input-res %{dest.width}x%{dest.height} --input-csp %{dest.chromaSubsampling} --input-depth %{dest.bitDepth} -
--colorprim %{dest.colorSpace} --transfer %{dest.colorSpace} --colormatrix %{dest.colorSpace} --tune psnr
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,17 @@
import com.netflix.imfutility.conversion.executor.ProcessStarter;
import com.netflix.imfutility.conversion.templateParameter.context.TemplateParameterContextProvider;
import com.netflix.imfutility.util.ImfLogger;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
* Execute all operations in a pipeline.
Expand Down Expand Up @@ -60,6 +63,8 @@ public class ExecutePipeStrategy extends AbstractExecuteStrategy {

private static final Logger LOGGER = new ImfLogger(LoggerFactory.getLogger(ExecutePipeStrategy.class));

private final Set<ImmutablePair<ExternalProcess, ExternalProcess>> startedPipes = new HashSet<>();

public ExecutePipeStrategy(TemplateParameterContextProvider contextProvider, ProcessStarter processStarter) {
super(contextProvider, processStarter);
}
Expand All @@ -69,6 +74,7 @@ public void execute(PipeOperationInfo operations) throws IOException {

List<ExternalProcess> tailProcesses = new ArrayList<>();

startedPipes.clear();
try {
// 1. start all tailing operation
startTailProcesses(actualOperations, tailProcesses);
Expand All @@ -82,6 +88,7 @@ public void execute(PipeOperationInfo operations) throws IOException {
} finally {
// 3. close all tail processes.
tailProcesses.forEach(ExternalProcess::finishClose);
startedPipes.clear();
}
}

Expand Down Expand Up @@ -136,7 +143,7 @@ private void pipe(List<ExternalProcess> pipeline) {
p1 = pipeline.get(i);
if (i + 1 < pipeline.size()) {
p2 = pipeline.get(i + 1);
new Thread(new Piper(p1, p2)).start();
startPiper(p1, p2);
}
}

Expand All @@ -145,6 +152,13 @@ private void pipe(List<ExternalProcess> pipeline) {
firstProcess.finishWaitFor();
}

private void startPiper(ExternalProcess p1, ExternalProcess p2) {
if (!startedPipes.contains(ImmutablePair.of(p1, p2))) {
new Thread(new Piper(p1, p2)).start();
startedPipes.add(ImmutablePair.of(p1, p2));
}
}

protected PipeOperationInfo skipPipeOperations(PipeOperationInfo operations) {
PipeOperationInfo newOperations = new PipeOperationInfo();
for (List<OperationInfo> cycleOperations : operations.getCycleOperations()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ public enum SequenceContextParameters {
LANGUAGE("language"),

// we assume that all resources within audio sequence has the same number of channels
CHANNELS_NUM("channels_num");
CHANNELS_NUM("channels_num"),
// we assume that all resources within video sequence has the same fps
FRAME_RATE("frame_rate");

private final String name;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,11 @@
import com.netflix.imfutility.generated.conversion.SequenceType;
import com.netflix.imfutility.generated.mediainfo.FfprobeType;
import com.netflix.imfutility.generated.mediainfo.StreamType;
import com.netflix.imfutility.util.ConversionHelper;
import com.netflix.imfutility.xml.XmlParser;
import com.netflix.imfutility.xml.XmlParsingException;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.math3.fraction.BigFraction;

import java.io.File;
import java.io.FileNotFoundException;
Expand Down Expand Up @@ -148,6 +150,17 @@ public void build() throws IOException, XmlParsingException, MediaInfoException
SequenceContextParameters.CHANNELS_NUM,
prevVirtualTrack.getParameters().get(ResourceContextParameters.CHANNELS_NUM));
}

// we assume all resources within an video sequence have the same fps
if (seqType == SequenceType.VIDEO && prevVirtualTrack.getParameters().containsKey(ResourceContextParameters.FRAME_RATE)) {

BigFraction frameRate = ConversionHelper.parseEditRate(prevVirtualTrack.getParameters()
.get(ResourceContextParameters.FRAME_RATE));
sequenceContext.addSequenceParameter(
seqType, seqUuid,
SequenceContextParameters.FRAME_RATE,
ConversionHelper.toREditRate(frameRate));
}
}
}
}
Expand Down Expand Up @@ -265,6 +278,13 @@ private void validateSequenceHomogeneous(VirtualTrackInfo prevVirtualTrackInfo,
throw new ConversionException(
"All audio resource tracks within an audio sequence (virtual track) must have the same number of channels!");
}

if (!Objects.equals(
prevVirtualTrackInfo.getParameters().get(ResourceContextParameters.FRAME_RATE),
nextVirtualTrackInfo.getParameters().get(ResourceContextParameters.FRAME_RATE))) {
throw new ConversionException(
"All video resource tracks within an video sequence (virtual track) must have the same fps!");
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,13 @@ public void testFillSequenceContext() throws Exception {
.setSequenceUuid(getSequenceUuid(1, SequenceType.AUDIO))
.build();
assertEquals("2", sequenceContext.getParameterValue(SequenceContextParameters.CHANNELS_NUM, contextInfo));

// first video track
contextInfo = new ContextInfoBuilder()
.setSequenceType(SequenceType.VIDEO)
.setSequenceUuid(getSequenceUuid(0, SequenceType.VIDEO))
.build();
assertEquals("50/1", sequenceContext.getParameterValue(SequenceContextParameters.FRAME_RATE, contextInfo));
}

@Test
Expand Down Expand Up @@ -323,7 +330,7 @@ FfprobeType parseOutputFile(File outputFile, ContextInfo contextInfo) throws Xml
assertEquals("1920", resourceContext.getParameterValue(ResourceContextParameters.WIDTH, contextInfo));
assertEquals("1080", resourceContext.getParameterValue(ResourceContextParameters.HEIGHT, contextInfo));
assertEquals("8", resourceContext.getParameterValue(ResourceContextParameters.BIT_DEPTH, contextInfo));
assertEquals("30 1", resourceContext.getParameterValue(ResourceContextParameters.FRAME_RATE, contextInfo));
assertEquals("50 1", resourceContext.getParameterValue(ResourceContextParameters.FRAME_RATE, contextInfo));
assertEquals("yuv420p10le", resourceContext.getParameterValue(ResourceContextParameters.PIXEL_FORMAT, contextInfo));
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ffprobe:ffprobe xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:ffprobe='http://www.ffmpeg.org/schema/ffprobe' xsi:schemaLocation='http://www.ffmpeg.org/schema/ffprobe ffprobe.xsd'>
<streams>
<stream index="0" codec_name="jpeg2000" codec_long_name="JPEG 2000" codec_type="video" codec_time_base="1/50" codec_tag_string="[0][0][0][0]" codec_tag="0x0000" width="1920" height="1080" coded_width="1920" coded_height="1080" has_b_frames="0" sample_aspect_ratio="1:1" display_aspect_ratio="256:135" pix_fmt="yuv420p10le" level="-99" refs="1" r_frame_rate="30/1" avg_frame_rate="0/0" time_base="1/50" start_pts="0" start_time="0.000000" duration_ts="1697" duration="33.940000" bits_per_raw_sample="8">
<stream index="0" codec_name="jpeg2000" codec_long_name="JPEG 2000" codec_type="video" codec_time_base="1/50" codec_tag_string="[0][0][0][0]" codec_tag="0x0000" width="1920" height="1080" coded_width="1920" coded_height="1080" has_b_frames="0" sample_aspect_ratio="1:1" display_aspect_ratio="256:135" pix_fmt="yuv420p10le" level="-99" refs="1" r_frame_rate="50/1" avg_frame_rate="0/0" time_base="1/50" start_pts="0" start_time="0.000000" duration_ts="1697" duration="33.940000" bits_per_raw_sample="8">
<disposition default="0" dub="0" original="0" comment="0" lyrics="0" karaoke="0" forced="0" hearing_impaired="0" visual_impaired="0" clean_effects="0" attached_pic="0"/>
<tag key="file_package_umid" value="0x060A2B340101010501010F20130000006A64F1C5629D43BEBEFCBEBAFED2E946"/>
<tag key="file_package_name" value="File Package"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ private ITunesConversionConstants() {
public static final String DYNAMIC_PARAM_VENDOR_ID = "vendorId";
public static final String DYNAMIC_PARAM_DEST_SOURCE = "destSource";
public static final String DYNAMIC_PARAM_IS_OSX = "isOSX";
public static final String DYNAMIC_PARAM_SAME_FPS = "sameFps";

// trailer dynamic parameters:
public static final String DYNAMIC_PARAM_TRAILER_MEDIAINFO_INPUT = "trailerMediaInfoInput";
Expand All @@ -48,9 +49,7 @@ private ITunesConversionConstants() {
// video dest parameters:
public static final String DEST_PARAM_VIDEO_IFRAME_RATE = "iFrameRate";
public static final String DEST_PARAM_VIDEO_IS_DAR_SPECIFIED = "isDarSpecified";
public static final String DEST_PARAM_VIDEO_END_BLACK_FRAME_COUNT = "endBlackFrameCount";
public static final String DEST_PARAM_VIDEO_SPECIFIED_FOR = "specifiedFor";
public static final String DEST_PARAM_AUDIO_SAMPLES_PER_FRAME = "samplesPerFrame";

// AudioMap constants
public static final String GEN_MAIN_SEQ_UUID = "urn:uuid:38d52c00-68d3-4056-8858-28eeaf3238d3";
Expand Down
Loading

0 comments on commit 932b59c

Please sign in to comment.