Monday, May 25, 2015

List supported media codec using MediaCodecList

This example list media codec available on the device, using MediaCodecList, to enumerate available codecs, each specified as a MediaCodecInfo object, find a codec supporting a given format and query the capabilities of a given codec.


MainActivity.java
package com.example.androidmediacodec;

import android.annotation.TargetApi;
import android.media.MediaCodecInfo;
import android.media.MediaCodecList;
import android.os.Build;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;


public class MainActivity extends ActionBarActivity {

    TextView textInfo;
    TextView textCodecCount;
    Spinner spinnerMediaCodec;

    TextView textCodecname;
    TextView textIsEncoder;
    Spinner spinnerSupportedType;

    MediaCodecInfo[] mediaCodecInfo;
    String[] mediaCodecName;
    ArrayAdapter<String> mediaCodecAdapter;

    String[] supportedType;
    ArrayAdapter<String> supportedTypeAdapter;

    TextView textCapabilities;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textInfo = (TextView) findViewById(R.id.textinfo);
        textCodecCount = (TextView) findViewById(R.id.textcodeccount);
        spinnerMediaCodec = (Spinner) findViewById(R.id.spMediaCodec);
        textCodecname = (TextView) findViewById(R.id.textcodecname);
        textIsEncoder = (TextView) findViewById(R.id.textisEncoder);
        spinnerSupportedType = (Spinner) findViewById(R.id.spsupportedType);
        textCapabilities = (TextView)findViewById(R.id.textcapabilities);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            getCodecInfo_21();
        }else{
            getCodecInfo_16();
        }

        mediaCodecName = new String[mediaCodecInfo.length];
        for(int i = 0; i < mediaCodecInfo.length; i++){
            mediaCodecName[i] = mediaCodecInfo[i].getName();
        }

        mediaCodecAdapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_spinner_item,
                mediaCodecName);
        mediaCodecAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinnerMediaCodec.setAdapter(mediaCodecAdapter);
        spinnerMediaCodec.setOnItemSelectedListener(mediaCodecOnItemSelectedListener);

    }

    AdapterView.OnItemSelectedListener mediaCodecOnItemSelectedListener =
            new AdapterView.OnItemSelectedListener(){

                @Override
                public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                    final MediaCodecInfo selMediaCodecInfo = mediaCodecInfo[position];
                    textCodecname.setText(selMediaCodecInfo.getName());
                    textIsEncoder.setText("isEncoder: " + selMediaCodecInfo.isEncoder());

                    supportedType = selMediaCodecInfo.getSupportedTypes();
                    supportedTypeAdapter = new ArrayAdapter<String>(MainActivity.this,
                            android.R.layout.simple_spinner_item,
                            supportedType);
                    supportedTypeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
                    spinnerSupportedType.setAdapter(supportedTypeAdapter);

                    spinnerSupportedType.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener(){
                        @Override
                        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                            String type = (String) parent.getItemAtPosition(position);

                            //...you can get more details from codecCapabilities
                            MediaCodecInfo.CodecCapabilities codecCapabilities = selMediaCodecInfo.getCapabilitiesForType(type);

                            textCapabilities.setText(codecCapabilities.toString());

                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                                textCapabilities.append("\n" + "MimeType: " + codecCapabilities.getMimeType());
                                textCapabilities.append("\n" + "DefaultFormat: " + codecCapabilities.getDefaultFormat().toString());
                            }

                        }

                        @Override
                        public void onNothingSelected(AdapterView<?> parent) {}
                    });
                }

                @Override
                public void onNothingSelected(AdapterView<?> parent) {}
            };

    //Added in API level 16
    //deprecated in API level 21
    //ref:
    //http://developer.android.com/reference/android/media/MediaCodecInfo.html
    private void getCodecInfo_16(){
        textInfo.setText("API < 21");
        int numCodecs = MediaCodecList.getCodecCount();
        mediaCodecInfo = new MediaCodecInfo[numCodecs];

        for (int i = 0; i < numCodecs; i++) {
            MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
            mediaCodecInfo[i] = codecInfo;
        }

        textCodecCount.setText("Number of Codec: " + numCodecs);

    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    private void getCodecInfo_21() {
        textInfo.setText("API >= 21");
        MediaCodecList mediaCodecList = new MediaCodecList(MediaCodecList.ALL_CODECS);
        //MediaCodecList mediaCodecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
        mediaCodecInfo = mediaCodecList.getCodecInfos();

        textCodecCount.setText("Number of Codec: " + mediaCodecInfo.length);
    }
}


layout/activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="16dp"
    android:paddingRight="16dp"
    android:paddingTop="16dp"
    android:paddingBottom="16dp"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:autoLink="web"
        android:text="http://android-er.blogspot.com/"
        android:textStyle="bold" />
    <TextView
        android:id="@+id/textinfo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/textcodeccount"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <Spinner
        android:id="@+id/spMediaCodec"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/textcodecname"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textStyle="bold"/>
    <TextView
        android:id="@+id/textisEncoder"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textStyle="italic"/>
    <Spinner
        android:id="@+id/spsupportedType"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#B0B0B0"/>

    <TextView
        android:id="@+id/textcapabilities"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textStyle="italic"/>

</LinearLayout>


Test on Nexus 7 running Android 5.1.1

Test on Redmi 2 running Android 4.4.4

download filesDownload the files (Android Studio Format).

download filesDownload the APK to test on your device.

Android Studio - too slow!!!
I try to force myself to switch to Android Studio. A suppose one hour example using Eclipse, now use up to 5 hours using Android Studio!

No comments: