title: Cannot play a video from internal storage with the native codec given by Google using adb
body: <p>I am using the native codec app given by Google: (<a href="https://github.com/googlesamples/android-ndk/tree/master/native-codec" rel="nofollow noreferrer">https://github.com/googlesamples/android-ndk/tree/master/native-codec</a>).
  The app has a folder (assets) which contains some video samples to play.
  My purpose is to read videos from the internal storage of the phone (i.e /sdcard/filename.mp4).
  I added these 2 lines to the manifest file but this hasn't helped to fix the issue yet.</p>
  
  <pre><code>&lt;uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/&gt;
  &lt;uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/&gt;
  </code></pre>
  
  <p>I modified the code to get the video filename as an argument given by adb shell.
  Here is the code:</p>
  
  <pre><code>    mSourceString = getIntent().getStringExtra("arg");
      if (!mCreated) {
          if (mSourceString != null) {
              mCreated = createStreamingMediaPlayer(getResources().getAssets(), mSourceString);
          }
      }
  
      if (mCreated) {
          mIsPlaying = !mIsPlaying;
          setPlayingStreamingMediaPlayer(mIsPlaying);
      }
  </code></pre>
  
  <p>The native code of the method which reads the video filename is the following:</p>
  
  <pre><code>jboolean Java_com_example_mohammed_myapplication_MainActivity_createStreamingMediaPlayer(JNIEnv* env,                                                                                   jclass clazz, jobject assetMgr, jstring filename)
  {
      LOGV("@@@ create");
  
      // convert Java string to UTF-8
      const char *utf8 = env-&gt;GetStringUTFChars(filename, NULL);
      LOGV("opening %s", utf8);
  
      off_t outStart, outLen;
      int fd = AAsset_openFileDescriptor(AAssetManager_open(AAssetManager_fromJava(env, assetMgr), utf8, 0),
                                         &amp;outStart, &amp;outLen);
  
      env-&gt;ReleaseStringUTFChars(filename, utf8);
      if (fd &lt; 0) {
          LOGE("failed to open file: %s %d (%s)", utf8, fd, strerror(errno));
          return JNI_FALSE;
      }
  
      data.fd = fd;
  
      workerdata *d = &amp;data;
  
      AMediaExtractor *ex = AMediaExtractor_new();
      media_status_t err = AMediaExtractor_setDataSourceFd(ex, d-&gt;fd,
                                                           static_cast&lt;off64_t&gt;(outStart),
                                                           static_cast&lt;off64_t&gt;(outLen));
      close(d-&gt;fd);
      if (err != AMEDIA_OK) {
          LOGV("setDataSource error: %d", err);
          return JNI_FALSE;
      }
  
      int numtracks = AMediaExtractor_getTrackCount(ex);
  
      AMediaCodec *codec = NULL;
  
      LOGV("input has %d tracks", numtracks);
      for (int i = 0; i &lt; numtracks; i++) {
          AMediaFormat *format = AMediaExtractor_getTrackFormat(ex, i);
          const char *s = AMediaFormat_toString(format);
          LOGV("track %d format: %s", i, s);
          const char *mime;
          if (!AMediaFormat_getString(format, AMEDIAFORMAT_KEY_MIME, &amp;mime)) {
              LOGV("no mime type");
              return JNI_FALSE;
          } else if (!strncmp(mime, "video/", 6)) {
              // Omitting most error handling for clarity.
              // Production code should check for errors.
              AMediaExtractor_selectTrack(ex, i);
              codec = AMediaCodec_createDecoderByType(mime);
              AMediaCodec_configure(codec, format, d-&gt;window, NULL, 0);
              d-&gt;ex = ex;
              d-&gt;codec = codec;
              d-&gt;renderstart = -1;
              d-&gt;sawInputEOS = false;
              d-&gt;sawOutputEOS = false;
              d-&gt;isPlaying = false;
              d-&gt;renderonce = true;
              AMediaCodec_start(codec);
          }
          AMediaFormat_delete(format);
      }
  
      mlooper = new mylooper();
      mlooper-&gt;post(kMsgCodecBuffer, d);
  
      return JNI_TRUE;
  }
  </code></pre>
  
  <p>The app plays the videos successfully when they are in the "assets" folder, i.e inside the app. But when a video is outside the app (internal/external storage) the app stops working.</p>
  
  <p>Is there a solution for this issue?</p>