With this feature that is also called "transwrapping", you can trim a local file, capture a network stream to a local file, or transcode a list of files in a single file of the same or different container. Note, that for a playlist all the files should be of the same codecs and format (resolution, frame rate, etc).
The feature is based on an approach where data packets from a source (a network stream or a file) are extracted and the same packets are used to create new frames in the output file. The packets are not changed in this process. And as a result, you'll get a direct copy of your source file.
It is similar to the FFmpeg "copy" feature, but it works differently within SDKs.
Since 2.12.0.15019 SDK version, Closed Captions (CC) can also be transwrapped. Just add "embed_cc=true" to your configuration string.
Required settings
Transcoding works within a single process - in this mode, the packets are processed within a single thread so they are not changed. Below you can find additional settings you need to set.
MFormats
m_objMFReader.PropsSet("experimental.mfcodecs", "true");
m_objMFReader.PropsSet("experimental.out_video_packets", "true");
m_objMFReader.PropsSet("experimental.out_audio_packets", "true");
m_objMFReader.PropsSet("external_process", "false");
m_objMFWriter.PropsSet("external_process", "false");MPlatform
For MPlaylist, you should set the properties directly the moment you add a file to the playlist:
m_objPlaylist.PlaylistAdd(null, openMediaFile.FileNames[i], "external_process=false experimental.mfcodecs=true experimental.out_video_packets=true experimental.out_audio_packets=true", ref nIndex, out pFile);For MFile, the properties should be set within a FileNameSet method:
myFile.FileNameSet(pathToFile, "external_process=false experimental.mfcodecs=true experimental.out_video_packets=true experimental.out_audio_packets=true");And for MWriter you should disable external processing:
m_objWriter.PropsSet("external_process", "false");Important! This feature works for original video sources only. Don't use any conversion, i.e. FormatVideoSet(eMFT_Convert, ...) or SourceFrameConvertedGet methods.
If you set the "experimental.out_video_packets" to "true" or "1", the video is still decoded so you can use it for preview. If you don't need the preview and you'd like to increase the overall speed of the encoding, consider setting the following:
m_objMFReader.PropsSet("experimental.out_video_packets", "2");
m_objMFReader.PropsSet("experimental.out_audio_packets", "2");In this case, the video and audio data is not decoded.
Encoding configuration
You should use a specific video and audio codecs for transcoding - "packets" as a video codec and audio codec. For example, for MP4 container, the encoding configuration looks like:
format='mp4' video::codec='packets' audio::codec='packets'DVB Subtitles transwrapping
Since SDK version 2.7.2 you can also transwrap DVB Subtitles. For example, your source has two subtitle tracks, to transwrapp them into TS file, you should follow these steps:
1. Disable "external_process" for MFReader/MFile object as usual.
2. Select desired subtitle tracks and set "experimental.out_subtitle_packets" to "true".
As a result you will get:
myFile.FileNameSet(pathToFile, "external_process=false experimental.mfcodecs=true experimental.out_video_packets=true experimental.out_audio_packets=true experimental.out_subtitle_packets=true subtitle_track=0,1");4. Set "packets" as subtitles codec in the Writer config string (all tracks will be transwrapped):
format='mpegts' video::codec='packets' audio::codec='packets' subtitle::codec='packets'Also, you can specify subtitles metadata and custom PID numbers for each track if necessary:
subtitle::metadata::language='eng' subtitle.1::metadata::language='ger' subtitle::streamid='1200' subtitle.1::streamid='1201'5. Run the transcoding process.
Please note that if you set the "experimental.out_subtitle_packets" to "true" (equal to "1"), subtitles are still decoded so you can use them for preview (as this described in the according article - Displaying-DVB-subtitles-from-TS-file), but they also will be burned-in to the recorded file. If you don't need the preview, you can set the "experimental.out_subtitle_packets" to "2".
Important note about using MPlaylist as a source for subtitles transwrapping. If the first playlist item doesn't contain any subtitle data, the following property must be set to be able to run the MWriter object:
Computer\HKEY_CURRENT_USER\Software\Medialooks\MPlatform\MWriter\MWriterFFM
subtitle.init_without_data = trueIf you start MWriter object before MPlaylist, you should also disable playlist background, for example:
m_objPlaylist.PlaylistBackgroundSet(null, null, null, out _);Preserving MXF pre-charge and track origin
Some MXF files contain leading frames that are required for decoding but should not be presented during normal playback. These frames are called pre-charge or pre-roll. The MXF track origin identifies the intended playback start after these frames.
When transwrapping such files to MXF, the SDK can preserve this information so that playback starts at the intended frame instead of displaying the leading pre-charge frames.
| Parameter | Applied to | Default | Description |
|---|---|---|---|
mxf.use_track_origin |
MFReader / MFile | false |
Makes the Reader honor the source MXF track origin and identify pre-charge packets. Enable before opening the source. |
track_origin |
MFWriter / MWriter configuration |
0 — automatic |
Sets the output MXF track origin in edit units, normally video frames. A positive value overrides automatic selection. |
For automatic preservation, enable mxf.use_track_origin=true on the source and leave track_origin unspecified in the Writer configuration. The MXF muxer can derive the origin from the leading video packets marked as pre-charge.
MFormats SDK:
myReader.ReaderOpen(pathToFile, "external_process=false experimental.mfcodecs=true experimental.out_video_packets=1 experimental.out_audio_packets=1 mxf.use_track_origin=true");
myWriter.PropsSet("external_process", "false");
myWriter.WriterSet(pathToOutput, 1, "format='mxf' video::codec='packets' audio::codec='packets'");Pass the original frames from the Reader to the Writer without format conversion, as described above.
MPlatform SDK:
myFile.FileNameSet(pathToFile, "external_process=false experimental.mfcodecs=true experimental.out_video_packets=true experimental.out_audio_packets=true mxf.use_track_origin=true");
myWriter.PropsSet("external_process", "false");
myWriter.WriterNameSet(pathToOutput, "format='mxf' video::codec='packets' audio::codec='packets'");If an explicit origin is required, add track_origin to the Writer configuration:
format='mxf' track_origin='5' video::codec='packets' audio::codec='packets'This declares five edit units of pre-charge before the intended playback start. It changes the MXF origin metadata; it does not physically remove or add encoded frames.
Note: Track origin is separate from the starting timecode. To play or verify the resulting MXF in the SDK while honoring its origin, open it with mxf.use_track_origin=true as well.
Still have questions?
Tell us what didn’t work or what you’d like clarified.