screenrecord.cpp revision 7a66622c2c9250ce4ad0091195331ce4cb91a63d
1576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma/*
2576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma * Copyright 2013 The Android Open Source Project
3576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma *
4576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma * Licensed under the Apache License, Version 2.0 (the "License");
5576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma * you may not use this file except in compliance with the License.
6576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma * You may obtain a copy of the License at
7576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma *
8576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma *      http://www.apache.org/licenses/LICENSE-2.0
9576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma *
10576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma * Unless required by applicable law or agreed to in writing, software
11576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma * distributed under the License is distributed on an "AS IS" BASIS,
12576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma * See the License for the specific language governing permissions and
14576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma * limitations under the License.
15576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma */
16576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
17576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#define LOG_TAG "ScreenRecord"
18576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#define ATRACE_TAG ATRACE_TAG_GRAPHICS
19576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma//#define LOG_NDEBUG 0
20576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <utils/Log.h>
21576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
22576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <binder/IPCThreadState.h>
23576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <utils/Errors.h>
24576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <utils/Timers.h>
25576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <utils/Trace.h>
26576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
27576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <gui/Surface.h>
28576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <gui/SurfaceComposerClient.h>
29576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <gui/ISurfaceComposer.h>
30576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <ui/DisplayInfo.h>
31576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <media/openmax/OMX_IVCommon.h>
32576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <media/stagefright/foundation/ABuffer.h>
33576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <media/stagefright/foundation/AMessage.h>
34576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <media/stagefright/MediaCodec.h>
35576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <media/stagefright/MediaErrors.h>
36576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <media/stagefright/MediaMuxer.h>
37576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <media/ICrypto.h>
38576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
39576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <stdlib.h>
40576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <unistd.h>
41576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <string.h>
42576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <stdio.h>
43576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <ctype.h>
44576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <fcntl.h>
45576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <signal.h>
46576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <getopt.h>
47576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <sys/wait.h>
48576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include <assert.h>
49576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
50576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include "screenrecord.h"
51576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma#include "Overlay.h"
52576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
53576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmausing namespace android;
54576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
55576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmastatic const uint32_t kMinBitRate = 100000;         // 0.1Mbps
56576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmastatic const uint32_t kMaxBitRate = 200 * 1000000;  // 200Mbps
57576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmastatic const uint32_t kMaxTimeLimitSec = 180;       // 3 minutes
58576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmastatic const uint32_t kFallbackWidth = 1280;        // 720p
59576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmastatic const uint32_t kFallbackHeight = 720;
60576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
61576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma// Command-line parameters.
62576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmastatic bool gVerbose = false;           // chatty on stdout
63576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmastatic bool gRotate = false;            // rotate 90 degrees
64576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmastatic bool gSizeSpecified = false;     // was size explicitly requested?
65576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmastatic bool gWantInfoScreen = false;    // do we want initial info screen?
66576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmastatic bool gWantFrameTime = false;     // do we want times on each frame?
67576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmastatic uint32_t gVideoWidth = 0;        // default width+height
68576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmastatic uint32_t gVideoHeight = 0;
69576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmastatic uint32_t gBitRate = 4000000;     // 4Mbps
70576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmastatic uint32_t gTimeLimitSec = kMaxTimeLimitSec;
71576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
72576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma// Set by signal handler to stop recording.
73576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmastatic volatile bool gStopRequested;
74576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
75576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma// Previous signal handler state, restored after first hit.
76576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmastatic struct sigaction gOrigSigactionINT;
77576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmastatic struct sigaction gOrigSigactionHUP;
78576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
79576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
80576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma/*
81576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma * Catch keyboard interrupt signals.  On receipt, the "stop requested"
82e9f161a677087dfdf8e543b9e70c7131ac3fd942Tommi Rantala * flag is raised, and the original handler is restored (so that, if
83576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma * we get stuck finishing, a second Ctrl-C will kill the process).
84576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma */
85576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmastatic void signalCatcher(int signum)
86576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma{
87576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma    gStopRequested = true;
88e9f161a677087dfdf8e543b9e70c7131ac3fd942Tommi Rantala    switch (signum) {
89576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma    case SIGINT:
90576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma    case SIGHUP:
91576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma        sigaction(SIGINT, &gOrigSigactionINT, NULL);
92576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma        sigaction(SIGHUP, &gOrigSigactionHUP, NULL);
93576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma        break;
94e9f161a677087dfdf8e543b9e70c7131ac3fd942Tommi Rantala    default:
95576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma        abort();
96576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma        break;
97576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma    }
98576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma}
99576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma
10047a99b6f0007c69959d7d56e52243c1780102d80Tommi Rantala/*
101576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma * Configures signal handlers.  The previous handlers are saved.
102576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma *
103576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma * If the command is run from an interactive adb shell, we get SIGINT
104576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma * when Ctrl-C is hit.  If we're run from the host, the local adb process
105576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma * gets the signal, and we get a SIGHUP when the terminal disconnects.
106576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma */
107576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharmastatic status_t configureSignals() {
108576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma    struct sigaction act;
109576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma    memset(&act, 0, sizeof(act));
110576b59e4b15ddf2f2d3f17036b9c2f43c7504777Arun Sharma    act.sa_handler = signalCatcher;
111    if (sigaction(SIGINT, &act, &gOrigSigactionINT) != 0) {
112        status_t err = -errno;
113        fprintf(stderr, "Unable to configure SIGINT handler: %s\n",
114                strerror(errno));
115        return err;
116    }
117    if (sigaction(SIGHUP, &act, &gOrigSigactionHUP) != 0) {
118        status_t err = -errno;
119        fprintf(stderr, "Unable to configure SIGHUP handler: %s\n",
120                strerror(errno));
121        return err;
122    }
123    return NO_ERROR;
124}
125
126/*
127 * Returns "true" if the device is rotated 90 degrees.
128 */
129static bool isDeviceRotated(int orientation) {
130    return orientation != DISPLAY_ORIENTATION_0 &&
131            orientation != DISPLAY_ORIENTATION_180;
132}
133
134/*
135 * Configures and starts the MediaCodec encoder.  Obtains an input surface
136 * from the codec.
137 */
138static status_t prepareEncoder(float displayFps, sp<MediaCodec>* pCodec,
139        sp<IGraphicBufferProducer>* pBufferProducer) {
140    status_t err;
141
142    if (gVerbose) {
143        printf("Configuring recorder for %dx%d video at %.2fMbps\n",
144                gVideoWidth, gVideoHeight, gBitRate / 1000000.0);
145    }
146
147    sp<AMessage> format = new AMessage;
148    format->setInt32("width", gVideoWidth);
149    format->setInt32("height", gVideoHeight);
150    format->setString("mime", "video/avc");
151    format->setInt32("color-format", OMX_COLOR_FormatAndroidOpaque);
152    format->setInt32("bitrate", gBitRate);
153    format->setFloat("frame-rate", displayFps);
154    format->setInt32("i-frame-interval", 10);
155
156    sp<ALooper> looper = new ALooper;
157    looper->setName("screenrecord_looper");
158    looper->start();
159    ALOGV("Creating codec");
160    sp<MediaCodec> codec = MediaCodec::CreateByType(looper, "video/avc", true);
161    if (codec == NULL) {
162        fprintf(stderr, "ERROR: unable to create video/avc codec instance\n");
163        return UNKNOWN_ERROR;
164    }
165
166    err = codec->configure(format, NULL, NULL,
167            MediaCodec::CONFIGURE_FLAG_ENCODE);
168    if (err != NO_ERROR) {
169        fprintf(stderr, "ERROR: unable to configure codec (err=%d)\n", err);
170        codec->release();
171        return err;
172    }
173
174    ALOGV("Creating encoder input surface");
175    sp<IGraphicBufferProducer> bufferProducer;
176    err = codec->createInputSurface(&bufferProducer);
177    if (err != NO_ERROR) {
178        fprintf(stderr,
179            "ERROR: unable to create encoder input surface (err=%d)\n", err);
180        codec->release();
181        return err;
182    }
183
184    ALOGV("Starting codec");
185    err = codec->start();
186    if (err != NO_ERROR) {
187        fprintf(stderr, "ERROR: unable to start codec (err=%d)\n", err);
188        codec->release();
189        return err;
190    }
191
192    ALOGV("Codec prepared");
193    *pCodec = codec;
194    *pBufferProducer = bufferProducer;
195    return 0;
196}
197
198/*
199 * Sets the display projection, based on the display dimensions, video size,
200 * and device orientation.
201 */
202static status_t setDisplayProjection(const sp<IBinder>& dpy,
203        const DisplayInfo& mainDpyInfo) {
204    status_t err;
205
206    // Set the region of the layer stack we're interested in, which in our
207    // case is "all of it".  If the app is rotated (so that the width of the
208    // app is based on the height of the display), reverse width/height.
209    bool deviceRotated = isDeviceRotated(mainDpyInfo.orientation);
210    uint32_t sourceWidth, sourceHeight;
211    if (!deviceRotated) {
212        sourceWidth = mainDpyInfo.w;
213        sourceHeight = mainDpyInfo.h;
214    } else {
215        ALOGV("using rotated width/height");
216        sourceHeight = mainDpyInfo.w;
217        sourceWidth = mainDpyInfo.h;
218    }
219    Rect layerStackRect(sourceWidth, sourceHeight);
220
221    // We need to preserve the aspect ratio of the display.
222    float displayAspect = (float) sourceHeight / (float) sourceWidth;
223
224
225    // Set the way we map the output onto the display surface (which will
226    // be e.g. 1280x720 for a 720p video).  The rect is interpreted
227    // post-rotation, so if the display is rotated 90 degrees we need to
228    // "pre-rotate" it by flipping width/height, so that the orientation
229    // adjustment changes it back.
230    //
231    // We might want to encode a portrait display as landscape to use more
232    // of the screen real estate.  (If players respect a 90-degree rotation
233    // hint, we can essentially get a 720x1280 video instead of 1280x720.)
234    // In that case, we swap the configured video width/height and then
235    // supply a rotation value to the display projection.
236    uint32_t videoWidth, videoHeight;
237    uint32_t outWidth, outHeight;
238    if (!gRotate) {
239        videoWidth = gVideoWidth;
240        videoHeight = gVideoHeight;
241    } else {
242        videoWidth = gVideoHeight;
243        videoHeight = gVideoWidth;
244    }
245    if (videoHeight > (uint32_t)(videoWidth * displayAspect)) {
246        // limited by narrow width; reduce height
247        outWidth = videoWidth;
248        outHeight = (uint32_t)(videoWidth * displayAspect);
249    } else {
250        // limited by short height; restrict width
251        outHeight = videoHeight;
252        outWidth = (uint32_t)(videoHeight / displayAspect);
253    }
254    uint32_t offX, offY;
255    offX = (videoWidth - outWidth) / 2;
256    offY = (videoHeight - outHeight) / 2;
257    Rect displayRect(offX, offY, offX + outWidth, offY + outHeight);
258
259    if (gVerbose) {
260        if (gRotate) {
261            printf("Rotated content area is %ux%u at offset x=%d y=%d\n",
262                    outHeight, outWidth, offY, offX);
263        } else {
264            printf("Content area is %ux%u at offset x=%d y=%d\n",
265                    outWidth, outHeight, offX, offY);
266        }
267    }
268
269    SurfaceComposerClient::setDisplayProjection(dpy,
270            gRotate ? DISPLAY_ORIENTATION_90 : DISPLAY_ORIENTATION_0,
271            layerStackRect, displayRect);
272    return NO_ERROR;
273}
274
275/*
276 * Configures the virtual display.  When this completes, virtual display
277 * frames will start arriving from the buffer producer.
278 */
279static status_t prepareVirtualDisplay(const DisplayInfo& mainDpyInfo,
280        const sp<IGraphicBufferProducer>& bufferProducer,
281        sp<IBinder>* pDisplayHandle) {
282    sp<IBinder> dpy = SurfaceComposerClient::createDisplay(
283            String8("ScreenRecorder"), false /*secure*/);
284
285    SurfaceComposerClient::openGlobalTransaction();
286    SurfaceComposerClient::setDisplaySurface(dpy, bufferProducer);
287    setDisplayProjection(dpy, mainDpyInfo);
288    SurfaceComposerClient::setDisplayLayerStack(dpy, 0);    // default stack
289    SurfaceComposerClient::closeGlobalTransaction();
290
291    *pDisplayHandle = dpy;
292
293    return NO_ERROR;
294}
295
296/*
297 * Runs the MediaCodec encoder, sending the output to the MediaMuxer.  The
298 * input frames are coming from the virtual display as fast as SurfaceFlinger
299 * wants to send them.
300 *
301 * The muxer must *not* have been started before calling.
302 */
303static status_t runEncoder(const sp<MediaCodec>& encoder,
304        const sp<MediaMuxer>& muxer, const sp<IBinder>& mainDpy,
305        const sp<IBinder>& virtualDpy, uint8_t orientation) {
306    static int kTimeout = 250000;   // be responsive on signal
307    status_t err;
308    ssize_t trackIdx = -1;
309    uint32_t debugNumFrames = 0;
310    int64_t startWhenNsec = systemTime(CLOCK_MONOTONIC);
311    int64_t endWhenNsec = startWhenNsec + seconds_to_nanoseconds(gTimeLimitSec);
312    DisplayInfo mainDpyInfo;
313
314    Vector<sp<ABuffer> > buffers;
315    err = encoder->getOutputBuffers(&buffers);
316    if (err != NO_ERROR) {
317        fprintf(stderr, "Unable to get output buffers (err=%d)\n", err);
318        return err;
319    }
320
321    // This is set by the signal handler.
322    gStopRequested = false;
323
324    // Run until we're signaled.
325    while (!gStopRequested) {
326        size_t bufIndex, offset, size;
327        int64_t ptsUsec;
328        uint32_t flags;
329
330        if (systemTime(CLOCK_MONOTONIC) > endWhenNsec) {
331            if (gVerbose) {
332                printf("Time limit reached\n");
333            }
334            break;
335        }
336
337        ALOGV("Calling dequeueOutputBuffer");
338        err = encoder->dequeueOutputBuffer(&bufIndex, &offset, &size, &ptsUsec,
339                &flags, kTimeout);
340        ALOGV("dequeueOutputBuffer returned %d", err);
341        switch (err) {
342        case NO_ERROR:
343            // got a buffer
344            if ((flags & MediaCodec::BUFFER_FLAG_CODECCONFIG) != 0) {
345                // ignore this -- we passed the CSD into MediaMuxer when
346                // we got the format change notification
347                ALOGV("Got codec config buffer (%u bytes); ignoring", size);
348                size = 0;
349            }
350            if (size != 0) {
351                ALOGV("Got data in buffer %d, size=%d, pts=%lld",
352                        bufIndex, size, ptsUsec);
353                assert(trackIdx != -1);
354
355                { // scope
356                    ATRACE_NAME("orientation");
357                    // Check orientation, update if it has changed.
358                    //
359                    // Polling for changes is inefficient and wrong, but the
360                    // useful stuff is hard to get at without a Dalvik VM.
361                    err = SurfaceComposerClient::getDisplayInfo(mainDpy,
362                            &mainDpyInfo);
363                    if (err != NO_ERROR) {
364                        ALOGW("getDisplayInfo(main) failed: %d", err);
365                    } else if (orientation != mainDpyInfo.orientation) {
366                        ALOGD("orientation changed, now %d", mainDpyInfo.orientation);
367                        SurfaceComposerClient::openGlobalTransaction();
368                        setDisplayProjection(virtualDpy, mainDpyInfo);
369                        SurfaceComposerClient::closeGlobalTransaction();
370                        orientation = mainDpyInfo.orientation;
371                    }
372                }
373
374                // If the virtual display isn't providing us with timestamps,
375                // use the current time.  This isn't great -- we could get
376                // decoded data in clusters -- but we're not expecting
377                // to hit this anyway.
378                if (ptsUsec == 0) {
379                    ptsUsec = systemTime(SYSTEM_TIME_MONOTONIC) / 1000;
380                }
381
382                // The MediaMuxer docs are unclear, but it appears that we
383                // need to pass either the full set of BufferInfo flags, or
384                // (flags & BUFFER_FLAG_SYNCFRAME).
385                //
386                // If this blocks for too long we could drop frames.  We may
387                // want to queue these up and do them on a different thread.
388                { // scope
389                    ATRACE_NAME("write sample");
390                    err = muxer->writeSampleData(buffers[bufIndex], trackIdx,
391                            ptsUsec, flags);
392                    if (err != NO_ERROR) {
393                        fprintf(stderr,
394                            "Failed writing data to muxer (err=%d)\n", err);
395                        return err;
396                    }
397                }
398                debugNumFrames++;
399            }
400            err = encoder->releaseOutputBuffer(bufIndex);
401            if (err != NO_ERROR) {
402                fprintf(stderr, "Unable to release output buffer (err=%d)\n",
403                        err);
404                return err;
405            }
406            if ((flags & MediaCodec::BUFFER_FLAG_EOS) != 0) {
407                // Not expecting EOS from SurfaceFlinger.  Go with it.
408                ALOGI("Received end-of-stream");
409                gStopRequested = true;
410            }
411            break;
412        case -EAGAIN:                       // INFO_TRY_AGAIN_LATER
413            ALOGV("Got -EAGAIN, looping");
414            break;
415        case INFO_FORMAT_CHANGED:           // INFO_OUTPUT_FORMAT_CHANGED
416            {
417                // Format includes CSD, which we must provide to muxer.
418                ALOGV("Encoder format changed");
419                sp<AMessage> newFormat;
420                encoder->getOutputFormat(&newFormat);
421                trackIdx = muxer->addTrack(newFormat);
422                ALOGV("Starting muxer");
423                err = muxer->start();
424                if (err != NO_ERROR) {
425                    fprintf(stderr, "Unable to start muxer (err=%d)\n", err);
426                    return err;
427                }
428            }
429            break;
430        case INFO_OUTPUT_BUFFERS_CHANGED:   // INFO_OUTPUT_BUFFERS_CHANGED
431            // Not expected for an encoder; handle it anyway.
432            ALOGV("Encoder buffers changed");
433            err = encoder->getOutputBuffers(&buffers);
434            if (err != NO_ERROR) {
435                fprintf(stderr,
436                        "Unable to get new output buffers (err=%d)\n", err);
437                return err;
438            }
439            break;
440        case INVALID_OPERATION:
441            ALOGW("dequeueOutputBuffer returned INVALID_OPERATION");
442            return err;
443        default:
444            fprintf(stderr,
445                    "Got weird result %d from dequeueOutputBuffer\n", err);
446            return err;
447        }
448    }
449
450    ALOGV("Encoder stopping (req=%d)", gStopRequested);
451    if (gVerbose) {
452        printf("Encoder stopping; recorded %u frames in %lld seconds\n",
453                debugNumFrames, nanoseconds_to_seconds(
454                        systemTime(CLOCK_MONOTONIC) - startWhenNsec));
455    }
456    return NO_ERROR;
457}
458
459/*
460 * Main "do work" method.
461 *
462 * Configures codec, muxer, and virtual display, then starts moving bits
463 * around.
464 */
465static status_t recordScreen(const char* fileName) {
466    status_t err;
467
468    // Configure signal handler.
469    err = configureSignals();
470    if (err != NO_ERROR) return err;
471
472    // Start Binder thread pool.  MediaCodec needs to be able to receive
473    // messages from mediaserver.
474    sp<ProcessState> self = ProcessState::self();
475    self->startThreadPool();
476
477    // Get main display parameters.
478    sp<IBinder> mainDpy = SurfaceComposerClient::getBuiltInDisplay(
479            ISurfaceComposer::eDisplayIdMain);
480    DisplayInfo mainDpyInfo;
481    err = SurfaceComposerClient::getDisplayInfo(mainDpy, &mainDpyInfo);
482    if (err != NO_ERROR) {
483        fprintf(stderr, "ERROR: unable to get display characteristics\n");
484        return err;
485    }
486    if (gVerbose) {
487        printf("Main display is %dx%d @%.2ffps (orientation=%u)\n",
488                mainDpyInfo.w, mainDpyInfo.h, mainDpyInfo.fps,
489                mainDpyInfo.orientation);
490    }
491
492    bool rotated = isDeviceRotated(mainDpyInfo.orientation);
493    if (gVideoWidth == 0) {
494        gVideoWidth = rotated ? mainDpyInfo.h : mainDpyInfo.w;
495    }
496    if (gVideoHeight == 0) {
497        gVideoHeight = rotated ? mainDpyInfo.w : mainDpyInfo.h;
498    }
499
500    // Configure and start the encoder.
501    sp<MediaCodec> encoder;
502    sp<IGraphicBufferProducer> encoderInputSurface;
503    err = prepareEncoder(mainDpyInfo.fps, &encoder, &encoderInputSurface);
504
505    if (err != NO_ERROR && !gSizeSpecified) {
506        // fallback is defined for landscape; swap if we're in portrait
507        bool needSwap = gVideoWidth < gVideoHeight;
508        uint32_t newWidth = needSwap ? kFallbackHeight : kFallbackWidth;
509        uint32_t newHeight = needSwap ? kFallbackWidth : kFallbackHeight;
510        if (gVideoWidth != newWidth && gVideoHeight != newHeight) {
511            ALOGV("Retrying with 720p");
512            fprintf(stderr, "WARNING: failed at %dx%d, retrying at %dx%d\n",
513                    gVideoWidth, gVideoHeight, newWidth, newHeight);
514            gVideoWidth = newWidth;
515            gVideoHeight = newHeight;
516            err = prepareEncoder(mainDpyInfo.fps, &encoder,
517                    &encoderInputSurface);
518        }
519    }
520    if (err != NO_ERROR) return err;
521
522    // From here on, we must explicitly release() the encoder before it goes
523    // out of scope, or we will get an assertion failure from stagefright
524    // later on in a different thread.
525
526
527    // Draw the "info" page by rendering a frame with GLES and sending
528    // it directly to the encoder.
529    // TODO: consider displaying this as a regular layer to avoid b/11697754
530    if (gWantInfoScreen) {
531        Overlay::drawInfoPage(encoderInputSurface);
532    }
533
534    // Configure optional overlay.
535    sp<IGraphicBufferProducer> bufferProducer;
536    sp<Overlay> overlay;
537    if (gWantFrameTime) {
538        // Send virtual display frames to an external texture.
539        overlay = new Overlay();
540        err = overlay->start(encoderInputSurface, &bufferProducer);
541        if (err != NO_ERROR) {
542            encoder->release();
543            return err;
544        }
545        if (gVerbose) {
546            printf("Bugreport overlay created\n");
547        }
548    } else {
549        // Use the encoder's input surface as the virtual display surface.
550        bufferProducer = encoderInputSurface;
551    }
552
553    // Configure virtual display.
554    sp<IBinder> dpy;
555    err = prepareVirtualDisplay(mainDpyInfo, bufferProducer, &dpy);
556    if (err != NO_ERROR) {
557        encoder->release();
558        return err;
559    }
560
561    // Configure muxer.  We have to wait for the CSD blob from the encoder
562    // before we can start it.
563    sp<MediaMuxer> muxer = new MediaMuxer(fileName,
564            MediaMuxer::OUTPUT_FORMAT_MPEG_4);
565    if (gRotate) {
566        muxer->setOrientationHint(90);  // TODO: does this do anything?
567    }
568
569    // Main encoder loop.
570    err = runEncoder(encoder, muxer, mainDpy, dpy, mainDpyInfo.orientation);
571    if (err != NO_ERROR) {
572        fprintf(stderr, "Encoder failed (err=%d)\n", err);
573        // fall through to cleanup
574    }
575
576    if (gVerbose) {
577        printf("Stopping encoder and muxer\n");
578    }
579
580    // Shut everything down, starting with the producer side.
581    encoderInputSurface = NULL;
582    SurfaceComposerClient::destroyDisplay(dpy);
583    if (overlay != NULL) {
584        overlay->stop();
585    }
586    encoder->stop();
587    // If we don't stop muxer explicitly, i.e. let the destructor run,
588    // it may hang (b/11050628).
589    muxer->stop();
590    encoder->release();
591
592    return err;
593}
594
595/*
596 * Sends a broadcast to the media scanner to tell it about the new video.
597 *
598 * This is optional, but nice to have.
599 */
600static status_t notifyMediaScanner(const char* fileName) {
601    // need to do allocations before the fork()
602    String8 fileUrl("file://");
603    fileUrl.append(fileName);
604
605    const char* kCommand = "/system/bin/am";
606    const char* const argv[] = {
607            kCommand,
608            "broadcast",
609            "-a",
610            "android.intent.action.MEDIA_SCANNER_SCAN_FILE",
611            "-d",
612            fileUrl.string(),
613            NULL
614    };
615    if (gVerbose) {
616        printf("Executing:");
617        for (int i = 0; argv[i] != NULL; i++) {
618            printf(" %s", argv[i]);
619        }
620        putchar('\n');
621    }
622
623    pid_t pid = fork();
624    if (pid < 0) {
625        int err = errno;
626        ALOGW("fork() failed: %s", strerror(err));
627        return -err;
628    } else if (pid > 0) {
629        // parent; wait for the child, mostly to make the verbose-mode output
630        // look right, but also to check for and log failures
631        int status;
632        pid_t actualPid = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0));
633        if (actualPid != pid) {
634            ALOGW("waitpid(%d) returned %d (errno=%d)", pid, actualPid, errno);
635        } else if (status != 0) {
636            ALOGW("'am broadcast' exited with status=%d", status);
637        } else {
638            ALOGV("'am broadcast' exited successfully");
639        }
640    } else {
641        if (!gVerbose) {
642            // non-verbose, suppress 'am' output
643            ALOGV("closing stdout/stderr in child");
644            int fd = open("/dev/null", O_WRONLY);
645            if (fd >= 0) {
646                dup2(fd, STDOUT_FILENO);
647                dup2(fd, STDERR_FILENO);
648                close(fd);
649            }
650        }
651        execv(kCommand, const_cast<char* const*>(argv));
652        ALOGE("execv(%s) failed: %s\n", kCommand, strerror(errno));
653        exit(1);
654    }
655    return NO_ERROR;
656}
657
658/*
659 * Parses a string of the form "1280x720".
660 *
661 * Returns true on success.
662 */
663static bool parseWidthHeight(const char* widthHeight, uint32_t* pWidth,
664        uint32_t* pHeight) {
665    long width, height;
666    char* end;
667
668    // Must specify base 10, or "0x0" gets parsed differently.
669    width = strtol(widthHeight, &end, 10);
670    if (end == widthHeight || *end != 'x' || *(end+1) == '\0') {
671        // invalid chars in width, or missing 'x', or missing height
672        return false;
673    }
674    height = strtol(end + 1, &end, 10);
675    if (*end != '\0') {
676        // invalid chars in height
677        return false;
678    }
679
680    *pWidth = width;
681    *pHeight = height;
682    return true;
683}
684
685/*
686 * Accepts a string with a bare number ("4000000") or with a single-character
687 * unit ("4m").
688 *
689 * Returns an error if parsing fails.
690 */
691static status_t parseValueWithUnit(const char* str, uint32_t* pValue) {
692    long value;
693    char* endptr;
694
695    value = strtol(str, &endptr, 10);
696    if (*endptr == '\0') {
697        // bare number
698        *pValue = value;
699        return NO_ERROR;
700    } else if (toupper(*endptr) == 'M' && *(endptr+1) == '\0') {
701        *pValue = value * 1000000;  // check for overflow?
702        return NO_ERROR;
703    } else {
704        fprintf(stderr, "Unrecognized value: %s\n", str);
705        return UNKNOWN_ERROR;
706    }
707}
708
709/*
710 * Dumps usage on stderr.
711 */
712static void usage() {
713    fprintf(stderr,
714        "Usage: screenrecord [options] <filename>\n"
715        "\n"
716        "Android screenrecord v%d.%d.  Records the device's display to a .mp4 file.\n"
717        "\n"
718        "Options:\n"
719        "--size WIDTHxHEIGHT\n"
720        "    Set the video size, e.g. \"1280x720\".  Default is the device's main\n"
721        "    display resolution (if supported), 1280x720 if not.  For best results,\n"
722        "    use a size supported by the AVC encoder.\n"
723        "--bit-rate RATE\n"
724        "    Set the video bit rate, in megabits per second.  Value may be specified\n"
725        "    in bits or megabits, e.g. '4000000' is equivalent to '4M'.  Default %dMbps.\n"
726        "--bugreport\n"
727        "    Add additional information, such as a timestamp overlay, that is helpful\n"
728        "    in videos captured to illustrate bugs.\n"
729        "--time-limit TIME\n"
730        "    Set the maximum recording time, in seconds.  Default / maximum is %d.\n"
731        "--verbose\n"
732        "    Display interesting information on stdout.\n"
733        "--help\n"
734        "    Show this message.\n"
735        "\n"
736        "Recording continues until Ctrl-C is hit or the time limit is reached.\n"
737        "\n",
738        kVersionMajor, kVersionMinor, gBitRate / 1000000, gTimeLimitSec
739        );
740}
741
742/*
743 * Parses args and kicks things off.
744 */
745int main(int argc, char* const argv[]) {
746    static const struct option longOptions[] = {
747        { "help",               no_argument,        NULL, 'h' },
748        { "verbose",            no_argument,        NULL, 'v' },
749        { "size",               required_argument,  NULL, 's' },
750        { "bit-rate",           required_argument,  NULL, 'b' },
751        { "time-limit",         required_argument,  NULL, 't' },
752        { "show-device-info",   no_argument,        NULL, 'i' },
753        { "show-frame-time",    no_argument,        NULL, 'f' },
754        { "bugreport",          no_argument,        NULL, 'u' },
755        { "rotate",             no_argument,        NULL, 'r' },
756        { NULL,                 0,                  NULL, 0 }
757    };
758
759    while (true) {
760        int optionIndex = 0;
761        int ic = getopt_long(argc, argv, "", longOptions, &optionIndex);
762        if (ic == -1) {
763            break;
764        }
765
766        switch (ic) {
767        case 'h':
768            usage();
769            return 0;
770        case 'v':
771            gVerbose = true;
772            break;
773        case 's':
774            if (!parseWidthHeight(optarg, &gVideoWidth, &gVideoHeight)) {
775                fprintf(stderr, "Invalid size '%s', must be width x height\n",
776                        optarg);
777                return 2;
778            }
779            if (gVideoWidth == 0 || gVideoHeight == 0) {
780                fprintf(stderr,
781                    "Invalid size %ux%u, width and height may not be zero\n",
782                    gVideoWidth, gVideoHeight);
783                return 2;
784            }
785            gSizeSpecified = true;
786            break;
787        case 'b':
788            if (parseValueWithUnit(optarg, &gBitRate) != NO_ERROR) {
789                return 2;
790            }
791            if (gBitRate < kMinBitRate || gBitRate > kMaxBitRate) {
792                fprintf(stderr,
793                        "Bit rate %dbps outside acceptable range [%d,%d]\n",
794                        gBitRate, kMinBitRate, kMaxBitRate);
795                return 2;
796            }
797            break;
798        case 't':
799            gTimeLimitSec = atoi(optarg);
800            if (gTimeLimitSec == 0 || gTimeLimitSec > kMaxTimeLimitSec) {
801                fprintf(stderr,
802                        "Time limit %ds outside acceptable range [1,%d]\n",
803                        gTimeLimitSec, kMaxTimeLimitSec);
804                return 2;
805            }
806            break;
807        case 'i':
808            gWantInfoScreen = true;
809            break;
810        case 'f':
811            gWantFrameTime = true;
812            break;
813        case 'u':
814            gWantInfoScreen = true;
815            gWantFrameTime = true;
816            break;
817        case 'r':
818            // experimental feature
819            gRotate = true;
820            break;
821        default:
822            if (ic != '?') {
823                fprintf(stderr, "getopt_long returned unexpected value 0x%x\n", ic);
824            }
825            return 2;
826        }
827    }
828
829    if (optind != argc - 1) {
830        fprintf(stderr, "Must specify output file (see --help).\n");
831        return 2;
832    }
833
834    // MediaMuxer tries to create the file in the constructor, but we don't
835    // learn about the failure until muxer.start(), which returns a generic
836    // error code without logging anything.  We attempt to create the file
837    // now for better diagnostics.
838    const char* fileName = argv[optind];
839    int fd = open(fileName, O_CREAT | O_RDWR, 0644);
840    if (fd < 0) {
841        fprintf(stderr, "Unable to open '%s': %s\n", fileName, strerror(errno));
842        return 1;
843    }
844    close(fd);
845
846    status_t err = recordScreen(fileName);
847    if (err == NO_ERROR) {
848        // Try to notify the media scanner.  Not fatal if this fails.
849        notifyMediaScanner(fileName);
850    }
851    ALOGD(err == NO_ERROR ? "success" : "failed");
852    return (int) err;
853}
854