1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <time.h>
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <unistd.h>
21 
22 #include "mosaic/Mosaic.h"
23 #include "mosaic/ImageUtils.h"
24 
25 #define MAX_FRAMES 200
26 #define KERNEL_ITERATIONS 10
27 
28 const int blendingType = Blend::BLEND_TYPE_HORZ;
29 const int stripType = Blend::STRIP_TYPE_WIDE;
30 
31 ImageType yvuFrames[MAX_FRAMES];
32 
loadImages(const char * basename,int & width,int & height)33 int loadImages(const char* basename, int &width, int &height)
34 {
35     char filename[512];
36     struct stat filestat;
37     int i;
38 
39     for (i = 0; i < MAX_FRAMES; i++) {
40         sprintf(filename, "%s_%03d.ppm", basename, i + 1);
41         if (stat(filename, &filestat) != 0) break;
42         ImageType rgbFrame = ImageUtils::readBinaryPPM(filename, width, height);
43         yvuFrames[i] = ImageUtils::allocateImage(width, height,
44                                 ImageUtils::IMAGE_TYPE_NUM_CHANNELS);
45         ImageUtils::rgb2yvu(yvuFrames[i], rgbFrame, width, height);
46         ImageUtils::freeImage(rgbFrame);
47     }
48     return i;
49 }
50 
main(int argc,char ** argv)51 int main(int argc, char **argv)
52 {
53     struct timespec t1, t2, t3;
54 
55     int width, height;
56     float totalElapsedTime = 0;
57 
58     const char *basename;
59     const char *filename;
60 
61     if (argc != 3) {
62         printf("Usage: %s input_dir output_filename\n", argv[0]);
63         return 0;
64     } else {
65         basename = argv[1];
66         filename = argv[2];
67     }
68 
69     // Load the images outside the computational kernel
70     int totalFrames = loadImages(basename, width, height);
71 
72     if (totalFrames == 0) {
73         printf("Image files not found. Make sure %s exists.\n",
74                basename);
75         return 1;
76     }
77 
78     printf("%d frames loaded\n", totalFrames);
79 
80 
81     // Interesting stuff is here
82     for (int iteration = 0; iteration < KERNEL_ITERATIONS; iteration++)  {
83         Mosaic mosaic;
84 
85         mosaic.initialize(blendingType, stripType, width, height, -1, false, 0);
86 
87         clock_gettime(CLOCK_MONOTONIC, &t1);
88         for (int i = 0; i < totalFrames; i++) {
89             mosaic.addFrame(yvuFrames[i]);
90         }
91         clock_gettime(CLOCK_MONOTONIC, &t2);
92 
93         float progress = 0.0;
94         bool cancelComputation = false;
95 
96         mosaic.createMosaic(progress, cancelComputation);
97 
98         int mosaicWidth, mosaicHeight;
99         ImageType resultYVU = mosaic.getMosaic(mosaicWidth, mosaicHeight);
100 
101         ImageType imageRGB = ImageUtils::allocateImage(
102             mosaicWidth, mosaicHeight, ImageUtils::IMAGE_TYPE_NUM_CHANNELS);
103 
104         clock_gettime(CLOCK_MONOTONIC, &t3);
105 
106         float elapsedTime =
107             (t3.tv_sec - t1.tv_sec) + (t3.tv_nsec - t1.tv_nsec)/1e9;
108         float addImageTime =
109             (t2.tv_sec - t1.tv_sec) + (t2.tv_nsec - t1.tv_nsec)/1e9;
110         float stitchImageTime =
111             (t3.tv_sec - t2.tv_sec) + (t3.tv_nsec - t2.tv_nsec)/1e9;
112 
113         totalElapsedTime += elapsedTime;
114 
115         printf("Iteration %d: %dx%d moasic created: "
116                "%.2f seconds (%.2f + %.2f)\n",
117                iteration, mosaicWidth, mosaicHeight,
118                elapsedTime, addImageTime, stitchImageTime);
119 
120         // Write the output only once for correctness check
121         if (iteration == 0) {
122             ImageUtils::yvu2rgb(imageRGB, resultYVU, mosaicWidth,
123                                 mosaicHeight);
124             ImageUtils::writeBinaryPPM(imageRGB, filename, mosaicWidth,
125                                        mosaicHeight);
126         }
127     }
128     printf("Total elapsed time: %.2f seconds\n", totalElapsedTime);
129 
130     return 0;
131 }
132