/*
* Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.camera.video.internal.workaround;
import android.media.MediaMuxer;
import android.util.Pair;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.camera.video.internal.compat.quirk.DeviceQuirks;
import androidx.camera.video.internal.compat.quirk.NegativeLatLongSavesIncorrectlyQuirk;
/**
* Workaround to correct negative geo location in the saved video metadata.
*
* <p>See {@link NegativeLatLongSavesIncorrectlyQuirk} and b/232327925 for the reason.
* {@link #adjustGeoLocation} should be applied to the geo location before setting to
* MediaMuxer#setLocation.
*/
@RequiresApi(21) // TODO(b/200306659): Remove and replace with annotation on package-info.java
public final class CorrectNegativeLatLongForMediaMuxer {
private CorrectNegativeLatLongForMediaMuxer() {
}
/**
* Adjusts the geo location for setting to {@link MediaMuxer#setLocation(float, float)}.
*
* <p>In the source code of MediaMuxer#setLocation:
* <pre>{@code
* int latitudex10000 = (int) (latitude * 10000 + 0.5);
* int longitudex10000 = (int) (longitude * 10000 + 0.5);
* }</pre>
* For negative latitude and longitude, "minus 0.5" should be applied instead of "plus 0.5" for
* rounding. This method does nothing for positive value and "minus 1" for negative value.
* The geo location should apply this adjustment before setting to MediaMuxer#setLocation, which
* results in the effect of "minus 0.5" for rounding on negative latitude and longitude in
* the above source code.
*
* @return a pair of {@link Double}. The first element of the pair is the adjusted latitude.
* The second element of the pair is the adjusted longitude.
*/
@NonNull
public static Pair<Double, Double> adjustGeoLocation(double latitude, double longitude) {
if (DeviceQuirks.get(NegativeLatLongSavesIncorrectlyQuirk.class) != null) {
latitude = adjustInternal(latitude);
longitude = adjustInternal(longitude);
}
return Pair.create(latitude, longitude);
}
private static double adjustInternal(double value) {
return value >= 0 ? value : (value * 10000.0 - 1.0) / 10000.0;
}
}