blob: 53be2124a8c9c6945cdd8f81256805c83e3fb608 [file] [log] [blame]
/*
* 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"
}
class SkCanvas;
class SkSurface;
// 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