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