Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  VideoSegment.h   Sprache: C

 
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */


#ifndef MOZILLA_VIDEOSEGMENT_H_
#define MOZILLA_VIDEOSEGMENT_H_

#include "MediaSegment.h"
#include "nsCOMPtr.h"
#include "gfxPoint.h"
#include "ImageContainer.h"
#include "TimeUnits.h"

namespace mozilla {

namespace layers {
class Image;
}  // namespace layers

class VideoFrame {
 public:
  typedef mozilla::layers::Image Image;

  VideoFrame(already_AddRefed<Image> aImage,
             const gfx::IntSize& aIntrinsicSize);
  VideoFrame();
  ~VideoFrame();

  bool operator==(const VideoFrame& aFrame) const {
    return mIntrinsicSize == aFrame.mIntrinsicSize &&
           mForceBlack == aFrame.mForceBlack &&
           ((mForceBlack && aFrame.mForceBlack) || mImage == aFrame.mImage) &&
           mPrincipalHandle == aFrame.mPrincipalHandle;
  }
  bool operator!=(const VideoFrame& aFrame) const {
    return !operator==(aFrame);
  }

  Image* GetImage() const { return mImage; }
  void SetForceBlack(bool aForceBlack) { mForceBlack = aForceBlack; }
  bool GetForceBlack() const { return mForceBlack; }
  void SetPrincipalHandle(PrincipalHandle aPrincipalHandle) {
    mPrincipalHandle = std::forward<PrincipalHandle>(aPrincipalHandle);
  }
  const PrincipalHandle& GetPrincipalHandle() const { return mPrincipalHandle; }
  const gfx::IntSize& GetIntrinsicSize() const { return mIntrinsicSize; }
  void SetNull();
  void TakeFrom(VideoFrame* aFrame);

  // Create a planar YCbCr black image.
  static already_AddRefed<Image> CreateBlackImage(const gfx::IntSize& aSize);

 protected:
  // mImage can be null to indicate "no video" (aka "empty frame"). It can
  // still have an intrinsic size in this case.
  RefPtr<Image> mImage;
  // The desired size to render the video frame at.
  gfx::IntSize mIntrinsicSize;
  bool mForceBlack;
  // principalHandle for the image in this frame.
  // This can be compared to an nsIPrincipal when back on main thread.
  PrincipalHandle mPrincipalHandle;
};

struct VideoChunk {
  void SliceTo(TrackTime aStart, TrackTime aEnd) {
    NS_ASSERTION(aStart >= 0 && aStart < aEnd && aEnd <= mDuration,
                 "Slice out of bounds");
    mDuration = aEnd - aStart;
  }
  TrackTime GetDuration() const { return mDuration; }
  bool CanCombineWithFollowing(const VideoChunk& aOther) const {
    return aOther.mFrame == mFrame;
  }
  bool IsNull() const { return !mFrame.GetImage(); }
  void SetNull(TrackTime aDuration) {
    mDuration = aDuration;
    mFrame.SetNull();
    mTimeStamp = TimeStamp();
  }
  void SetForceBlack(bool aForceBlack) { mFrame.SetForceBlack(aForceBlack); }

  size_t SizeOfExcludingThisIfUnshared(MallocSizeOf aMallocSizeOf) const {
    // Future:
    // - mFrame
    return 0;
  }

  const PrincipalHandle& GetPrincipalHandle() const {
    return mFrame.GetPrincipalHandle();
  }

  TrackTime mDuration;
  VideoFrame mFrame;
  TimeStamp mTimeStamp;
  media::TimeUnit mProcessingDuration;
  media::TimeUnit mMediaTime;
  layers::ContainerCaptureTime mWebrtcCaptureTime = AsVariant(Nothing());
  layers::ContainerReceiveTime mWebrtcReceiveTime;
  layers::ContainerRtpTimestamp mRtpTimestamp;
};

class VideoSegment : public MediaSegmentBase<VideoSegment, VideoChunk> {
 public:
  typedef mozilla::layers::Image Image;
  typedef mozilla::gfx::IntSize IntSize;

