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 SkVideDecoder_DEFINED
9 #define SkVideDecoder_DEFINED
10 
11 #include "include/core/SkImage.h"
12 
13 extern "C" {
14 #include "libavcodec/avcodec.h"
15 #include "libavformat/avformat.h"
16 #include "libavformat/avio.h"
17 #include "libavutil/pixdesc.h"
18 #include "libswscale/swscale.h"
19 }
20 
21 class SkVideoDecoder {
22 public:
23     SkVideoDecoder(GrRecordingContext* = nullptr);
24     ~SkVideoDecoder();
25 
26     void reset();
setGrContext(GrRecordingContext * rContext)27     void setGrContext(GrRecordingContext* rContext) { fRecordingContext = rContext; }
28 
29     bool loadStream(std::unique_ptr<SkStream>);
30     bool rewind();
31 
32     SkISize dimensions() const;
33     double duration() const;    // in seconds
34 
35     // Returns each image in the video, or nullptr on eof
36     sk_sp<SkImage> nextImage(double* timeStamp = nullptr);
37 
38 private:
39     sk_sp<SkImage> convertFrame(const AVFrame*);
40     double computeTimeStamp(const AVFrame*) const;
41 
42     struct ConvertedColorSpace {
43         AVColorPrimaries              fPrimaries;
44         AVColorTransferCharacteristic fTransfer;
45         // fCS is the converted skia form of the above enums
46         sk_sp<SkColorSpace> fCS;
47 
48         // Init with illegal values, so our first compare will fail, forcing us to compute
49         // the skcolorspace.
50         ConvertedColorSpace();
51 
52         void update(AVColorPrimaries, AVColorTransferCharacteristic);
53     };
54 
55     GrRecordingContext* fRecordingContext = nullptr;  // not owned by us
56 
57     std::unique_ptr<SkStream>   fStream;
58 
59     AVIOContext*        fStreamCtx = nullptr;
60     AVFormatContext*    fFormatCtx = nullptr;
61     AVCodecContext*     fDecoderCtx = nullptr;
62     int                 fStreamIndex = -1;  // fFormatCtx->stream[...]
63 
64     AVPacket            fPacket;
65     AVFrame*            fFrame = nullptr;
66     ConvertedColorSpace fCSCache;
67 
68     enum Mode {
69         kProcessing_Mode,
70         kDraining_Mode,
71         kDone_Mode,
72     };
73     Mode    fMode = kDone_Mode;
74 };
75 
76 #endif
77 
78