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