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