Bug 1320705: P5. Pass discard padding information from ogg container. r=kinetik
authorJean-Yves Avenard <jyavenard@mozilla.com>
Wed, 30 Nov 2016 17:44:49 +1100
changeset 325259 7495e866529ebd20352e63eb2b25dfa688a7dfd2
parent 325258 d330cc7e9094d9e8d832280e3f0c125f876f8b68
child 325260 05a07920b83263f12235f283c5869be656dba405
push id24
push usermaklebus@msu.edu
push dateTue, 20 Dec 2016 03:11:33 +0000
reviewerskinetik
bugs1320705
milestone53.0a1
Bug 1320705: P5. Pass discard padding information from ogg container. r=kinetik MozReview-Commit-ID: 8UKSVM0F0xF
dom/media/ogg/OggCodecState.cpp
dom/media/ogg/OggCodecState.h
--- a/dom/media/ogg/OggCodecState.cpp
+++ b/dom/media/ogg/OggCodecState.cpp
@@ -1227,16 +1227,47 @@ OpusState::ReconstructOpusGranulepos(voi
   // We MUST reject such streams.
   if (!mDoneReadingHeaders && GetOpusDeltaGP(mUnstamped[0]) > gp) {
     return false;
   }
   mPrevPageGranulepos = last->granulepos;
   return true;
 }
 
+already_AddRefed<MediaRawData>
+OpusState::PacketOutAsMediaRawData()
+{
+  ogg_packet* packet = PacketPeek();
+  uint32_t frames = 0;
+  const int64_t endFrame = packet->granulepos;
+
+  if (!packet) {
+    return nullptr;
+  }
+  if (packet->e_o_s) {
+    frames = GetOpusDeltaGP(packet);
+  }
+
+  RefPtr<MediaRawData> data = OggCodecState::PacketOutAsMediaRawData();
+
+  if (data->mEOS && mPrevPacketGranulepos != -1) {
+    // If this is the last packet, perform end trimming.
+    int64_t startFrame = mPrevPacketGranulepos;
+    frames -= std::max<int64_t>(
+      0, std::min(endFrame - startFrame, static_cast<int64_t>(frames)));
+    data->mDiscardPadding = frames;
+  }
+
+  // Save this packet's granule position in case we need to perform end
+  // trimming on the next packet.
+  mPrevPacketGranulepos = endFrame;
+
+  return data.forget();
+}
+
 FlacState::FlacState(ogg_page* aBosPage)
   : OggCodecState(aBosPage, true)
 {
 }
 
 bool
 FlacState::DecodeHeader(ogg_packet* aPacket)
 {
--- a/dom/media/ogg/OggCodecState.h
+++ b/dom/media/ogg/OggCodecState.h
@@ -386,17 +386,17 @@ public:
   bool DecodeHeader(ogg_packet* aPacket) override;
   int64_t Time(int64_t aGranulepos) override;
   int64_t PacketDuration(ogg_packet* aPacket) override;
   bool Init() override;
   nsresult Reset() override;
   nsresult Reset(bool aStart);
   bool IsHeader(ogg_packet* aPacket) override;
   nsresult PageIn(ogg_page* aPage) override;
-
+  already_AddRefed<MediaRawData> PacketOutAsMediaRawData() override;
   // Returns the end time that a granulepos represents.
   static int64_t Time(int aPreSkip, int64_t aGranulepos);
 
   // Various fields from the Ogg Opus header.
   int mRate;        // Sample rate the decoder uses (always 48 kHz).
   int mChannels;    // Number of channels the stream encodes.
   uint16_t mPreSkip; // Number of samples to strip after decoder reset.
 #ifdef MOZ_SAMPLE_TYPE_FLOAT32