0

我正在尝试使用 android ndk开发简单decoder/player应用程序。我使用创建了一个项目android sdk,然后在我的项目目录中创建了一个名为 jni 的文件夹。在 jni 目录中,我创建了一个omx.cpp文件,我想在其中编写我自己的类,该类继承自 Android MediaSourcestagefright我还在stagefright我的项目中包含了头文件。我正在libstagefright.so通过dlopen在我的omx.cpp文件中使用来加载。

我使用的代码如下:

using android::sp;

namespace android
{

class ImageSource : public MediaSource {
public:
ImageSource(int width, int height, int colorFormat)
: mWidth(width),
  mHeight(height),
  mColorFormat(colorFormat)
 {

  }

public:
int mWidth;
int mHeight;
int mColorFormat;

 virtual status_t start(MetaData *params = NULL) {}

 virtual status_t stop() {}

 // Returns the format of the data output by this media source.
 virtual sp<MetaData> getFormat() {}

 virtual status_t read(
    MediaBuffer **buffer, const MediaSource::ReadOptions *options) {
 }

/*protected:
virtual ~ImageSource() {}*/
};



void Java_com_exampleomxvideodecoder_MainActivity(JNIEnv *env, jobject obj, jobject    surface)
{

    void *dlhandle;

    dlhandle = dlopen("d:\libstagefright.so", RTLD_NOW);
    if (dlhandle == NULL)  {
        printf("Service  Not Found:  %s\n", dlerror());
    }
    int width = 720;
    int height = 480;
    int colorFormat = 0;

    sp<MediaSource> img_source = new ImageSource(width, height, colorFormat);

    sp<MetaData> enc_meta = new MetaData;
   // enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_H263);
   // enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);
   enc_meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
   enc_meta->setInt32(kKeyWidth, width);
   enc_meta->setInt32(kKeyHeight, height);
   enc_meta->setInt32(kKeySampleRate, kFramerate);
   enc_meta->setInt32(kKeyBitRate, kVideoBitRate);
   enc_meta->setInt32(kKeyStride, width);
   enc_meta->setInt32(kKeySliceHeight, height);
   enc_meta->setInt32(kKeyIFramesInterval, kIFramesIntervalSec);
   enc_meta->setInt32(kKeyColorFormat, colorFormat);


   sp<MediaSource> encoder =
       OMXCodec::Create(
               client.interface(), enc_meta, true, image_source);

   sp<MPEG4Writer> writer = new MPEG4Writer("/sdcard/screenshot.mp4");
   writer->addSource(encoder);

   // you can add an audio source here if you want to encode audio as well

   sp<MediaSource> audioEncoder =
   OMXCodec::Create(client.interface(), encMetaAudio, true, audioSource);
   writer->addSource(audioEncoder);

   writer->setMaxFileDuration(kDurationUs);
   CHECK_EQ(OK, writer->start());
   while (!writer->reachedEOS()) {
       fprintf(stderr, ".");
       usleep(100000);
   }
   err = writer->stop();
}
}

我有以下疑问:

1.在jni函数中,如果我们创建一些类对象并使用它们来调用sayMediaSource类的函数是否可以,或者我们必须创建单独的.cpp和.h文件。如果我们使用单独的文件,我们如何从jni函数调用/引用它.

2.这是制作我们自己的从MediaSource类继承的包装类的正确方法还是有其他方法。

基本上我想制作一个应用程序,它需要.mp4/.avi文件,它分离音频/视频,解码和demux渲染/播放它只使用android 。stagefrightOpenMAX

如果ffmpeg建议使用源代码,demux那么如何将其与android st agefright框架集成。

问候

4

1 回答 1

0

要回答您的第一个问题,class的,可以在同一个源文件中定义 a并在下面的函数中实例化它。我认为对于这种实现来说可能是非常好的示例的一个最佳示例是可以在目录中找到DummySource的实用程序。recordVideocmds

但是,您的文件应MediaSource.h直接或间接包含文件,如上述示例中所示。

第二问题更多的是实施选择或宗教。对于某些开发人员来说,定义一个新类并继承自MediaSource可能是您在示例中尝试过的正确方法。

有一个替代实现,您可以在其中创建源代码并将类型转换为MediaSoure强指针,如下例所示。

<sp><MediaSource>   mVideoSource;
mVideoSource = new ImageSource(width, height, colorformat);

whereImageSource实现startread方法。我觉得recordVideo上面的例子是一个很好的参考。

关于最后一段,我将回复您的其他查询,但我觉得您的目标和代码之间存在根本不匹配。目标是创建一个parserorMediaExtractor和一个对应的decoder,但上面的代码正在实例化一个ImageSource我认为它提供YUV帧并encoder在您传递true编码器创建时创建一个。

我还将NDK在另一个线程上添加关于可能性的进一步评论。

于 2013-11-19T16:52:31.573 回答