• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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