1 /* 2 * Copyright 2019 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkVideEncoder_DEFINED 9 #define SkVideEncoder_DEFINED 10 11 #include "include/core/SkImage.h" 12 #include "include/core/SkStream.h" 13 14 extern "C" { 15 #include "libavcodec/avcodec.h" 16 #include "libavformat/avformat.h" 17 #include "libavformat/avio.h" 18 #include "libavutil/pixdesc.h" 19 } 20 21 // private to the impl 22 class SkRandomAccessWStream; 23 struct SwsContext; 24 25 class SkVideoEncoder { 26 public: 27 SkVideoEncoder(); 28 ~SkVideoEncoder(); 29 30 /** 31 * Begins a new recording. Balance this (after adding all of your frames) with a call 32 * to endRecording(). 33 */ 34 bool beginRecording(SkISize, int fps); 35 36 /** 37 * If you have your own pixmap, call addFrame(). Note this may fail if it uses an unsupported 38 * ColorType (requires kN32_SkColorType) or AlphaType, or the dimensions don't match those set 39 * in beginRecording. 40 */ 41 bool addFrame(const SkPixmap&); 42 43 /** 44 * As an alternative to calling addFrame(), you can call beginFrame/endFrame, and the encoder 45 * will manage allocating a surface/canvas for you. 46 * 47 * SkCanvas* canvas = encoder.beginFrame(); 48 * // your drawing code here, drawing into canvas 49 * encoder.endFrame(); 50 */ 51 SkCanvas* beginFrame(); 52 bool endFrame(); 53 54 /** 55 * Call this after having added all of your frames. After calling this, no more frames can 56 * be added to this recording. To record a new video, call beginRecording(). 57 */ 58 sk_sp<SkData> endRecording(); 59 60 private: 61 void reset(); 62 bool init(int fps); 63 bool sendFrame(AVFrame*); // frame can be null 64 65 double computeTimeStamp(const AVFrame*) const; 66 67 SwsContext* fSWScaleCtx = nullptr; 68 AVIOContext* fStreamCtx = nullptr; 69 AVFormatContext* fFormatCtx = nullptr; 70 AVCodecContext* fEncoderCtx = nullptr; 71 AVStream* fStream = nullptr; // we do not free this 72 AVFrame* fFrame = nullptr; 73 AVPacket* fPacket = nullptr; 74 75 SkImageInfo fInfo; // only defined between beginRecording() and endRecording() 76 std::unique_ptr<SkRandomAccessWStream> fWStream; 77 int64_t fCurrentPTS, fDeltaPTS; 78 79 // Lazily allocated, iff the client has called beginFrame() for a given recording session. 80 sk_sp<SkSurface> fSurface; 81 82 }; 83 84 #endif 85 86