1/*
2 * Copyright 2012, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef CONVERTER_H_
18
19#define CONVERTER_H_
20
21#include <media/stagefright/foundation/AHandler.h>
22
23namespace android {
24
25struct ABuffer;
26class IGraphicBufferProducer;
27struct MediaCodec;
28
29#define ENABLE_SILENCE_DETECTION        0
30
31// Utility class that receives media access units and converts them into
32// media access unit of a different format.
33// Right now this'll convert raw video into H.264 and raw audio into AAC.
34struct Converter : public AHandler {
35    enum {
36        kWhatAccessUnit,
37        kWhatEOS,
38        kWhatError,
39        kWhatShutdownCompleted,
40    };
41
42    enum FlagBits {
43        FLAG_USE_SURFACE_INPUT          = 1,
44        FLAG_PREPEND_CSD_IF_NECESSARY   = 2,
45    };
46    Converter(const sp<AMessage> &notify,
47              const sp<ALooper> &codecLooper,
48              const sp<AMessage> &outputFormat,
49              uint32_t flags = 0);
50
51    status_t init();
52
53    sp<IGraphicBufferProducer> getGraphicBufferProducer();
54
55    size_t getInputBufferCount() const;
56
57    sp<AMessage> getOutputFormat() const;
58    bool needToManuallyPrependSPSPPS() const;
59
60    void feedAccessUnit(const sp<ABuffer> &accessUnit);
61    void signalEOS();
62
63    void requestIDRFrame();
64
65    void dropAFrame();
66    void suspendEncoding(bool suspend);
67
68    void shutdownAsync();
69
70    int32_t getVideoBitrate() const;
71    void setVideoBitrate(int32_t bitrate);
72
73    static int32_t GetInt32Property(const char *propName, int32_t defaultValue);
74
75    enum {
76        // MUST not conflict with private enums below.
77        kWhatMediaPullerNotify = 'pulN',
78    };
79
80protected:
81    virtual ~Converter();
82    virtual void onMessageReceived(const sp<AMessage> &msg);
83
84private:
85    enum {
86        kWhatDoMoreWork,
87        kWhatRequestIDRFrame,
88        kWhatSuspendEncoding,
89        kWhatShutdown,
90        kWhatEncoderActivity,
91        kWhatDropAFrame,
92        kWhatReleaseOutputBuffer,
93    };
94
95    sp<AMessage> mNotify;
96    sp<ALooper> mCodecLooper;
97    sp<AMessage> mOutputFormat;
98    uint32_t mFlags;
99    bool mIsVideo;
100    bool mIsH264;
101    bool mIsPCMAudio;
102    bool mNeedToManuallyPrependSPSPPS;
103
104    sp<MediaCodec> mEncoder;
105    sp<AMessage> mEncoderActivityNotify;
106
107    sp<IGraphicBufferProducer> mGraphicBufferProducer;
108
109    Vector<sp<ABuffer> > mEncoderInputBuffers;
110    Vector<sp<ABuffer> > mEncoderOutputBuffers;
111
112    List<size_t> mAvailEncoderInputIndices;
113
114    List<sp<ABuffer> > mInputBufferQueue;
115
116    sp<ABuffer> mCSD0;
117
118    bool mDoMoreWorkPending;
119
120#if ENABLE_SILENCE_DETECTION
121    int64_t mFirstSilentFrameUs;
122    bool mInSilentMode;
123#endif
124
125    sp<ABuffer> mPartialAudioAU;
126
127    int32_t mPrevVideoBitrate;
128
129    int32_t mNumFramesToDrop;
130    bool mEncodingSuspended;
131
132    status_t initEncoder();
133    void releaseEncoder();
134
135    status_t feedEncoderInputBuffers();
136
137    void scheduleDoMoreWork();
138    status_t doMoreWork();
139
140    void notifyError(status_t err);
141
142    // Packetizes raw PCM audio data available in mInputBufferQueue
143    // into a format suitable for transport stream inclusion and
144    // notifies the observer.
145    status_t feedRawAudioInputBuffers();
146
147    static bool IsSilence(const sp<ABuffer> &accessUnit);
148
149    sp<ABuffer> prependCSD(const sp<ABuffer> &accessUnit) const;
150
151    DISALLOW_EVIL_CONSTRUCTORS(Converter);
152};
153
154}  // namespace android
155
156#endif  // CONVERTER_H_
157