1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4 
5 package org.mozilla.gecko.media;
6 
7 import android.media.MediaFormat;
8 import android.os.Bundle;
9 import android.os.Parcel;
10 import android.os.Parcelable;
11 
12 import java.nio.ByteBuffer;
13 
14 /** A wrapper to make {@link MediaFormat} parcelable.
15  *  Supports following keys:
16  *  <ul>
17  *  <li>{@link MediaFormat#KEY_MIME}</li>
18  *  <li>{@link MediaFormat#KEY_WIDTH}</li>
19  *  <li>{@link MediaFormat#KEY_HEIGHT}</li>
20  *  <li>{@link MediaFormat#KEY_CHANNEL_COUNT}</li>
21  *  <li>{@link MediaFormat#KEY_SAMPLE_RATE}</li>
22  *  <li>{@link MediaFormat#KEY_BIT_RATE}</li>
23  *  <li>{@link MediaFormat#KEY_BITRATE_MODE}</li>
24  *  <li>{@link MediaFormat#KEY_COLOR_FORMAT}</li>
25  *  <li>{@link MediaFormat#KEY_FRAME_RATE}</li>
26  *  <li>{@link MediaFormat#KEY_I_FRAME_INTERVAL}</li>
27  *  <li>"csd-0"</li>
28  *  <li>"csd-1"</li>
29  *  </ul>
30  */
31 public final class FormatParam implements Parcelable {
32     // Keys for codec specific config bits not exposed in {@link MediaFormat}.
33     private static final String KEY_CONFIG_0 = "csd-0";
34     private static final String KEY_CONFIG_1 = "csd-1";
35 
36     private MediaFormat mFormat;
37 
asFormat()38     public MediaFormat asFormat() {
39         return mFormat;
40     }
41 
FormatParam(final MediaFormat format)42     public FormatParam(final MediaFormat format) {
43         mFormat = format;
44     }
45 
FormatParam(final Parcel in)46     protected FormatParam(final Parcel in) {
47         mFormat = new MediaFormat();
48         readFromParcel(in);
49     }
50 
51     public static final Creator<FormatParam> CREATOR = new Creator<FormatParam>() {
52         @Override
53         public FormatParam createFromParcel(final Parcel in) {
54             return new FormatParam(in);
55         }
56 
57         @Override
58         public FormatParam[] newArray(final int size) {
59             return new FormatParam[size];
60         }
61     };
62 
63     @Override
describeContents()64     public int describeContents() {
65         return 0;
66     }
67 
readFromParcel(final Parcel in)68     public void readFromParcel(final Parcel in) {
69         final Bundle bundle = in.readBundle();
70         fromBundle(bundle);
71     }
72 
fromBundle(final Bundle bundle)73     private void fromBundle(final Bundle bundle) {
74         if (bundle.containsKey(MediaFormat.KEY_MIME)) {
75             mFormat.setString(MediaFormat.KEY_MIME,
76                     bundle.getString(MediaFormat.KEY_MIME));
77         }
78         if (bundle.containsKey(MediaFormat.KEY_WIDTH)) {
79             mFormat.setInteger(MediaFormat.KEY_WIDTH,
80                     bundle.getInt(MediaFormat.KEY_WIDTH));
81         }
82         if (bundle.containsKey(MediaFormat.KEY_HEIGHT)) {
83             mFormat.setInteger(MediaFormat.KEY_HEIGHT,
84                     bundle.getInt(MediaFormat.KEY_HEIGHT));
85         }
86         if (bundle.containsKey(MediaFormat.KEY_CHANNEL_COUNT)) {
87             mFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT,
88                     bundle.getInt(MediaFormat.KEY_CHANNEL_COUNT));
89         }
90         if (bundle.containsKey(MediaFormat.KEY_SAMPLE_RATE)) {
91             mFormat.setInteger(MediaFormat.KEY_SAMPLE_RATE,
92                     bundle.getInt(MediaFormat.KEY_SAMPLE_RATE));
93         }
94         if (bundle.containsKey(KEY_CONFIG_0)) {
95             mFormat.setByteBuffer(KEY_CONFIG_0,
96                     ByteBuffer.wrap(bundle.getByteArray(KEY_CONFIG_0)));
97         }
98         if (bundle.containsKey(KEY_CONFIG_1)) {
99             mFormat.setByteBuffer(KEY_CONFIG_1,
100                     ByteBuffer.wrap(bundle.getByteArray((KEY_CONFIG_1))));
101         }
102         if (bundle.containsKey(MediaFormat.KEY_BIT_RATE)) {
103             mFormat.setInteger(MediaFormat.KEY_BIT_RATE,
104                     bundle.getInt(MediaFormat.KEY_BIT_RATE));
105         }
106         if (bundle.containsKey(MediaFormat.KEY_BITRATE_MODE)) {
107             mFormat.setInteger(MediaFormat.KEY_BITRATE_MODE,
108                     bundle.getInt(MediaFormat.KEY_BITRATE_MODE));
109         }
110         if (bundle.containsKey(MediaFormat.KEY_COLOR_FORMAT)) {
111             mFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT,
112                     bundle.getInt(MediaFormat.KEY_COLOR_FORMAT));
113         }
114         if (bundle.containsKey(MediaFormat.KEY_FRAME_RATE)) {
115             mFormat.setInteger(MediaFormat.KEY_FRAME_RATE,
116                     bundle.getInt(MediaFormat.KEY_FRAME_RATE));
117         }
118         if (bundle.containsKey(MediaFormat.KEY_I_FRAME_INTERVAL)) {
119             mFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL,
120                     bundle.getInt(MediaFormat.KEY_I_FRAME_INTERVAL));
121         }
122     }
123 
124     @Override
writeToParcel(final Parcel dest, final int flags)125     public void writeToParcel(final Parcel dest, final int flags) {
126         dest.writeBundle(toBundle());
127     }
128 
toBundle()129     private Bundle toBundle() {
130         final Bundle bundle = new Bundle();
131         if (mFormat.containsKey(MediaFormat.KEY_MIME)) {
132             bundle.putString(MediaFormat.KEY_MIME, mFormat.getString(MediaFormat.KEY_MIME));
133         }
134         if (mFormat.containsKey(MediaFormat.KEY_WIDTH)) {
135             bundle.putInt(MediaFormat.KEY_WIDTH, mFormat.getInteger(MediaFormat.KEY_WIDTH));
136         }
137         if (mFormat.containsKey(MediaFormat.KEY_HEIGHT)) {
138             bundle.putInt(MediaFormat.KEY_HEIGHT, mFormat.getInteger(MediaFormat.KEY_HEIGHT));
139         }
140         if (mFormat.containsKey(MediaFormat.KEY_CHANNEL_COUNT)) {
141             bundle.putInt(MediaFormat.KEY_CHANNEL_COUNT, mFormat.getInteger(MediaFormat.KEY_CHANNEL_COUNT));
142         }
143         if (mFormat.containsKey(MediaFormat.KEY_SAMPLE_RATE)) {
144             bundle.putInt(MediaFormat.KEY_SAMPLE_RATE, mFormat.getInteger(MediaFormat.KEY_SAMPLE_RATE));
145         }
146         if (mFormat.containsKey(KEY_CONFIG_0)) {
147             final ByteBuffer bytes = mFormat.getByteBuffer(KEY_CONFIG_0);
148             bundle.putByteArray(KEY_CONFIG_0,
149                 Sample.byteArrayFromBuffer(bytes, 0, bytes.capacity()));
150         }
151         if (mFormat.containsKey(KEY_CONFIG_1)) {
152             final ByteBuffer bytes = mFormat.getByteBuffer(KEY_CONFIG_1);
153             bundle.putByteArray(KEY_CONFIG_1,
154                 Sample.byteArrayFromBuffer(bytes, 0, bytes.capacity()));
155         }
156         if (mFormat.containsKey(MediaFormat.KEY_BIT_RATE)) {
157             bundle.putInt(MediaFormat.KEY_BIT_RATE, mFormat.getInteger(MediaFormat.KEY_BIT_RATE));
158         }
159         if (mFormat.containsKey(MediaFormat.KEY_BITRATE_MODE)) {
160             bundle.putInt(MediaFormat.KEY_BITRATE_MODE, mFormat.getInteger(MediaFormat.KEY_BITRATE_MODE));
161         }
162         if (mFormat.containsKey(MediaFormat.KEY_COLOR_FORMAT)) {
163             bundle.putInt(MediaFormat.KEY_COLOR_FORMAT, mFormat.getInteger(MediaFormat.KEY_COLOR_FORMAT));
164         }
165         if (mFormat.containsKey(MediaFormat.KEY_FRAME_RATE)) {
166             bundle.putInt(MediaFormat.KEY_FRAME_RATE, mFormat.getInteger(MediaFormat.KEY_FRAME_RATE));
167         }
168         if (mFormat.containsKey(MediaFormat.KEY_I_FRAME_INTERVAL)) {
169             bundle.putInt(MediaFormat.KEY_I_FRAME_INTERVAL, mFormat.getInteger(MediaFormat.KEY_I_FRAME_INTERVAL));
170         }
171         return bundle;
172     }
173 }
174