• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 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 package com.android.camera.util;
18 
19 import android.hardware.camera2.CameraMetadata;
20 import android.hardware.camera2.CaptureRequest;
21 import android.hardware.camera2.CaptureResult;
22 import android.hardware.camera2.params.ColorSpaceTransform;
23 import android.hardware.camera2.params.LensShadingMap;
24 import android.hardware.camera2.params.RggbChannelVector;
25 import android.hardware.camera2.params.TonemapCurve;
26 import android.util.Pair;
27 import android.util.Rational;
28 
29 import com.android.camera.debug.Log;
30 import com.android.camera.debug.Log.Tag;
31 
32 import java.io.BufferedWriter;
33 import java.io.File;
34 import java.io.FileWriter;
35 import java.io.IOException;
36 import java.io.StringWriter;
37 import java.io.Writer;
38 import java.lang.reflect.Array;
39 import java.util.Arrays;
40 import java.util.List;
41 
42 /**
43  * Can be used for debugging to output details about Camera2 capture request and
44  * responses.
45  */
46 public class CaptureDataSerializer {
47     private static interface Writeable {
write(Writer writer)48         public void write(Writer writer) throws IOException;
49     }
50 
51     private static final Tag TAG = new Tag("CaptureDataSerilzr");
52 
53     /**
54      * Generate a human-readable string of the given capture request and return
55      * it.
56      */
toString(String title, CaptureRequest metadata)57     public static String toString(String title, CaptureRequest metadata) {
58         StringWriter writer = new StringWriter();
59         dumpMetadata(title, metadata, writer);
60         return writer.toString();
61     }
62 
63     /**
64      * Generate a human-readable string of the given capture request and write
65      * it to the given file.
66      */
toFile(String title, CameraMetadata<?> metadata, File file)67     public static void toFile(String title, CameraMetadata<?> metadata, File file) {
68         try {
69             // Will append if the file already exists.
70             FileWriter writer = new FileWriter(file, true);
71             if (metadata instanceof CaptureRequest) {
72                 dumpMetadata(title, (CaptureRequest) metadata, writer);
73             } else if (metadata instanceof CaptureResult) {
74                 dumpMetadata(title, (CaptureResult) metadata, writer);
75             } else {
76                 writer.close();
77                 throw new IllegalArgumentException("Cannot generate debug data from type "
78                         + metadata.getClass().getName());
79             }
80             writer.close();
81         } catch (IOException ex) {
82             Log.e(TAG, "Could not write capture data to file.", ex);
83         }
84     }
85 
86     /**
87      * Writes the data about the marker and requests to the given folder for
88      * offline debugging.
89      */
dumpMetadata(final String title, final CaptureRequest metadata, Writer writer)90     private static void dumpMetadata(final String title, final CaptureRequest metadata,
91             Writer writer) {
92         Writeable writeable = new Writeable() {
93             @Override
94             public void write(Writer writer) throws IOException {
95                 List<CaptureRequest.Key<?>> keys = metadata.getKeys();
96                 writer.write(title + '\n');
97 
98                 // TODO: move to CameraMetadata#toString ?
99                 for (CaptureRequest.Key<?> key : keys) {
100                     writer.write(String.format("    %s\n", key.getName()));
101                     writer.write(String.format("        %s\n",
102                             metadataValueToString(metadata.get(key))));
103                 }
104             }
105         };
106         dumpMetadata(writeable, new BufferedWriter(writer));
107     }
108 
109     /**
110      * Writes the data about the marker and requests to the given folder for
111      * offline debugging.
112      */
dumpMetadata(final String title, final CaptureResult metadata, Writer writer)113     private static void dumpMetadata(final String title, final CaptureResult metadata,
114             Writer writer) {
115         Writeable writeable = new Writeable() {
116             @Override
117             public void write(Writer writer) throws IOException {
118                 List<CaptureResult.Key<?>> keys = metadata.getKeys();
119                 writer.write(String.format(title) + '\n');
120 
121                 // TODO: move to CameraMetadata#toString ?
122                 for (CaptureResult.Key<?> key : keys) {
123                     writer.write(String.format("    %s\n", key.getName()));
124                     writer.write(String.format("        %s\n",
125                             metadataValueToString(metadata.get(key))));
126                 }
127             }
128         };
129         dumpMetadata(writeable, new BufferedWriter(writer));
130     }
131 
metadataValueToString(Object object)132     private static String metadataValueToString(Object object) {
133         if (object == null) {
134             return "<null>";
135         }
136         if (object.getClass().isArray()) {
137             StringBuilder builder = new StringBuilder();
138             builder.append("[");
139 
140             int length = Array.getLength(object);
141             for (int i = 0; i < length; ++i) {
142                 Object item = Array.get(object, i);
143                 builder.append(metadataValueToString(item));
144 
145                 if (i != length - 1) {
146                     builder.append(", ");
147                 }
148             }
149             builder.append(']');
150 
151             return builder.toString();
152         } else {
153             // These classes don't have a toString() method yet
154             // See: http://b/16899576
155             if (object instanceof LensShadingMap) {
156                 return toString((LensShadingMap) object);
157             } else if (object instanceof Pair) {
158                 return toString((Pair<?, ?>) object);
159             }
160             return object.toString();
161         }
162     }
163 
dumpMetadata(Writeable metadata, Writer writer)164     private static void dumpMetadata(Writeable metadata, Writer writer) {
165         /**
166          * Save metadata to file, appending if another metadata is already in
167          * that file.
168          */
169         try {
170             metadata.write(writer);
171         } catch (IOException e) {
172             Log.e(TAG, "dumpMetadata - Failed to dump metadata", e);
173         } finally {
174             try {
175                 if (writer != null) {
176                     writer.close();
177                 }
178             } catch (IOException e) {
179                 Log.e(TAG, "dumpMetadata - Failed to close writer.", e);
180             }
181         }
182     }
183 
toString(LensShadingMap lensShading)184     private static String toString(LensShadingMap lensShading) {
185         StringBuilder str = new StringBuilder();
186         str.append("LensShadingMap{");
187 
188         String channelName[] = {"R", "G_even", "G_odd", "B"};
189         int numRows = lensShading.getRowCount();
190         int numCols = lensShading.getColumnCount();
191         int numChannels = RggbChannelVector.COUNT;
192 
193         for (int ch = 0; ch < numChannels; ch++) {
194             str.append(channelName[ch]);
195             str.append(":(");
196 
197             for (int r = 0; r < numRows; r++) {
198                 str.append("[");
199                 for (int c = 0; c < numCols; c++) {
200                     float gain = lensShading.getGainFactor(ch, c, r);
201                     str.append(gain);
202                     if (c < numCols - 1) {
203                         str.append(", ");
204                     }
205                 }
206                 str.append("]");
207                 if (r < numRows - 1) {
208                     str.append(", ");
209                 }
210             }
211 
212             str.append(")");
213             if (ch < numChannels - 1) {
214                 str.append(", ");
215             }
216         }
217 
218         str.append("}");
219         return str.toString();
220     }
221 
toString(Pair<?, ?> pair)222     private static String toString(Pair<?, ?> pair) {
223         return "Pair: " + metadataValueToString(pair.first) + " / "
224                 + metadataValueToString(pair.second);
225     }
226 }
227