1/*
2 * Copyright 2013 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#include <assert.h>
18#include <ctype.h>
19#include <fcntl.h>
20#include <inttypes.h>
21#include <getopt.h>
22#include <signal.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <string.h>
26#include <sys/stat.h>
27#include <sys/types.h>
28#include <sys/wait.h>
29
30#include <termios.h>
31#include <unistd.h>
32
33#define LOG_TAG "ScreenRecord"
34#define ATRACE_TAG ATRACE_TAG_GRAPHICS
35//#define LOG_NDEBUG 0
36#include <utils/Log.h>
37
38#include <binder/IPCThreadState.h>
39#include <utils/Errors.h>
40#include <utils/Timers.h>
41#include <utils/Trace.h>
42
43#include <gui/Surface.h>
44#include <gui/SurfaceComposerClient.h>
45#include <gui/ISurfaceComposer.h>
46#include <ui/DisplayInfo.h>
47#include <media/openmax/OMX_IVCommon.h>
48#include <media/stagefright/foundation/ABuffer.h>
49#include <media/stagefright/foundation/AMessage.h>
50#include <media/stagefright/MediaCodec.h>
51#include <media/stagefright/MediaErrors.h>
52#include <media/stagefright/MediaMuxer.h>
53#include <media/ICrypto.h>
54
55#include "screenrecord.h"
56#include "Overlay.h"
57#include "FrameOutput.h"
58
59using namespace android;
60
61static const uint32_t kMinBitRate = 100000;         // 0.1Mbps
62static const uint32_t kMaxBitRate = 200 * 1000000;  // 200Mbps
63static const uint32_t kMaxTimeLimitSec = 180;       // 3 minutes
64static const uint32_t kFallbackWidth = 1280;        // 720p
65static const uint32_t kFallbackHeight = 720;
66static const char* kMimeTypeAvc = "video/avc";
67
68// Command-line parameters.
69static bool gVerbose = false;           // chatty on stdout
70static bool gRotate = false;            // rotate 90 degrees
71static enum {
72    FORMAT_MP4, FORMAT_H264, FORMAT_FRAMES, FORMAT_RAW_FRAMES
73} gOutputFormat = FORMAT_MP4;           // data format for output
74static bool gSizeSpecified = false;     // was size explicitly requested?
75static bool gWantInfoScreen = false;    // do we want initial info screen?
76static bool gWantFrameTime = false;     // do we want times on each frame?
77static uint32_t gVideoWidth = 0;        // default width+height
78static uint32_t gVideoHeight = 0;
79static uint32_t gBitRate = 4000000;     // 4Mbps
80static uint32_t gTimeLimitSec = kMaxTimeLimitSec;
81
82// Set by signal handler to stop recording.
83static volatile bool gStopRequested;
84
85// Previous signal handler state, restored after first hit.
86static struct sigaction gOrigSigactionINT;
87static struct sigaction gOrigSigactionHUP;
88
89
90/*
91 * Catch keyboard interrupt signals.  On receipt, the "stop requested"
92 * flag is raised, and the original handler is restored (so that, if
93 * we get stuck finishing, a second Ctrl-C will kill the process).
94 */
95static void signalCatcher(int signum)
96{
97    gStopRequested = true;
98    switch (signum) {
99    case SIGINT:
100    case SIGHUP:
101        sigaction(SIGINT, &gOrigSigactionINT, NULL);
102        sigaction(SIGHUP, &gOrigSigactionHUP, NULL);
103        break;
104    default:
105        abort();
106        break;
107    }
108}
109
110/*
111 * Configures signal handlers.  The previous handlers are saved.
112 *
113 * If the command is run from an interactive adb shell, we get SIGINT
114 * when Ctrl-C is hit.  If we're run from the host, the local adb process
115 * gets the signal, and we get a SIGHUP when the terminal disconnects.
116 */
117static status_t configureSignals() {
118    struct sigaction act;
119    memset(&act, 0, sizeof(act));
120    act.sa_handler = signalCatcher;
121    if (sigaction(SIGINT, &act, &gOrigSigactionINT) != 0) {
122        status_t err = -errno;
123        fprintf(stderr, "Unable to configure SIGINT handler: %s\n",
124                strerror(errno));
125        return err;
126    }
127    if (sigaction(SIGHUP, &act, &gOrigSigactionHUP) != 0) {
128        status_t err = -errno;
129        fprintf(stderr, "Unable to configure SIGHUP handler: %s\n",
130                strerror(errno));
131        return err;
132    }
133    return NO_ERROR;
134}
135
136/*
137 * Returns "true" if the device is rotated 90 degrees.
138 */
139static bool isDeviceRotated(int orientation) {
140    return orientation != DISPLAY_ORIENTATION_0 &&
141            orientation != DISPLAY_ORIENTATION_180;
142}
143
144/*
145 * Configures and starts the MediaCodec encoder.  Obtains an input surface
146 * from the codec.
147 */
148static status_t prepareEncoder(float displayFps, sp<MediaCodec>* pCodec,
149        sp<IGraphicBufferProducer>* pBufferProducer) {
150    status_t err;
151
152    if (gVerbose) {
153        printf("Configuring recorder for %dx%d %s at %.2fMbps\n",
154                gVideoWidth, gVideoHeight, kMimeTypeAvc, gBitRate / 1000000.0);
155    }
156
157    sp<AMessage> format = new AMessage;
158    format->setInt32("width", gVideoWidth);
159    format->setInt32("height", gVideoHeight);
160    format->setString("mime", kMimeTypeAvc);
161    format->setInt32("color-format", OMX_COLOR_FormatAndroidOpaque);
162    format->setInt32("bitrate", gBitRate);
163    format->setFloat("frame-rate", displayFps);
164    format->setInt32("i-frame-interval", 10);
165
166    sp<ALooper> looper = new ALooper;
167    looper->setName("screenrecord_looper");
168    looper->start();
169    ALOGV("Creating codec");
170    sp<MediaCodec> codec = MediaCodec::CreateByType(looper, kMimeTypeAvc, true);
171    if (codec == NULL) {
172        fprintf(stderr, "ERROR: unable to create %s codec instance\n",
173                kMimeTypeAvc);
174        return UNKNOWN_ERROR;
175    }
176
177    err = codec->configure(format, NULL, NULL,
178            MediaCodec::CONFIGURE_FLAG_ENCODE);
179    if (err != NO_ERROR) {
180        fprintf(stderr, "ERROR: unable to configure %s codec at %dx%d (err=%d)\n",
181                kMimeTypeAvc, gVideoWidth, gVideoHeight, err);
182        codec->release();
183        return err;
184    }
185
186    ALOGV("Creating encoder input surface");
187    sp<IGraphicBufferProducer> bufferProducer;
188    err = codec->createInputSurface(&bufferProducer);
189    if (err != NO_ERROR) {
190        fprintf(stderr,
191            "ERROR: unable to create encoder input surface (err=%d)\n", err);
192        codec->release();
193        return err;
194    }
195
196    ALOGV("Starting codec");
197    err = codec->start();
198    if (err != NO_ERROR) {
199        fprintf(stderr, "ERROR: unable to start codec (err=%d)\n", err);
200        codec->release();
201        return err;
202    }
203
204    ALOGV("Codec prepared");
205    *pCodec = codec;
206    *pBufferProducer = bufferProducer;
207    return 0;
208}
209
210/*
211 * Sets the display projection, based on the display dimensions, video size,
212 * and device orientation.
213 */
214static status_t setDisplayProjection(const sp<IBinder>& dpy,
215        const DisplayInfo& mainDpyInfo) {
216    status_t err;
217
218    // Set the region of the layer stack we're interested in, which in our
219    // case is "all of it".  If the app is rotated (so that the width of the
220    // app is based on the height of the display), reverse width/height.
221    bool deviceRotated = isDeviceRotated(mainDpyInfo.orientation);
222    uint32_t sourceWidth, sourceHeight;
223    if (!deviceRotated) {
224        sourceWidth = mainDpyInfo.w;
225        sourceHeight = mainDpyInfo.h;
226    } else {
227        ALOGV("using rotated width/height");
228        sourceHeight = mainDpyInfo.w;
229        sourceWidth = mainDpyInfo.h;
230    }
231    Rect layerStackRect(sourceWidth, sourceHeight);
232
233    // We need to preserve the aspect ratio of the display.
234    float displayAspect = (float) sourceHeight / (float) sourceWidth;
235
236
237    // Set the way we map the output onto the display surface (which will
238    // be e.g. 1280x720 for a 720p video).  The rect is interpreted
239    // post-rotation, so if the display is rotated 90 degrees we need to
240    // "pre-rotate" it by flipping width/height, so that the orientation
241    // adjustment changes it back.
242    //
243    // We might want to encode a portrait display as landscape to use more
244    // of the screen real estate.  (If players respect a 90-degree rotation
245    // hint, we can essentially get a 720x1280 video instead of 1280x720.)
246    // In that case, we swap the configured video width/height and then
247    // supply a rotation value to the display projection.
248    uint32_t videoWidth, videoHeight;
249    uint32_t outWidth, outHeight;
250    if (!gRotate) {
251        videoWidth = gVideoWidth;
252        videoHeight = gVideoHeight;
253    } else {
254        videoWidth = gVideoHeight;
255        videoHeight = gVideoWidth;
256    }
257    if (videoHeight > (uint32_t)(videoWidth * displayAspect)) {
258        // limited by narrow width; reduce height
259        outWidth = videoWidth;
260        outHeight = (uint32_t)(videoWidth * displayAspect);
261    } else {
262        // limited by short height; restrict width
263        outHeight = videoHeight;
264        outWidth = (uint32_t)(videoHeight / displayAspect);
265    }
266    uint32_t offX, offY;
267    offX = (videoWidth - outWidth) / 2;
268    offY = (videoHeight - outHeight) / 2;
269    Rect displayRect(offX, offY, offX + outWidth, offY + outHeight);
270
271    if (gVerbose) {
272        if (gRotate) {
273            printf("Rotated content area is %ux%u at offset x=%d y=%d\n",
274                    outHeight, outWidth, offY, offX);
275        } else {
276            printf("Content area is %ux%u at offset x=%d y=%d\n",
277                    outWidth, outHeight, offX, offY);
278        }
279    }
280
281    SurfaceComposerClient::setDisplayProjection(dpy,
282            gRotate ? DISPLAY_ORIENTATION_90 : DISPLAY_ORIENTATION_0,
283            layerStackRect, displayRect);
284    return NO_ERROR;
285}
286
287/*
288 * Configures the virtual display.  When this completes, virtual display
289 * frames will start arriving from the buffer producer.
290 */
291static status_t prepareVirtualDisplay(const DisplayInfo& mainDpyInfo,
292        const sp<IGraphicBufferProducer>& bufferProducer,
293        sp<IBinder>* pDisplayHandle) {
294    sp<IBinder> dpy = SurfaceComposerClient::createDisplay(
295            String8("ScreenRecorder"), false /*secure*/);
296
297    SurfaceComposerClient::openGlobalTransaction();
298    SurfaceComposerClient::setDisplaySurface(dpy, bufferProducer);
299    setDisplayProjection(dpy, mainDpyInfo);
300    SurfaceComposerClient::setDisplayLayerStack(dpy, 0);    // default stack
301    SurfaceComposerClient::closeGlobalTransaction();
302
303    *pDisplayHandle = dpy;
304
305    return NO_ERROR;
306}
307
308/*
309 * Runs the MediaCodec encoder, sending the output to the MediaMuxer.  The
310 * input frames are coming from the virtual display as fast as SurfaceFlinger
311 * wants to send them.
312 *
313 * Exactly one of muxer or rawFp must be non-null.
314 *
315 * The muxer must *not* have been started before calling.
316 */
317static status_t runEncoder(const sp<MediaCodec>& encoder,
318        const sp<MediaMuxer>& muxer, FILE* rawFp, const sp<IBinder>& mainDpy,
319        const sp<IBinder>& virtualDpy, uint8_t orientation) {
320    static int kTimeout = 250000;   // be responsive on signal
321    status_t err;
322    ssize_t trackIdx = -1;
323    uint32_t debugNumFrames = 0;
324    int64_t startWhenNsec = systemTime(CLOCK_MONOTONIC);
325    int64_t endWhenNsec = startWhenNsec + seconds_to_nanoseconds(gTimeLimitSec);
326    DisplayInfo mainDpyInfo;
327
328    assert((rawFp == NULL && muxer != NULL) || (rawFp != NULL && muxer == NULL));
329
330    Vector<sp<ABuffer> > buffers;
331    err = encoder->getOutputBuffers(&buffers);
332    if (err != NO_ERROR) {
333        fprintf(stderr, "Unable to get output buffers (err=%d)\n", err);
334        return err;
335    }
336
337    // This is set by the signal handler.
338    gStopRequested = false;
339
340    // Run until we're signaled.
341    while (!gStopRequested) {
342        size_t bufIndex, offset, size;
343        int64_t ptsUsec;
344        uint32_t flags;
345
346        if (systemTime(CLOCK_MONOTONIC) > endWhenNsec) {
347            if (gVerbose) {
348                printf("Time limit reached\n");
349            }
350            break;
351        }
352
353        ALOGV("Calling dequeueOutputBuffer");
354        err = encoder->dequeueOutputBuffer(&bufIndex, &offset, &size, &ptsUsec,
355                &flags, kTimeout);
356        ALOGV("dequeueOutputBuffer returned %d", err);
357        switch (err) {
358        case NO_ERROR:
359            // got a buffer
360            if ((flags & MediaCodec::BUFFER_FLAG_CODECCONFIG) != 0) {
361                ALOGV("Got codec config buffer (%zu bytes)", size);
362                if (muxer != NULL) {
363                    // ignore this -- we passed the CSD into MediaMuxer when
364                    // we got the format change notification
365                    size = 0;
366                }
367            }
368            if (size != 0) {
369                ALOGV("Got data in buffer %zu, size=%zu, pts=%" PRId64,
370                        bufIndex, size, ptsUsec);
371
372                { // scope
373                    ATRACE_NAME("orientation");
374                    // Check orientation, update if it has changed.
375                    //
376                    // Polling for changes is inefficient and wrong, but the
377                    // useful stuff is hard to get at without a Dalvik VM.
378                    err = SurfaceComposerClient::getDisplayInfo(mainDpy,
379                            &mainDpyInfo);
380                    if (err != NO_ERROR) {
381                        ALOGW("getDisplayInfo(main) failed: %d", err);
382                    } else if (orientation != mainDpyInfo.orientation) {
383                        ALOGD("orientation changed, now %d", mainDpyInfo.orientation);
384                        SurfaceComposerClient::openGlobalTransaction();
385                        setDisplayProjection(virtualDpy, mainDpyInfo);
386                        SurfaceComposerClient::closeGlobalTransaction();
387                        orientation = mainDpyInfo.orientation;
388                    }
389                }
390
391                // If the virtual display isn't providing us with timestamps,
392                // use the current time.  This isn't great -- we could get
393                // decoded data in clusters -- but we're not expecting
394                // to hit this anyway.
395                if (ptsUsec == 0) {
396                    ptsUsec = systemTime(SYSTEM_TIME_MONOTONIC) / 1000;
397                }
398
399                if (muxer == NULL) {
400                    fwrite(buffers[bufIndex]->data(), 1, size, rawFp);
401                    // Flush the data immediately in case we're streaming.
402                    // We don't want to do this if all we've written is
403                    // the SPS/PPS data because mplayer gets confused.
404                    if ((flags & MediaCodec::BUFFER_FLAG_CODECCONFIG) == 0) {
405                        fflush(rawFp);
406                    }
407                } else {
408                    // The MediaMuxer docs are unclear, but it appears that we
409                    // need to pass either the full set of BufferInfo flags, or
410                    // (flags & BUFFER_FLAG_SYNCFRAME).
411                    //
412                    // If this blocks for too long we could drop frames.  We may
413                    // want to queue these up and do them on a different thread.
414                    ATRACE_NAME("write sample");
415                    assert(trackIdx != -1);
416                    err = muxer->writeSampleData(buffers[bufIndex], trackIdx,
417                            ptsUsec, flags);
418                    if (err != NO_ERROR) {
419                        fprintf(stderr,
420                            "Failed writing data to muxer (err=%d)\n", err);
421                        return err;
422                    }
423                }
424                debugNumFrames++;
425            }
426            err = encoder->releaseOutputBuffer(bufIndex);
427            if (err != NO_ERROR) {
428                fprintf(stderr, "Unable to release output buffer (err=%d)\n",
429                        err);
430                return err;
431            }
432            if ((flags & MediaCodec::BUFFER_FLAG_EOS) != 0) {
433                // Not expecting EOS from SurfaceFlinger.  Go with it.
434                ALOGI("Received end-of-stream");
435                gStopRequested = true;
436            }
437            break;
438        case -EAGAIN:                       // INFO_TRY_AGAIN_LATER
439            ALOGV("Got -EAGAIN, looping");
440            break;
441        case INFO_FORMAT_CHANGED:           // INFO_OUTPUT_FORMAT_CHANGED
442            {
443                // Format includes CSD, which we must provide to muxer.
444                ALOGV("Encoder format changed");
445                sp<AMessage> newFormat;
446                encoder->getOutputFormat(&newFormat);
447                if (muxer != NULL) {
448                    trackIdx = muxer->addTrack(newFormat);
449                    ALOGV("Starting muxer");
450                    err = muxer->start();
451                    if (err != NO_ERROR) {
452                        fprintf(stderr, "Unable to start muxer (err=%d)\n", err);
453                        return err;
454                    }
455                }
456            }
457            break;
458        case INFO_OUTPUT_BUFFERS_CHANGED:   // INFO_OUTPUT_BUFFERS_CHANGED
459            // Not expected for an encoder; handle it anyway.
460            ALOGV("Encoder buffers changed");
461            err = encoder->getOutputBuffers(&buffers);
462            if (err != NO_ERROR) {
463                fprintf(stderr,
464                        "Unable to get new output buffers (err=%d)\n", err);
465                return err;
466            }
467            break;
468        case INVALID_OPERATION:
469            ALOGW("dequeueOutputBuffer returned INVALID_OPERATION");
470            return err;
471        default:
472            fprintf(stderr,
473                    "Got weird result %d from dequeueOutputBuffer\n", err);
474            return err;
475        }
476    }
477
478    ALOGV("Encoder stopping (req=%d)", gStopRequested);
479    if (gVerbose) {
480        printf("Encoder stopping; recorded %u frames in %" PRId64 " seconds\n",
481                debugNumFrames, nanoseconds_to_seconds(
482                        systemTime(CLOCK_MONOTONIC) - startWhenNsec));
483    }
484    return NO_ERROR;
485}
486
487/*
488 * Raw H.264 byte stream output requested.  Send the output to stdout
489 * if desired.  If the output is a tty, reconfigure it to avoid the
490 * CRLF line termination that we see with "adb shell" commands.
491 */
492static FILE* prepareRawOutput(const char* fileName) {
493    FILE* rawFp = NULL;
494
495    if (strcmp(fileName, "-") == 0) {
496        if (gVerbose) {
497            fprintf(stderr, "ERROR: verbose output and '-' not compatible");
498            return NULL;
499        }
500        rawFp = stdout;
501    } else {
502        rawFp = fopen(fileName, "w");
503        if (rawFp == NULL) {
504            fprintf(stderr, "fopen raw failed: %s\n", strerror(errno));
505            return NULL;
506        }
507    }
508
509    int fd = fileno(rawFp);
510    if (isatty(fd)) {
511        // best effort -- reconfigure tty for "raw"
512        ALOGD("raw video output to tty (fd=%d)", fd);
513        struct termios term;
514        if (tcgetattr(fd, &term) == 0) {
515            cfmakeraw(&term);
516            if (tcsetattr(fd, TCSANOW, &term) == 0) {
517                ALOGD("tty successfully configured for raw");
518            }
519        }
520    }
521
522    return rawFp;
523}
524
525/*
526 * Main "do work" start point.
527 *
528 * Configures codec, muxer, and virtual display, then starts moving bits
529 * around.
530 */
531static status_t recordScreen(const char* fileName) {
532    status_t err;
533
534    // Configure signal handler.
535    err = configureSignals();
536    if (err != NO_ERROR) return err;
537
538    // Start Binder thread pool.  MediaCodec needs to be able to receive
539    // messages from mediaserver.
540    sp<ProcessState> self = ProcessState::self();
541    self->startThreadPool();
542
543    // Get main display parameters.
544    sp<IBinder> mainDpy = SurfaceComposerClient::getBuiltInDisplay(
545            ISurfaceComposer::eDisplayIdMain);
546    DisplayInfo mainDpyInfo;
547    err = SurfaceComposerClient::getDisplayInfo(mainDpy, &mainDpyInfo);
548    if (err != NO_ERROR) {
549        fprintf(stderr, "ERROR: unable to get display characteristics\n");
550        return err;
551    }
552    if (gVerbose) {
553        printf("Main display is %dx%d @%.2ffps (orientation=%u)\n",
554                mainDpyInfo.w, mainDpyInfo.h, mainDpyInfo.fps,
555                mainDpyInfo.orientation);
556    }
557
558    bool rotated = isDeviceRotated(mainDpyInfo.orientation);
559    if (gVideoWidth == 0) {
560        gVideoWidth = rotated ? mainDpyInfo.h : mainDpyInfo.w;
561    }
562    if (gVideoHeight == 0) {
563        gVideoHeight = rotated ? mainDpyInfo.w : mainDpyInfo.h;
564    }
565
566    // Configure and start the encoder.
567    sp<MediaCodec> encoder;
568    sp<FrameOutput> frameOutput;
569    sp<IGraphicBufferProducer> encoderInputSurface;
570    if (gOutputFormat != FORMAT_FRAMES && gOutputFormat != FORMAT_RAW_FRAMES) {
571        err = prepareEncoder(mainDpyInfo.fps, &encoder, &encoderInputSurface);
572
573        if (err != NO_ERROR && !gSizeSpecified) {
574            // fallback is defined for landscape; swap if we're in portrait
575            bool needSwap = gVideoWidth < gVideoHeight;
576            uint32_t newWidth = needSwap ? kFallbackHeight : kFallbackWidth;
577            uint32_t newHeight = needSwap ? kFallbackWidth : kFallbackHeight;
578            if (gVideoWidth != newWidth && gVideoHeight != newHeight) {
579                ALOGV("Retrying with 720p");
580                fprintf(stderr, "WARNING: failed at %dx%d, retrying at %dx%d\n",
581                        gVideoWidth, gVideoHeight, newWidth, newHeight);
582                gVideoWidth = newWidth;
583                gVideoHeight = newHeight;
584                err = prepareEncoder(mainDpyInfo.fps, &encoder,
585                        &encoderInputSurface);
586            }
587        }
588        if (err != NO_ERROR) return err;
589
590        // From here on, we must explicitly release() the encoder before it goes
591        // out of scope, or we will get an assertion failure from stagefright
592        // later on in a different thread.
593    } else {
594        // We're not using an encoder at all.  The "encoder input surface" we hand to
595        // SurfaceFlinger will just feed directly to us.
596        frameOutput = new FrameOutput();
597        err = frameOutput->createInputSurface(gVideoWidth, gVideoHeight, &encoderInputSurface);
598        if (err != NO_ERROR) {
599            return err;
600        }
601    }
602
603    // Draw the "info" page by rendering a frame with GLES and sending
604    // it directly to the encoder.
605    // TODO: consider displaying this as a regular layer to avoid b/11697754
606    if (gWantInfoScreen) {
607        Overlay::drawInfoPage(encoderInputSurface);
608    }
609
610    // Configure optional overlay.
611    sp<IGraphicBufferProducer> bufferProducer;
612    sp<Overlay> overlay;
613    if (gWantFrameTime) {
614        // Send virtual display frames to an external texture.
615        overlay = new Overlay();
616        err = overlay->start(encoderInputSurface, &bufferProducer);
617        if (err != NO_ERROR) {
618            if (encoder != NULL) encoder->release();
619            return err;
620        }
621        if (gVerbose) {
622            printf("Bugreport overlay created\n");
623        }
624    } else {
625        // Use the encoder's input surface as the virtual display surface.
626        bufferProducer = encoderInputSurface;
627    }
628
629    // Configure virtual display.
630    sp<IBinder> dpy;
631    err = prepareVirtualDisplay(mainDpyInfo, bufferProducer, &dpy);
632    if (err != NO_ERROR) {
633        if (encoder != NULL) encoder->release();
634        return err;
635    }
636
637    sp<MediaMuxer> muxer = NULL;
638    FILE* rawFp = NULL;
639    switch (gOutputFormat) {
640        case FORMAT_MP4: {
641            // Configure muxer.  We have to wait for the CSD blob from the encoder
642            // before we can start it.
643            int fd = open(fileName, O_CREAT | O_LARGEFILE | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR);
644            if (fd < 0) {
645                fprintf(stderr, "ERROR: couldn't open file\n");
646                abort();
647            }
648            muxer = new MediaMuxer(fd, MediaMuxer::OUTPUT_FORMAT_MPEG_4);
649            close(fd);
650            if (gRotate) {
651                muxer->setOrientationHint(90);  // TODO: does this do anything?
652            }
653            break;
654        }
655        case FORMAT_H264:
656        case FORMAT_FRAMES:
657        case FORMAT_RAW_FRAMES: {
658            rawFp = prepareRawOutput(fileName);
659            if (rawFp == NULL) {
660                if (encoder != NULL) encoder->release();
661                return -1;
662            }
663            break;
664        }
665        default:
666            fprintf(stderr, "ERROR: unknown format %d\n", gOutputFormat);
667            abort();
668    }
669
670    if (gOutputFormat == FORMAT_FRAMES || gOutputFormat == FORMAT_RAW_FRAMES) {
671        // TODO: if we want to make this a proper feature, we should output
672        //       an outer header with version info.  Right now we never change
673        //       the frame size or format, so we could conceivably just send
674        //       the current frame header once and then follow it with an
675        //       unbroken stream of data.
676
677        // Make the EGL context current again.  This gets unhooked if we're
678        // using "--bugreport" mode.
679        // TODO: figure out if we can eliminate this
680        frameOutput->prepareToCopy();
681
682        while (!gStopRequested) {
683            // Poll for frames, the same way we do for MediaCodec.  We do
684            // all of the work on the main thread.
685            //
686            // Ideally we'd sleep indefinitely and wake when the
687            // stop was requested, but this will do for now.  (It almost
688            // works because wait() wakes when a signal hits, but we
689            // need to handle the edge cases.)
690            bool rawFrames = gOutputFormat == FORMAT_RAW_FRAMES;
691            err = frameOutput->copyFrame(rawFp, 250000, rawFrames);
692            if (err == ETIMEDOUT) {
693                err = NO_ERROR;
694            } else if (err != NO_ERROR) {
695                ALOGE("Got error %d from copyFrame()", err);
696                break;
697            }
698        }
699    } else {
700        // Main encoder loop.
701        err = runEncoder(encoder, muxer, rawFp, mainDpy, dpy,
702                mainDpyInfo.orientation);
703        if (err != NO_ERROR) {
704            fprintf(stderr, "Encoder failed (err=%d)\n", err);
705            // fall through to cleanup
706        }
707
708        if (gVerbose) {
709            printf("Stopping encoder and muxer\n");
710        }
711    }
712
713    // Shut everything down, starting with the producer side.
714    encoderInputSurface = NULL;
715    SurfaceComposerClient::destroyDisplay(dpy);
716    if (overlay != NULL) overlay->stop();
717    if (encoder != NULL) encoder->stop();
718    if (muxer != NULL) {
719        // If we don't stop muxer explicitly, i.e. let the destructor run,
720        // it may hang (b/11050628).
721        muxer->stop();
722    } else if (rawFp != stdout) {
723        fclose(rawFp);
724    }
725    if (encoder != NULL) encoder->release();
726
727    return err;
728}
729
730/*
731 * Sends a broadcast to the media scanner to tell it about the new video.
732 *
733 * This is optional, but nice to have.
734 */
735static status_t notifyMediaScanner(const char* fileName) {
736    // need to do allocations before the fork()
737    String8 fileUrl("file://");
738    fileUrl.append(fileName);
739
740    const char* kCommand = "/system/bin/am";
741    const char* const argv[] = {
742            kCommand,
743            "broadcast",
744            "-a",
745            "android.intent.action.MEDIA_SCANNER_SCAN_FILE",
746            "-d",
747            fileUrl.string(),
748            NULL
749    };
750    if (gVerbose) {
751        printf("Executing:");
752        for (int i = 0; argv[i] != NULL; i++) {
753            printf(" %s", argv[i]);
754        }
755        putchar('\n');
756    }
757
758    pid_t pid = fork();
759    if (pid < 0) {
760        int err = errno;
761        ALOGW("fork() failed: %s", strerror(err));
762        return -err;
763    } else if (pid > 0) {
764        // parent; wait for the child, mostly to make the verbose-mode output
765        // look right, but also to check for and log failures
766        int status;
767        pid_t actualPid = TEMP_FAILURE_RETRY(waitpid(pid, &status, 0));
768        if (actualPid != pid) {
769            ALOGW("waitpid(%d) returned %d (errno=%d)", pid, actualPid, errno);
770        } else if (status != 0) {
771            ALOGW("'am broadcast' exited with status=%d", status);
772        } else {
773            ALOGV("'am broadcast' exited successfully");
774        }
775    } else {
776        if (!gVerbose) {
777            // non-verbose, suppress 'am' output
778            ALOGV("closing stdout/stderr in child");
779            int fd = open("/dev/null", O_WRONLY);
780            if (fd >= 0) {
781                dup2(fd, STDOUT_FILENO);
782                dup2(fd, STDERR_FILENO);
783                close(fd);
784            }
785        }
786        execv(kCommand, const_cast<char* const*>(argv));
787        ALOGE("execv(%s) failed: %s\n", kCommand, strerror(errno));
788        exit(1);
789    }
790    return NO_ERROR;
791}
792
793/*
794 * Parses a string of the form "1280x720".
795 *
796 * Returns true on success.
797 */
798static bool parseWidthHeight(const char* widthHeight, uint32_t* pWidth,
799        uint32_t* pHeight) {
800    long width, height;
801    char* end;
802
803    // Must specify base 10, or "0x0" gets parsed differently.
804    width = strtol(widthHeight, &end, 10);
805    if (end == widthHeight || *end != 'x' || *(end+1) == '\0') {
806        // invalid chars in width, or missing 'x', or missing height
807        return false;
808    }
809    height = strtol(end + 1, &end, 10);
810    if (*end != '\0') {
811        // invalid chars in height
812        return false;
813    }
814
815    *pWidth = width;
816    *pHeight = height;
817    return true;
818}
819
820/*
821 * Accepts a string with a bare number ("4000000") or with a single-character
822 * unit ("4m").
823 *
824 * Returns an error if parsing fails.
825 */
826static status_t parseValueWithUnit(const char* str, uint32_t* pValue) {
827    long value;
828    char* endptr;
829
830    value = strtol(str, &endptr, 10);
831    if (*endptr == '\0') {
832        // bare number
833        *pValue = value;
834        return NO_ERROR;
835    } else if (toupper(*endptr) == 'M' && *(endptr+1) == '\0') {
836        *pValue = value * 1000000;  // check for overflow?
837        return NO_ERROR;
838    } else {
839        fprintf(stderr, "Unrecognized value: %s\n", str);
840        return UNKNOWN_ERROR;
841    }
842}
843
844/*
845 * Dumps usage on stderr.
846 */
847static void usage() {
848    fprintf(stderr,
849        "Usage: screenrecord [options] <filename>\n"
850        "\n"
851        "Android screenrecord v%d.%d.  Records the device's display to a .mp4 file.\n"
852        "\n"
853        "Options:\n"
854        "--size WIDTHxHEIGHT\n"
855        "    Set the video size, e.g. \"1280x720\".  Default is the device's main\n"
856        "    display resolution (if supported), 1280x720 if not.  For best results,\n"
857        "    use a size supported by the AVC encoder.\n"
858        "--bit-rate RATE\n"
859        "    Set the video bit rate, in bits per second.  Value may be specified as\n"
860        "    bits or megabits, e.g. '4000000' is equivalent to '4M'.  Default %dMbps.\n"
861        "--bugreport\n"
862        "    Add additional information, such as a timestamp overlay, that is helpful\n"
863        "    in videos captured to illustrate bugs.\n"
864        "--time-limit TIME\n"
865        "    Set the maximum recording time, in seconds.  Default / maximum is %d.\n"
866        "--verbose\n"
867        "    Display interesting information on stdout.\n"
868        "--help\n"
869        "    Show this message.\n"
870        "\n"
871        "Recording continues until Ctrl-C is hit or the time limit is reached.\n"
872        "\n",
873        kVersionMajor, kVersionMinor, gBitRate / 1000000, gTimeLimitSec
874        );
875}
876
877/*
878 * Parses args and kicks things off.
879 */
880int main(int argc, char* const argv[]) {
881    static const struct option longOptions[] = {
882        { "help",               no_argument,        NULL, 'h' },
883        { "verbose",            no_argument,        NULL, 'v' },
884        { "size",               required_argument,  NULL, 's' },
885        { "bit-rate",           required_argument,  NULL, 'b' },
886        { "time-limit",         required_argument,  NULL, 't' },
887        { "bugreport",          no_argument,        NULL, 'u' },
888        // "unofficial" options
889        { "show-device-info",   no_argument,        NULL, 'i' },
890        { "show-frame-time",    no_argument,        NULL, 'f' },
891        { "rotate",             no_argument,        NULL, 'r' },
892        { "output-format",      required_argument,  NULL, 'o' },
893        { NULL,                 0,                  NULL, 0 }
894    };
895
896    while (true) {
897        int optionIndex = 0;
898        int ic = getopt_long(argc, argv, "", longOptions, &optionIndex);
899        if (ic == -1) {
900            break;
901        }
902
903        switch (ic) {
904        case 'h':
905            usage();
906            return 0;
907        case 'v':
908            gVerbose = true;
909            break;
910        case 's':
911            if (!parseWidthHeight(optarg, &gVideoWidth, &gVideoHeight)) {
912                fprintf(stderr, "Invalid size '%s', must be width x height\n",
913                        optarg);
914                return 2;
915            }
916            if (gVideoWidth == 0 || gVideoHeight == 0) {
917                fprintf(stderr,
918                    "Invalid size %ux%u, width and height may not be zero\n",
919                    gVideoWidth, gVideoHeight);
920                return 2;
921            }
922            gSizeSpecified = true;
923            break;
924        case 'b':
925            if (parseValueWithUnit(optarg, &gBitRate) != NO_ERROR) {
926                return 2;
927            }
928            if (gBitRate < kMinBitRate || gBitRate > kMaxBitRate) {
929                fprintf(stderr,
930                        "Bit rate %dbps outside acceptable range [%d,%d]\n",
931                        gBitRate, kMinBitRate, kMaxBitRate);
932                return 2;
933            }
934            break;
935        case 't':
936            gTimeLimitSec = atoi(optarg);
937            if (gTimeLimitSec == 0 || gTimeLimitSec > kMaxTimeLimitSec) {
938                fprintf(stderr,
939                        "Time limit %ds outside acceptable range [1,%d]\n",
940                        gTimeLimitSec, kMaxTimeLimitSec);
941                return 2;
942            }
943            break;
944        case 'u':
945            gWantInfoScreen = true;
946            gWantFrameTime = true;
947            break;
948        case 'i':
949            gWantInfoScreen = true;
950            break;
951        case 'f':
952            gWantFrameTime = true;
953            break;
954        case 'r':
955            // experimental feature
956            gRotate = true;
957            break;
958        case 'o':
959            if (strcmp(optarg, "mp4") == 0) {
960                gOutputFormat = FORMAT_MP4;
961            } else if (strcmp(optarg, "h264") == 0) {
962                gOutputFormat = FORMAT_H264;
963            } else if (strcmp(optarg, "frames") == 0) {
964                gOutputFormat = FORMAT_FRAMES;
965            } else if (strcmp(optarg, "raw-frames") == 0) {
966                gOutputFormat = FORMAT_RAW_FRAMES;
967            } else {
968                fprintf(stderr, "Unknown format '%s'\n", optarg);
969                return 2;
970            }
971            break;
972        default:
973            if (ic != '?') {
974                fprintf(stderr, "getopt_long returned unexpected value 0x%x\n", ic);
975            }
976            return 2;
977        }
978    }
979
980    if (optind != argc - 1) {
981        fprintf(stderr, "Must specify output file (see --help).\n");
982        return 2;
983    }
984
985    const char* fileName = argv[optind];
986    if (gOutputFormat == FORMAT_MP4) {
987        // MediaMuxer tries to create the file in the constructor, but we don't
988        // learn about the failure until muxer.start(), which returns a generic
989        // error code without logging anything.  We attempt to create the file
990        // now for better diagnostics.
991        int fd = open(fileName, O_CREAT | O_RDWR, 0644);
992        if (fd < 0) {
993            fprintf(stderr, "Unable to open '%s': %s\n", fileName, strerror(errno));
994            return 1;
995        }
996        close(fd);
997    }
998
999    status_t err = recordScreen(fileName);
1000    if (err == NO_ERROR) {
1001        // Try to notify the media scanner.  Not fatal if this fails.
1002        notifyMediaScanner(fileName);
1003    }
1004    ALOGD(err == NO_ERROR ? "success" : "failed");
1005    return (int) err;
1006}
1007