Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5bb4b20d authored by Santiago Seifert's avatar Santiago Seifert
Browse files

Support psshs with matching UUID in DrmInitData

Also prevent unnecessary allocation in a
MediaExtractor DrmInitData implementation.

Bug: 132153067
Test: Draft CL.
Change-Id: If7d50a9f3fec22035b6db41338a2d5e9e7e839db
parent 0a3c802e
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -24793,11 +24793,15 @@ package android.media {
  public abstract class DrmInitData {
    method public abstract android.media.DrmInitData.SchemeInitData get(java.util.UUID);
    method @NonNull public android.media.DrmInitData.SchemeInitData getSchemeInitDataAt(int);
    method public int getSchemeInitDataCount();
  }
  public static final class DrmInitData.SchemeInitData {
    field @NonNull public static final java.util.UUID UUID_NIL;
    field public final byte[] data;
    field public final String mimeType;
    field @NonNull public final java.util.UUID uuid;
  }
  public class ExifInterface {
+38 −5
Original line number Diff line number Diff line
@@ -15,11 +15,10 @@
 */
package android.media;

import android.annotation.NonNull;
import android.media.MediaDrm;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
@@ -41,11 +40,41 @@ public abstract class DrmInitData {
     */
    public abstract SchemeInitData get(UUID schemeUuid);

    /**
     * Returns the number of {@link SchemeInitData} elements available through {@link
     * #getSchemeInitDataAt}.
     */
    public int getSchemeInitDataCount() {
        return 0;
    }

    /**
     * Returns the {@link SchemeInitData} with the given {@code index}.
     *
     * @param index The index of the {@link SchemeInitData} to return.
     * @return The {@link SchemeInitData} associated with the given {@code index}.
     * @throws IndexOutOfBoundsException If the given {@code index} is negative or greater than
     *         {@link #getSchemeInitDataCount}{@code - 1}.
     */
    @NonNull public SchemeInitData getSchemeInitDataAt(int index) {
        throw new IndexOutOfBoundsException();
    }

    /**
     * Scheme initialization data.
     */
    public static final class SchemeInitData {

        /**
         * The Nil UUID, as defined in RFC 4122, section 4.1.7.
         */
        @NonNull public static final UUID UUID_NIL = new UUID(0, 0);

        /**
         * The UUID associated with this scheme initialization data. May be {@link #UUID_NIL} if
         * unknown or not applicable.
         */
        @NonNull public final UUID uuid;
        /**
         * The mimeType of {@link #data}.
         */
@@ -56,12 +85,14 @@ public abstract class DrmInitData {
        public final byte[] data;

        /**
         * @param uuid The UUID associated with this scheme initialization data.
         * @param mimeType The mimeType of the initialization data.
         * @param data The initialization data.
         *
         * @hide
         */
        public SchemeInitData(String mimeType, byte[] data) {
        public SchemeInitData(UUID uuid, String mimeType, byte[] data) {
            this.uuid = uuid;
            this.mimeType = mimeType;
            this.data = data;
        }
@@ -76,12 +107,14 @@ public abstract class DrmInitData {
            }

            SchemeInitData other = (SchemeInitData) obj;
            return mimeType.equals(other.mimeType) && Arrays.equals(data, other.data);
            return uuid.equals(other.uuid)
                    && mimeType.equals(other.mimeType)
                    && Arrays.equals(data, other.data);
        }

        @Override
        public int hashCode() {
            return mimeType.hashCode() + 31 * Arrays.hashCode(data);
            return uuid.hashCode() + 31 * (mimeType.hashCode() + 31 * Arrays.hashCode(data));
        }

    }
+34 −7
Original line number Diff line number Diff line
@@ -40,10 +40,12 @@ import java.lang.annotation.RetentionPolicy;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * MediaExtractor facilitates extraction of demuxed, typically encoded,  media data
@@ -393,17 +395,28 @@ final public class MediaExtractor {
        }
        if (formatMap.containsKey("pssh")) {
            Map<UUID, byte[]> psshMap = getPsshInfo();
            DrmInitData.SchemeInitData[] schemeInitDatas =
                    psshMap.entrySet().stream().map(
                            entry -> new DrmInitData.SchemeInitData(
                                    entry.getKey(), /* mimeType= */ "cenc", entry.getValue()))
                            .toArray(DrmInitData.SchemeInitData[]::new);
            final Map<UUID, DrmInitData.SchemeInitData> initDataMap =
                new HashMap<UUID, DrmInitData.SchemeInitData>();
            for (Map.Entry<UUID, byte[]> e: psshMap.entrySet()) {
                UUID uuid = e.getKey();
                byte[] data = e.getValue();
                initDataMap.put(uuid, new DrmInitData.SchemeInitData("cenc", data));
            }
                    Arrays.stream(schemeInitDatas).collect(
                            Collectors.toMap(initData -> initData.uuid, initData -> initData));
            return new DrmInitData() {
                public SchemeInitData get(UUID schemeUuid) {
                    return initDataMap.get(schemeUuid);
                }

                @Override
                public int getSchemeInitDataCount() {
                    return schemeInitDatas.length;
                }

                @Override
                public SchemeInitData getSchemeInitDataAt(int index) {
                    return schemeInitDatas[index];
                }
            };
        } else {
            int numTracks = getTrackCount();
@@ -416,9 +429,23 @@ final public class MediaExtractor {
                buf.rewind();
                final byte[] data = new byte[buf.remaining()];
                buf.get(data);
                // Webm scheme init data is not uuid-specific.
                DrmInitData.SchemeInitData webmSchemeInitData =
                        new DrmInitData.SchemeInitData(
                                DrmInitData.SchemeInitData.UUID_NIL, "webm", data);
                return new DrmInitData() {
                    public SchemeInitData get(UUID schemeUuid) {
                        return new DrmInitData.SchemeInitData("webm", data);
                        return webmSchemeInitData;
                    }

                    @Override
                    public int getSchemeInitDataCount() {
                        return 1;
                    }

                    @Override
                    public SchemeInitData getSchemeInitDataAt(int index) {
                        return webmSchemeInitData;
                    }
                };
            }