android MediaSource在jni代码中未被识别为类

时间:2013-11-16 21:25:18

标签: android stagefright

我正在尝试使用android ndk来开发简单的decoder / player应用。我使用android sdk创建了一个项目,然后我在我的项目目录中创建了一个名为jni的文件夹。 在jni目录中,我创建了一个omx.cpp文件,我想在其中编写自己的类,从MediaSource继承Android stagefright。我还包含了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函数中,如果我们创建一些类对象并使用它们来调用say MediaSource类的函数,或者我们必须创建单独的.cpp和.h文件,这是可以的。如果我们如何使用单独的文件从jni函数调用/引用它。

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

基本上我想创建一个应用程序,它将.mp4 / .avi文件,demux分开音频/视频,使用android stagefright解码和渲染/播放它仅OpenMAX

如果为来源建议ffmpeg,请demux然后如何将其与android st agefright框架集成。

此致

1 个答案:

答案 0 :(得分:0)

要回答第一个问题,,可以在同一个源文件中定义class,并在下面的函数中对其进行实例化。我认为这样一个实现的最佳示例可能是DummySource实用程序的recordVideo,可以在cmds目录中找到。

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

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

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

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

其中ImageSource实施startread方法。我觉得上面的recordVideo示例是一个很好的参考。

关于最后一段,我会回答您的其他问题,但我觉得您的目标和代码之间存在根本的不匹配。目标是创建parserMediaExtractor以及相应的decoder,但上面的代码实例化ImageSource,我认为它会提供YUV个框架并创建正在传递encoder以创建编码器时true

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