/**
   * select the first codec that match a specific MIME type
   *
   * @param mimeType
   * @return
   */
  private static final MediaCodecInfo selectAudioCodec(final String mimeType) {
    if (DEBUG) Log.v(TAG, "selectAudioCodec:");

    MediaCodecInfo result = null;
    // get the list of available codecs
    final int numCodecs = MediaCodecList.getCodecCount();
    LOOP:
    for (int i = 0; i < numCodecs; i++) {
      final MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
      if (!codecInfo.isEncoder()) { // skipp decoder
        continue;
      }
      final String[] types = codecInfo.getSupportedTypes();
      for (int j = 0; j < types.length; j++) {
        if (DEBUG) Log.i(TAG, "supportedType:" + codecInfo.getName() + ",MIME=" + types[j]);
        if (types[j].equalsIgnoreCase(mimeType)) {
          if (result == null) {
            result = codecInfo;
            break LOOP;
          }
        }
      }
    }
    return result;
  }
  private static DecoderProperties findDecoder(String mime, String[] supportedCodecPrefixes) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
      return null; // MediaCodec.setParameters is missing.
    }
    for (int i = 0; i < MediaCodecList.getCodecCount(); ++i) {
      MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);
      if (info.isEncoder()) {
        continue;
      }
      String name = null;
      for (String mimeType : info.getSupportedTypes()) {
        if (mimeType.equals(mime)) {
          name = info.getName();
          break;
        }
      }
      if (name == null) {
        continue; // No HW support in this codec; try the next one.
      }
      Logging.v(TAG, "Found candidate decoder " + name);

      // Check if this is supported decoder.
      boolean supportedCodec = false;
      for (String codecPrefix : supportedCodecPrefixes) {
        if (name.startsWith(codecPrefix)) {
          supportedCodec = true;
          break;
        }
      }
      if (!supportedCodec) {
        continue;
      }

      // Check if codec supports either yuv420 or nv12.
      CodecCapabilities capabilities = info.getCapabilitiesForType(mime);
      for (int colorFormat : capabilities.colorFormats) {
        Logging.v(TAG, "   Color: 0x" + Integer.toHexString(colorFormat));
      }
      for (int supportedColorFormat : supportedColorList) {
        for (int codecColorFormat : capabilities.colorFormats) {
          if (codecColorFormat == supportedColorFormat) {
            // Found supported HW decoder.
            Logging.d(
                TAG,
                "Found target decoder "
                    + name
                    + ". Color: 0x"
                    + Integer.toHexString(codecColorFormat));
            return new DecoderProperties(name, codecColorFormat);
          }
        }
      }
    }
    return null; // No HW decoder.
  }
Пример #3
0
  private static boolean hasCodecForMime(boolean encoder, String mime) {
    for (MediaCodecInfo info : sMCL.getCodecInfos()) {
      if (encoder != info.isEncoder()) {
        continue;
      }

      for (String type : info.getSupportedTypes()) {
        if (type.equalsIgnoreCase(mime)) {
          Log.i(TAG, "found codec " + info.getName() + " for mime " + mime);
          return true;
        }
      }
    }
    return false;
  }
  /**
   * Returns the first codec capable of encoding the specified MIME type, or null if no match was
   * found.
   */
  private static MediaCodecInfo selectCodec(String mimeType) {
    int numCodecs = MediaCodecList.getCodecCount();
    for (int i = 0; i < numCodecs; i++) {
      MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);

      if (!codecInfo.isEncoder()) {
        continue;
      }

      String[] types = codecInfo.getSupportedTypes();
      for (int j = 0; j < types.length; j++) {
        if (types[j].equalsIgnoreCase(mimeType)) {
          return codecInfo;
        }
      }
    }
    return null;
  }
Пример #5
0
  @SuppressWarnings("RedundantThrows")
  public static String dumpDecoders() throws Exception {
    String str = "";
    for (MediaCodecInfo codecInfo : getMediaCodecList()) {
      // Skip encoders
      if (codecInfo.isEncoder()) {
        continue;
      }

      str += "Decoder: " + codecInfo.getName() + "\n";
      for (String type : codecInfo.getSupportedTypes()) {
        str += "\t" + type + "\n";
        CodecCapabilities caps = codecInfo.getCapabilitiesForType(type);

        for (CodecProfileLevel profile : caps.profileLevels) {
          str += "\t\t" + profile.profile + " " + profile.level + "\n";
        }
      }
    }
    return str;
  }
Пример #6
0
  // We declare this method as explicitly throwing Exception
  // since some bad decoders can throw IllegalArgumentExceptions unexpectedly
  // and we want to be sure all callers are handling this possibility
  @SuppressWarnings("RedundantThrows")
  private static MediaCodecInfo findKnownSafeDecoder(String mimeType, int requiredProfile)
      throws Exception {
    for (MediaCodecInfo codecInfo : getMediaCodecList()) {
      // Skip encoders
      if (codecInfo.isEncoder()) {
        continue;
      }

      // Check for explicitly blacklisted decoders
      if (isDecoderInList(blacklistedDecoderPrefixes, codecInfo.getName())) {
        LimeLog.info("Skipping blacklisted decoder: " + codecInfo.getName());
        continue;
      }

      // Find a decoder that supports the requested video format
      for (String mime : codecInfo.getSupportedTypes()) {
        if (mime.equalsIgnoreCase(mimeType)) {
          LimeLog.info("Examining decoder capabilities of " + codecInfo.getName());

          CodecCapabilities caps = codecInfo.getCapabilitiesForType(mime);

          if (requiredProfile != -1) {
            for (CodecProfileLevel profile : caps.profileLevels) {
              if (profile.profile == requiredProfile) {
                LimeLog.info("Decoder " + codecInfo.getName() + " supports required profile");
                return codecInfo;
              }
            }

            LimeLog.info("Decoder " + codecInfo.getName() + " does NOT support required profile");
          } else {
            return codecInfo;
          }
        }
      }
    }

    return null;
  }