  VideoSegment();
  VideoSegment(VideoSegment&& aSegment);

  VideoSegment(const VideoSegment&) = delete;
  VideoSegment& operator=(const VideoSegment&) = delete;

  ~VideoSegment();

  void AppendFrame(const VideoChunk& aChunk,
                   const Maybe<bool>& aForceBlack = Nothing(),
                   const Maybe<TimeStamp>& aTimeStamp = Nothing());
  void AppendFrame(
      already_AddRefed<Image>&& aImage, const IntSize& aIntrinsicSize,
      const PrincipalHandle& aPrincipalHandle, bool aForceBlack = false,
      TimeStamp aTimeStamp = TimeStamp::Now(),
      media::TimeUnit aProcessingDuration = media::TimeUnit::Invalid(),
      media::TimeUnit aMediaTime = media::TimeUnit::Invalid());
  void AppendWebrtcRemoteFrame(already_AddRefed<Image>&& aImage,
                               const IntSize& aIntrinsicSize,
                               const PrincipalHandle& aPrincipalHandle,
                               bool aForceBlack, TimeStamp aTimeStamp,
                               media::TimeUnit aProcessingDuration,
                               uint32_t aRtpTimestamp,
                               int64_t aWebrtcCaptureTimeNtp,
                               int64_t aWebrtcReceiveTimeUs);
  void AppendWebrtcLocalFrame(already_AddRefed<Image>&& aImage,
                              const IntSize& aIntrinsicSize,
                              const PrincipalHandle& aPrincipalHandle,
                              bool aForceBlack, TimeStamp aTimeStamp,
                              media::TimeUnit aProcessingDuration,
                              TimeStamp aWebrtcCaptureTime);
  void ExtendLastFrameBy(TrackTime aDuration) {
    if (aDuration <= 0) {
      return;
    }
    if (mChunks.IsEmpty()) {
      mChunks.AppendElement()->SetNull(aDuration);
    } else {
      mChunks[mChunks.Length() - 1].mDuration += aDuration;
    }
    mDuration += aDuration;
  }
  const VideoFrame* GetLastFrame(TrackTime* aStart = nullptr) {
    VideoChunk* c = GetLastChunk();
    if (!c) {
      return nullptr;
    }
    if (aStart) {
      *aStart = mDuration - c->mDuration;
    }
    return &c->mFrame;
  }
  VideoChunk* FindChunkContaining(const TimeStamp& aTime) {
    VideoChunk* previousChunk = nullptr;
    for (VideoChunk& c : mChunks) {
      if (c.mTimeStamp.IsNull()) {
        continue;
      }
      if (c.mTimeStamp > aTime) {
        return previousChunk;
      }
      previousChunk = &c;
    }
    return previousChunk;
  }
  void ForgetUpToTime(const TimeStamp& aTime) {
    VideoChunk* chunk = FindChunkContaining(aTime);
    if (!chunk) {
      return;
    }
    TrackTime duration = 0;
    size_t chunksToRemove = 0;
    for (const VideoChunk& c : mChunks) {
      if (c.mTimeStamp >= chunk->mTimeStamp) {
        break;
      }
      duration += c.GetDuration();
      ++chunksToRemove;
    }
    mChunks.RemoveElementsAt(0, chunksToRemove);
    mDuration -= duration;
    MOZ_ASSERT(mChunks.Capacity() >= DEFAULT_SEGMENT_CAPACITY,
               "Capacity must be retained after removing chunks");
  }
  // Override default impl
  void ReplaceWithDisabled() override {
    for (ChunkIterator i(*this); !i.IsEnded(); i.Next()) {
      VideoChunk& chunk = *i;
      chunk.SetForceBlack(true);
    }
  }

  // Segment-generic methods not in MediaSegmentBase
  static Type StaticType() { return VIDEO; }

  size_t SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const override {
    return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
  }
};

}  // namespace mozilla

#endif /* MOZILLA_VIDEOSEGMENT_H_ */

Messung V0.5
C=94 H=96 G=94

¤ Dauer der Verarbeitung: 0.3 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge