【问题标题】:android MediaSource not recogonized as class in jni codeandroid Media Source 在 jni 代码中未被识别为类
【发布时间】:2013-11-30 04:54:47
【问题描述】:

我正在尝试使用androidndk 开发简单的decoder/player 应用程序。我使用androidsdk 创建了一个项目,然后我在我的项目目录中创建了一个名为jni 的文件夹。 在 jni 目录中,我创建了一个 omx.cpp 文件,我想在其中编写自己的类,它从 stagefright 继承 Android MediaSource。我还在我的项目中包含了 stagefright 头文件。我正在加载 @987654331 @ 在我的omx.cpp 文件中使用 dlopen

我使用的代码如下:

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函数中,如果我们创建一些类对象并使用它们来调用MediaSource类的函数,或者我们必须创建单独的.cpp和.h文件。如果我们使用单独的文件如何我们是否从 jni 函数中调用/引用它。

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

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

如果建议使用ffmpeg 作为源,demuxing 那么如何将其与android st agefright 框架集成。

问候

【问题讨论】:

  • 请分享一些日志和您的Android.mkmakefile 以及一些显示您如何在代码中使用MediaSource 的来源。根据这些信息,我们可以为您提供帮助。

标签: android stagefright


【解决方案1】:

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

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

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

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

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

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

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

我还将在另一个线程的NDK 可能性上添加更多 cmets。

【讨论】:

  • 如何将omx编解码器组件作为硬件组件集成到android代码中。也可以在应用程序级别查询框架是使用omx软件还是硬件组件作为解码器。
  • @MayankAgarwal.. 要添加任何 OMX 组件,请查看此线程:stackoverflow.com/questions/15334509/…。当您提到一个应用程序时,您能否更具体地说明您正在查看哪个应用程序?例如:对于像stagefright 这样的示例命令行实用程序,有一种方法更喜欢软件编解码器,如下所示:androidxref.com/4.4.2_r1/xref/frameworks/av/cmds/stagefright/…。如果这不能回答您当前的查询,您能否发布一个不同的问题?
  • 目前我有一个多媒体产品的android开源代码,该项目使用其定制的媒体播放器比stagefright好得多,播放器选择是在MediaPlayerService.cpp中完成的(android也在做同样的事情)。但是而不是 STAGEFRIGHT_PLAYER 它正在创建自己的播放器。如果我删除该自定义,则 m3u8 文件(android 使用 NU Player 播放 m3u8 文件)由于 OMX 软件解码器中发生崩溃而无法播放。现在我该如何更改这个 omx 软件解码器其他一些可以播放 m3u8 文件的解码器。
  • @MayankAgarwal.. 在您的media_codecs.xml 文件中,确保您的首选解码器是给定mime 类型文件中第一个出现的解码器。这样,就不会回退到软件解码器。通常,只有在找不到任何其他编解码器类型时,流程才会回退到 SW 解码器。您对哪个编解码器有疑问??
  • 有什么办法可以在应用程序级别选择解码器组件并通过 jni 将其提供给 omxcodec.cpp
猜你喜欢
  • 2017-06-27
  • 2018-02-28
  • 1970-01-01
  • 2021-11-22
  • 2017-01-19
  • 2021-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多