Пример #7
0
  private boolean supports(String mimeType, int profile, int level, boolean testLevel) {
    int numCodecs = MediaCodecList.getCodecCount();
    for (int i = 0; i < numCodecs; i++) {
      MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
      if (codecInfo.isEncoder()) {
        continue;
      }

      if (!supportsMimeType(codecInfo, mimeType)) {
        continue;
      }

      CodecCapabilities capabilities = codecInfo.getCapabilitiesForType(mimeType);
      for (CodecProfileLevel profileLevel : capabilities.profileLevels) {
        if (profileLevel.profile == profile && (!testLevel || profileLevel.level >= level)) {
          return true;
        }
      }
    }

    return false;
  }
Пример #8
0
  private static MediaCodecInfo findPreferredDecoder() {
    // This is a different algorithm than the other findXXXDecoder functions,
    // because we want to evaluate the decoders in our list's order
    // rather than MediaCodecList's order

    for (String preferredDecoder : preferredDecoders) {
      for (MediaCodecInfo codecInfo : getMediaCodecList()) {
        // Skip encoders
        if (codecInfo.isEncoder()) {
          continue;
        }

        // Check for preferred decoders
        if (preferredDecoder.equalsIgnoreCase(codecInfo.getName())) {
          LimeLog.info("Preferred decoder choice is " + codecInfo.getName());
          return codecInfo;
        }
      }
    }

    return null;
  }
Пример #9
0
  public static MediaCodecInfo findFirstDecoder(String mimeType) {
    for (MediaCodecInfo codecInfo : getMediaCodecList()) {
      // Skip encoders
      if (codecInfo.isEncoder()) {
        continue;
      }

      // Check for explicitly blacklisted decoders
      if (isDecoderInList(blacklistedDecoderPrefixes, codecInfo.getName())) {
        LimeLog.info("Skipping blacklisted decoder: " + codecInfo.getName());
        continue;
      }

      // Find a decoder that supports the specified video format
      for (String mime : codecInfo.getSupportedTypes()) {
        if (mime.equalsIgnoreCase(mimeType)) {
          LimeLog.info("First decoder choice is " + codecInfo.getName());
          return codecInfo;
        }
      }
    }

    return null;
  }
Пример #10
0
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    mSurfaceView = (SurfaceView) findViewById(R.id.surface_view);
    //        mSurfaceView.setBackgroundColor(Color.RED);

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(
        new View.OnClickListener() {
          private VideoPlayer mVideoPlayer = null;

          @Override
          public void onClick(View view) {
            if (mVideoPlayer != null) {
              mVideoPlayer.stop();
            }

            mVideoPlayer =
                new VideoPlayer(
                    MainActivity.mSelectedEncoder,
                    mSurfaceView.getHolder().getSurface(),
                    BASE_FOLDER + MainActivity.mSelectedFile);
            VideoPlayer.PlayTask task = new VideoPlayer.PlayTask(mVideoPlayer);
            task.execute();

            //                Snackbar.make(view, "Replace with your own action",
            // Snackbar.LENGTH_LONG)
            //                        .setAction("Action", null).show();
          }
        });

    List<String> decodersNames = new ArrayList<String>();
    for (int i = 0; i < MediaCodecList.getCodecCount(); ++i) {
      MediaCodecInfo info = MediaCodecList.getCodecInfoAt(i);

      Log.d(TAG, "onCreate: info " + i + info.getName());

      if (!info.isEncoder()
          && (info.getName().contains("avc")
              || info.getName().contains("AVC")
              || info.getName().contains("h264")
              || info.getName().contains("H264"))) {
        decodersNames.add(info.getName());
      }

      //            mEncodersNames. = info.getName();
      //            String[] types = info.getSupportedTypes();
      //            String allTypes = "";
      //            for ( String type: types )
      //            {
      //                allTypes += type + "; ";
      //            }

      //            Log.d(TAG, "XXXXXX - " +
      //                    "Name: " + info.getName() + ", " +
      //                    "Types: " + allTypes + ", " +
      //                    (info.isEncoder() ? "Encoder" : "Decoder"));
    }

    {
      mEncodersNames = new String[decodersNames.size()];
      decodersNames.toArray(mEncodersNames);

      Spinner spinner = (Spinner) findViewById(R.id.listEncoders);

      ArrayAdapter<String> adapter =
          new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, mEncodersNames);
      adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
      // Apply the adapter to the spinner.
      spinner.setAdapter(adapter);
      spinner.setOnItemSelectedListener(this);
    }

    {
      File f = new File(new String(BASE_FOLDER));
      File filesDir = f; // getFilesDir()
      Log.d(TAG, "searching for files in " + filesDir.toString());
      mFilesNames = com.android.grafika.MiscUtils.getFiles(filesDir, "*");
      Log.d(TAG, "files: " + mFilesNames.toString());
      for (String file : mFilesNames) {
        Log.d(TAG, file);
      }

      Spinner spinner = (Spinner) findViewById(R.id.listFiles);
      ArrayAdapter<String> adapter =
          new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, mFilesNames);
      adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
      // Apply the adapter to the spinner.
      spinner.setAdapter(adapter);
      spinner.setOnItemSelectedListener(this);
    }
  }
 public boolean isEncoder() {
   return codecInfo.isEncoder();
 }