• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2019 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #pragma once
16 
17 #include "host-common/GoldfishMediaDefs.h"
18 #include "host-common/H264PingInfoParser.h"
19 #include "host-common/MediaH264DecoderDefault.h"
20 #include "host-common/MediaH264DecoderPlugin.h"
21 #include "host-common/MediaHostRenderer.h"
22 
23 
24 extern "C" {
25 #include <libavcodec/avcodec.h>                 // for AVCodecContext, AVPacket
26 #include <libavformat/avio.h>                   // for avio_open, AVIO_FLAG_...
27 #include <libavutil/avutil.h>                   // for AVMediaType, AVMEDIA_...
28 #include <libavutil/dict.h>                     // for AVDictionary
29 #include <libavutil/error.h>                    // for av_make_error_string
30 #include <libavutil/frame.h>                    // for AVFrame, av_frame_alloc
31 #include <libavutil/log.h>                      // for av_log_set_callback
32 #include <libavutil/pixfmt.h>                   // for AVPixelFormat, AV_PIX...
33 #include <libavutil/rational.h>                 // for AVRational
34 #include <libavutil/samplefmt.h>                // for AVSampleFormat
35 #include <libavutil/timestamp.h>
36 }
37 
38 
39 #include <cstdint>
40 #include <string>
41 #include <vector>
42 
43 #include <stdio.h>
44 #include <string.h>
45 
46 
47 #include <stddef.h>
48 
49 namespace android {
50 namespace emulation {
51 
52 class MediaH264DecoderFfmpeg: public MediaH264DecoderPlugin {
53 public:
54     virtual void reset(void* ptr) override;
55     virtual void initH264Context(void* ptr) override;
56     virtual MediaH264DecoderPlugin* clone() override;
57     virtual void destroyH264Context() override;
58     virtual void decodeFrame(void* ptr) override;
59     virtual void flush(void* ptr) override;
60     virtual void getImage(void* ptr) override;
61 
62     virtual void save(base::Stream* stream) const override;
63     virtual bool load(base::Stream* stream) override;
64 
65     explicit MediaH264DecoderFfmpeg(uint64_t id, H264PingInfoParser parser);
66     virtual ~MediaH264DecoderFfmpeg();
67 
type()68     virtual int type() const override { return PLUGIN_TYPE_FFMPEG; }
69 
70     friend MediaH264DecoderDefault;
71 
72 public:
73     void decodeFrameDirect(void* ptr,
74                            const uint8_t* frame,
75                            size_t szBytes,
76                            uint64_t pts);
77 
78 private:
79     void decodeFrameInternal(H264PingInfoParser::DecodeFrameParam& param);
80 
81     void initH264ContextInternal(unsigned int width,
82                                  unsigned int height,
83                                  unsigned int outWidth,
84                                  unsigned int outHeight,
85                                  PixelFormat pixFmt);
86     uint64_t mId = 0;
87     H264PingInfoParser mParser;
88     MediaHostRenderer mRenderer;
89     // image props
90     int mNumDecodedFrame = 0;
91     bool mImageReady = false;
92     bool mIsSoftwareDecoder = true;
93     bool mIsInFlush = false;
94     bool mFrameFormatChanged = false;
95     static constexpr int kBPP = 2; // YUV420 is 2 bytes per pixel
96     unsigned int mWidth = 0;
97     unsigned int mHeight = 0;
98     unsigned int mOutputHeight = 0;
99     unsigned int mOutputWidth = 0;
100     unsigned int mColorPrimaries = 2;
101     unsigned int mColorRange = 0;
102     unsigned int mColorTransfer = 2;
103     unsigned int mColorSpace = 2;
104     uint64_t mOutputPts = 0;
105     uint64_t mInputPts = 0;
106     unsigned int mSurfaceHeight = 0;
107     unsigned int mBPP = 0;
108     unsigned int mSurfaceWidth = 0;
109     unsigned int mLumaHeight = 0;
110     unsigned int mChromaHeight = 0;
111     PixelFormat mOutPixFmt;
112     unsigned int mOutBufferSize = 0;
113 
114     // right now, decoding command only passes the input address;
115     // and output address is only available in getImage().
116     // TODO: this should be set to the output address to avoid
117     // extra copying
118     std::vector<uint8_t> mDecodedFrame;
119 
120     // ffmpeg stuff
121     AVCodec *mCodec = nullptr;;
122     AVCodecContext *mCodecCtx = nullptr;
123     AVFrame *mFrame = nullptr;
124     AVPacket mPacket;
125 
126 private:
127     mutable SnapshotState mSnapshotState;
128 
129 private:
130     void copyFrame();
131     void resetDecoder();
132     bool checkWhetherConfigChanged(const uint8_t* frame, size_t szBytes);
133 
134     void oneShotDecode(std::vector<uint8_t>& data, uint64_t pts);
135 };  // MediaH264DecoderFfmpeg
136 
137 
138 }  // namespace emulation
139 }  // namespace android
140