• 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/H264NaluParser.h"
19 #include "host-common/H264PingInfoParser.h"
20 #include "host-common/MediaCodec.h"
21 #include "host-common/MediaH264DecoderPlugin.h"
22 #include "host-common/MediaHostRenderer.h"
23 
24 #include <VideoToolbox/VideoToolbox.h>
25 
26 #include <cstdint>
27 #include <string>
28 #include <vector>
29 
30 #include <stdio.h>
31 #include <string.h>
32 
33 #ifndef kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder
34 #define kVTVideoDecoderSpecification_RequireHardwareAcceleratedVideoDecoder CFSTR("RequireHardwareAcceleratedVideoDecoder")
35 #endif
36 
37 
38 #include <stddef.h>
39 
40 namespace android {
41 namespace emulation {
42 
43 class MediaH264DecoderVideoToolBox : public MediaH264DecoderPlugin {
44 public:
45     virtual void initH264Context(void* ptr) override;
46     virtual void reset(void* ptr) override;
47     virtual MediaH264DecoderPlugin* clone() override;
48     virtual void destroyH264Context() override;
49     virtual void decodeFrame(void* ptr) override;
50     virtual void flush(void* ptr) override;
51     virtual void getImage(void* ptr) override;
52 
53     virtual void save(base::Stream* stream) const override;
54     virtual bool load(base::Stream* stream) override;
55 
type()56     virtual int type() const override { return PLUGIN_TYPE_VIDEO_TOOL_BOX; }
57 
58 
59     explicit MediaH264DecoderVideoToolBox(uint64_t id,
60                                           H264PingInfoParser parser);
61     virtual ~MediaH264DecoderVideoToolBox();
62 
63 public:
64     enum class DecoderState {
65         BAD_STATE = 0,
66         GOOD_STATE = 1,
67     };
68 
getState()69     DecoderState getState() const {return mState;}
getSPS()70     std::vector<uint8_t> getSPS() const { return mSPS; }
getPPS()71     std::vector<uint8_t> getPPS() const { return mPPS; }
72 private:
73     void initH264ContextInternal(unsigned int width,
74                                  unsigned int height,
75                                  unsigned int outWidth,
76                                  unsigned int outHeight,
77                                  PixelFormat pixFmt);
78     uint64_t mId = 0;
79     H264PingInfoParser mParser;
80     MediaHostRenderer mRenderer;
81     DecoderState mState = DecoderState::GOOD_STATE;
82 
83     void decodeFrameInternal(size_t* pRetSzBytes, int32_t* pRetErr, const uint8_t* frame, size_t szBytes, uint64_t pts, size_t consumedSzBytes);
84     // Passes the Sequence Parameter Set (SPS) and Picture Parameter Set (PPS) to the
85     // videotoolbox decoder
86     CFDataRef createVTDecoderConfig();
87     // Callback passed to the VTDecompressionSession
88     static void videoToolboxDecompressCallback(void* opaque,
89                                                void* sourceFrameRefCon,
90                                                OSStatus status,
91                                                VTDecodeInfoFlags flags,
92                                                CVImageBufferRef image_buffer,
93                                                CMTime pts,
94                                                CMTime duration);
95     static CFDictionaryRef createOutputBufferAttributes(int width,
96                                                         int height,
97                                                         OSType pix_fmt);
98     static CMSampleBufferRef createSampleBuffer(CMFormatDescriptionRef fmtDesc,
99                                                 void* buffer,
100                                                 size_t sz);
101     static OSType toNativePixelFormat(PixelFormat fmt);
102 
103     // We should move these shared memory calls elsewhere, as vpx decoder is also using the same/similar
104     // functions
105     static void* getReturnAddress(void* ptr);
106     static uint8_t* getDst(void* ptr);
107 
108     void handleIDRFrame(const uint8_t* ptr, size_t szBytes, uint64_t pts);
109     void handleNonIDRFrame(const uint8_t* ptr, size_t szBytes, uint64_t pts);
110     void handleSEIFrame(const uint8_t* ptr, size_t szBytes);
111 
112     void createCMFormatDescription();
113     void recreateDecompressionSession();
114 
115     // The VideoToolbox decoder session
116     VTDecompressionSessionRef mDecoderSession = nullptr;
117     // The decoded video buffer
118     uint64_t mOutputPts = 0;
119     CVImageBufferRef mDecodedFrame = nullptr;
120     CMFormatDescriptionRef mCmFmtDesc = nullptr;
121     bool mImageReady = false;
122     static constexpr int kBPP = 2; // YUV420 is 2 bytes per pixel
123     unsigned int mOutputHeight = 0;
124     unsigned int mOutputWidth = 0;
125     unsigned int mWidth = 0;
126     unsigned int mHeight = 0;
127     PixelFormat mOutPixFmt;
128     // The calculated size of the outHeader buffer size allocated in the guest.
129     // It should be sizeY + (sizeUV * 2), where:
130     //  sizeY = outWidth * outHeight,
131     //  sizeUV = sizeY / 4
132     // It is equivalent to outWidth * outHeight * 3 / 2
133     unsigned int mOutBufferSize = 0;
134     std::vector<uint8_t> mSPS; // sps NALU
135     std::vector<uint8_t> mPPS; // pps NALU
136 
137     bool mIsInFlush = false;
138 private:
139 
140     bool mIsLoadingFromSnapshot = false;
141     std::vector<uint8_t> mSavedDecodedFrame;
142     void copyFrame();
143     void oneShotDecode(std::vector<uint8_t> & data, uint64_t pts);
144 
145     mutable SnapshotState  mSnapshotState;
146 
147 }; // MediaH264DecoderVideoToolBox
148 
149 
150 }  // namespace emulation
151 }  // namespace android
152