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