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 class SkCanvas; 22 class SkSurface; 23 24 // private to the impl 25 class SkRandomAccessWStream; 26 struct SwsContext; 27 28 class SkVideoEncoder { 29 public: 30 SkVideoEncoder(); 31 ~SkVideoEncoder(); 32 33 /** 34 * Begins a new recording. Balance this (after adding all of your frames) with a call 35 * to endRecording(). 36 */ 37 bool beginRecording(SkISize, int fps); 38 39 /** 40 * If you have your own pixmap, call addFrame(). Note this may fail if it uses an unsupported 41 * ColorType (requires kN32_SkColorType) or AlphaType, or the dimensions don't match those set 42 * in beginRecording. 43 */ 44 bool addFrame(const SkPixmap&); 45 46 /** 47 * As an alternative to calling addFrame(), you can call beginFrame/endFrame, and the encoder 48 * will manage allocating a surface/canvas for you. 49 * 50 * SkCanvas* canvas = encoder.beginFrame(); 51 * // your drawing code here, drawing into canvas 52 * encoder.endFrame(); 53 */ 54 SkCanvas* beginFrame(); 55 bool endFrame(); 56 57 /** 58 * Call this after having added all of your frames. After calling this, no more frames can 59 * be added to this recording. To record a new video, call beginRecording(). 60 */ 61 sk_sp<SkData> endRecording(); 62 63 private: 64 void reset(); 65 bool init(int fps); 66 bool sendFrame(AVFrame*); // frame can be null 67 68 double computeTimeStamp(const AVFrame*) const; 69 70 SwsContext* fSWScaleCtx = nullptr; 71 AVIOContext* fStreamCtx = nullptr; 72 AVFormatContext* fFormatCtx = nullptr; 73 AVCodecContext* fEncoderCtx = nullptr; 74 AVStream* fStream = nullptr; // we do not free this 75 AVFrame* fFrame = nullptr; 76 AVPacket* fPacket = nullptr; 77 78 SkImageInfo fInfo; // only defined between beginRecording() and endRecording() 79 std::unique_ptr<SkRandomAccessWStream> fWStream; 80 int64_t fCurrentPTS, fDeltaPTS; 81 82 // Lazily allocated, iff the client has called beginFrame() for a given recording session. 83 sk_sp<SkSurface> fSurface; 84 85 }; 86 87 #endif 88 89