| /* | 
 |  * Copyright 2019 Google Inc. | 
 |  * | 
 |  * Use of this source code is governed by a BSD-style license that can be | 
 |  * found in the LICENSE file. | 
 |  */ | 
 |  | 
 | #ifndef SkVideEncoder_DEFINED | 
 | #define SkVideEncoder_DEFINED | 
 |  | 
 | #include "include/core/SkImage.h" | 
 | #include "include/core/SkStream.h" | 
 |  | 
 | extern "C" { | 
 | #include "libavcodec/avcodec.h" | 
 | #include "libavformat/avformat.h" | 
 | #include "libavformat/avio.h" | 
 | #include "libavutil/pixdesc.h" | 
 | } | 
 |  | 
 | // private to the impl | 
 | class SkRandomAccessWStream; | 
 | struct SwsContext; | 
 |  | 
 | class SkVideoEncoder { | 
 | public: | 
 |     SkVideoEncoder(); | 
 |     ~SkVideoEncoder(); | 
 |  | 
 |     /** | 
 |      *  Begins a new recording. Balance this (after adding all of your frames) with a call | 
 |      *  to endRecording(). | 
 |      */ | 
 |     bool beginRecording(SkISize, int fps); | 
 |  | 
 |     /** | 
 |      *  If you have your own pixmap, call addFrame(). Note this may fail if it uses an unsupported | 
 |      *  ColorType (requires kN32_SkColorType) or AlphaType, or the dimensions don't match those set | 
 |      *  in beginRecording. | 
 |      */ | 
 |     bool addFrame(const SkPixmap&); | 
 |  | 
 |     /** | 
 |      *  As an alternative to calling addFrame(), you can call beginFrame/endFrame, and the encoder | 
 |      *  will manage allocating a surface/canvas for you. | 
 |      * | 
 |      *  SkCanvas* canvas = encoder.beginFrame(); | 
 |      *  // your drawing code here, drawing into canvas | 
 |      *  encoder.endFrame(); | 
 |      */ | 
 |     SkCanvas* beginFrame(); | 
 |     bool endFrame(); | 
 |  | 
 |     /** | 
 |      *  Call this after having added all of your frames. After calling this, no more frames can | 
 |      *  be added to this recording. To record a new video, call beginRecording(). | 
 |      */ | 
 |     sk_sp<SkData> endRecording(); | 
 |  | 
 | private: | 
 |     void reset(); | 
 |     bool init(int fps); | 
 |     bool sendFrame(AVFrame*);   // frame can be null | 
 |  | 
 |     double computeTimeStamp(const AVFrame*) const; | 
 |  | 
 |     SwsContext*     fSWScaleCtx = nullptr; | 
 |     AVIOContext*    fStreamCtx = nullptr; | 
 |     AVFormatContext* fFormatCtx = nullptr; | 
 |     AVCodecContext* fEncoderCtx = nullptr; | 
 |     AVStream*       fStream = nullptr;  // we do not free this | 
 |     AVFrame*        fFrame = nullptr; | 
 |     AVPacket*       fPacket = nullptr; | 
 |  | 
 |     SkImageInfo     fInfo;  // only defined between beginRecording() and endRecording() | 
 |     std::unique_ptr<SkRandomAccessWStream> fWStream; | 
 |     int64_t         fCurrentPTS, fDeltaPTS; | 
 |  | 
 |     // Lazily allocated, iff the client has called beginFrame() for a given recording session. | 
 |     sk_sp<SkSurface> fSurface; | 
 |  | 
 | }; | 
 |  | 
 | #endif | 
 |  |