[Cellar] matroska and side data vs timecode

Dave Rice <dave@dericed.com> Tue, 29 October 2019 16:04 UTC

Return-Path: <dave@dericed.com>
X-Original-To: cellar@ietfa.amsl.com
Delivered-To: cellar@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 611FC120073 for <cellar@ietfa.amsl.com>; Tue, 29 Oct 2019 09:04:21 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.118
X-Spam-Level:
X-Spam-Status: No, score=-1.118 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_NEUTRAL=0.779, URIBL_BLOCKED=0.001] autolearn=no autolearn_force=no
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id PYDaToXyfFiH for <cellar@ietfa.amsl.com>; Tue, 29 Oct 2019 09:04:19 -0700 (PDT)
Received: from server172-3.web-hosting.com (server172-3.web-hosting.com [68.65.122.111]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 3FE0A12002F for <cellar@ietf.org>; Tue, 29 Oct 2019 09:04:19 -0700 (PDT)
Received: from [146.96.19.240] (port=46559 helo=[10.10.201.21]) by server172.web-hosting.com with esmtpsa (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.92) (envelope-from <dave@dericed.com>) id 1iPTyf-0016s7-Q6; Tue, 29 Oct 2019 12:04:18 -0400
From: Dave Rice <dave@dericed.com>
Content-Type: multipart/alternative; boundary="Apple-Mail=_AA62B11B-49B9-49CD-AB71-A6C163408D8F"
Mime-Version: 1.0 (Mac OS X Mail 12.4 \(3445.104.8\))
Date: Tue, 29 Oct 2019 12:04:07 -0400
Message-Id: <00F6A0BF-2922-4BAC-AC73-EB888767886F@dericed.com>
To: Codec Encoding for LossLess Archiving and Realtime transmission <cellar@ietf.org>
X-Mailer: Apple Mail (2.3445.104.8)
X-OutGoing-Spam-Status: No, score=-2.9
X-AntiAbuse: This header was added to track abuse, please include it with any abuse report
X-AntiAbuse: Primary Hostname - server172.web-hosting.com
X-AntiAbuse: Original Domain - ietf.org
X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12]
X-AntiAbuse: Sender Address Domain - dericed.com
X-Get-Message-Sender-Via: server172.web-hosting.com: authenticated_id: dave@dericed.com
X-Authenticated-Sender: server172.web-hosting.com: dave@dericed.com
X-Source:
X-Source-Args:
X-Source-Dir:
X-From-Rewrite: unmodified, already matched
Archived-At: <https://mailarchive.ietf.org/arch/msg/cellar/nfs0S7ALB7Im_ZdwftwuqiuXfD0>
Subject: [Cellar] matroska and side data vs timecode
X-BeenThere: cellar@ietf.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: Codec Encoding for LossLess Archiving and Realtime transmission <cellar.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/cellar>, <mailto:cellar-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/cellar/>
List-Post: <mailto:cellar@ietf.org>
List-Help: <mailto:cellar-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/cellar>, <mailto:cellar-request@ietf.org?subject=subscribe>
X-List-Received-Date: Tue, 29 Oct 2019 16:04:22 -0000

Hi cellar working group,

I wanted to share some recent and ongoing developments within https://github.com/cellar-wg/matroska-specification <https://github.com/cellar-wg/matroska-specification>.

Some background of recent Matroska side data work:

Recently a pull request at https://github.com/cellar-wg/matroska-specification/pull/287 was merged into the Matroska specification which adds a structure to identify, store, and describe side data to Matroska frames. This adds a block mapping to the TrackEntry that identifies the side data to a registry entry such as:

<Segment>
 <!-- skipped elements here -->
 <Tracks>
  <!-- lots of other track data here -->
  <TrackEntry>
   <BlockAdditionMapping>
    <BlockAddIDValue> {arbitrary value used to link BlockAddID (see the Cluster below) } </BlockAddIDValue>
    <BlockAddIDName>  {a human readable name for that side data}.   </BlockAddIDName>
    <BlockAddIDType>  {a registered ID for that type of side data}  </BlockAddIDType>
   </BlockAdditionMapping>
 </Tracks>
 <!-- then within the Cluster which stores audiovisual data within frames in Blocks, there is -->
 <Cluster>
  <BlockGroup>
   <Block> { some data, probably an audio or video frame } </Block>
   <BlockAdditions>
    <BlockMore>
     <BlockAddID> {arbitrary value used to link BlockAddIDValue (see above) } </BlockAddID>
     <BlockAdditional> { insert side data here, if the BlockAddID value is >=2 then look up what the data is in the BlockAdditionMapping } </BlockAdditional>
    </BlockMore>
   </BlockAdditions>
  </BlockGroup>
 </Cluster>
