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