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