</Segment>

Within BlockMore, if the BlockAddID = 1 then the Codec Mapping defines what is within BlockAdditional as side data, but if the BlockAddID is >=2, then the identity of the BlockAdditional side data is defined within the BlockAdditionalMapping of the associated TrackEntry.

Active work on Matroska and timecode:

I drafted a pull request at https://github.com/cellar-wg/matroska-specification/pull/348 that builds upon the new side data structure defined above. This pull request registers a BlockAddIDType for a 64 bit binary expression of timecode as defined by SMPTE ST12-1:2014 (which is mostly hours, minutes, seconds, frames, a drop frame flag, and other a few other flags and binary groups). This would allow timecode to be associated with Matroska frames such as:

<Segment>
 <!-- skipped elements here --> 
 <Tracks>
  <!-- lots of other track data here -->
  <TrackEntry>
   <BlockAdditionMapping>
    <BlockAddIDValue>2</BlockAddIDValue>
    <BlockAddIDName>SMPTE ST 12-1 timecode</BlockAddIDName>
    <BlockAddIDType>121</BlockAddIDType>
   </BlockAdditionMapping>
 </Tracks>
 <!-- then within the Cluster which stores audiovisual data within frames in Blocks, there is -->
 <Cluster>
  <BlockGroup>
   <Block> { a video frame } </Block>
   <BlockAdditions>
    <BlockMore>
     <BlockAddID>2</BlockAddID>
     <BlockAdditional> { SMPTE ST12-1:2014 64-bit binary representation of a 07:32:54;18 } </BlockAdditional>
    </BlockMore>
   </BlockAdditions>
  </BlockGroup>
  <BlockGroup>
   <Block> { the next video frame } </Block>
   <BlockAdditions>
    <BlockMore>
     <BlockAddID>2</BlockAddID>
     <BlockAdditional> { SMPTE ST12-1:2014 64-bit binary representation of a 07:32:54;19 } </BlockAdditional>
    </BlockMore>
   </BlockAdditions>
  </BlockGroup>
 </Cluster>
</Segment>

With the BlockAdditions, BlockMore, BlockAddID, and BlockAdditional Elements, I think this would add 18 bytes per timecode expression. Adding timecode to one hour of PAL video (25 frames * 3600 seconds/hour) would add about 1.5 MB to the file.

Implementation Considerations:

Thinking ahead of this work, I think it would be worthwhile to add a dedicated section to the Matroska specification on timecode and describe two methods for adding a reference timecode to a Matroska Segment.

1. Using tags. Make an official tag “TIMECODE” to store a string of the timecode expression that correlates to the Matroska timestamp of 0. This approach is limited to storing timecode that is incremental and continuous. Defaults for the incrementation and the behavior of the timecode could be described as part of the tag definitions and feasibly another tag or tags could be reserved for timecode flags when the timecode behavior is not a default. Defining a use of a “TIMECODE” tag would provide the benefit of standardizing an existing practice in FFmpeg’s Matroska muxer, where rewrapping from a timecode-supportive format to Matroska carries the timecode value over as a tag.

2. Using BlockAdditions as described above. This adds more overhead as each timecode value would be written, but would support non-continuous timecode. In FFmpeg, timecode is sometimes carried as side-data such as from the decklink device via https://git.ffmpeg.org/gitweb/ffmpeg.git/commit/0946c0ec177dc48ef0677f890aa42d95e667c417 <https://git.ffmpeg.org/gitweb/ffmpeg.git/commit/0946c0ec177dc48ef0677f890aa42d95e667c417>. I’d be interested if the Block Addition Mapping described above could be used to carry the timecode side data from the decklink device (or other incoming stream with timecode side data) and store the result within the written Matroska BlockGroups.

Comments welcome.

Thanks much,
Dave Rice