AMediaExtractor 在一种情况下会出错,而在其他情况下不会,为什么?
AMediaExtractor gives an error in one case and doesn't in other, why?
我需要将数据传递给MediaExtractor
,为此我使用了这个方法SetDataSource
https://developer.android.com/ndk/reference/group/media#amediaextractor_setdatasourcefd
像这样:
int32_t NDK_extractor::decode()
{
FILE *fp = nullptr;
media_status_t err;
AMediaExtractor *ex = AMediaExtractor_new();
fp = fopen("/storage/emulated/0/Android/data/com.test.debug/files/Models/test.mp3", "rb");
if (fp)
{
err = AMediaExtractor_setDataSourceFd(ex, fileno(fp), 0, dataSize);
}
else
{
LOGE("Failed open file");
return 0;
}
if (err != AMEDIA_OK)
{
LOGE("SOUND :: Error setting ex data source, err %d", err);
return 0;
}
...
}
它工作正常,但现在我需要使用指向数据和数据大小的指针,所以我像这样更改了这个方法
int32_t NDK_extractor::decode()
{
FILE *fp = nullptr;
media_status_t err;
AMediaExtractor *ex = AMediaExtractor_new();
fp = fopen("/storage/emulated/0/Android/data/com.test.debug/files/Models/test.mp3", "rb");
fseek(fp, 0, SEEK_END);
long lSize = ftell(fp);
rewind(fp);
void *buf = new unsigned char[lSize];
fread(buf, 1, lSize, fp);
fclose(fp);
fp = fmemopen(buf, lSize, "r");
if (fp)
{
err = AMediaExtractor_setDataSourceFd(ex, fileno(fp), 0, dataSize);
}
else
{
LOGE("Failed open file");
return 0;
}
if (err != AMEDIA_OK)
{
LOGE("SOUND :: Error setting ex data source, err %d", err);
return 0;
}
...
}
所以,我在缓冲区中读取相同的数据(与之前的例子一样)也得到一个大小,然后我用 fmemopen
打开它,结果得到这样的错误 - AMEDIA_ERROR_BASE
这里有什么问题?为什么它在一种情况下有效而在其他情况下却不起作用,尽管它几乎相同?我错过了什么?
结果,问题原来是AMediaExtractor_setDataSourceFd
方法接受一个文件描述符作为参数。为了从 FILE
获取文件描述符,您需要在使用 fopen()
打开的 FILE
上调用 fileno()
方法然后一切正常,但是如果文件被打开使用 fmemopen()
然后 fileno()
returns -1。我试图通过管道 来完成,但这种方法不适用于 AMediaExtractor_setDataSourceFd
(我认为是因为管道不支持 seek())试图通过自定义 MediaExtractor
(方法 setDataSource() 之一),但它仅通过 api 29 引入(它不太适合我)最后我用一种解决方法做到了 - 我得到字节,写入临时文件并使用 fopen()
打开此文件并调用 fileno()
获取文件描述符并将其传递给 setDataSouceFd()
我需要将数据传递给MediaExtractor
,为此我使用了这个方法SetDataSource
https://developer.android.com/ndk/reference/group/media#amediaextractor_setdatasourcefd
像这样:
int32_t NDK_extractor::decode()
{
FILE *fp = nullptr;
media_status_t err;
AMediaExtractor *ex = AMediaExtractor_new();
fp = fopen("/storage/emulated/0/Android/data/com.test.debug/files/Models/test.mp3", "rb");
if (fp)
{
err = AMediaExtractor_setDataSourceFd(ex, fileno(fp), 0, dataSize);
}
else
{
LOGE("Failed open file");
return 0;
}
if (err != AMEDIA_OK)
{
LOGE("SOUND :: Error setting ex data source, err %d", err);
return 0;
}
...
}
它工作正常,但现在我需要使用指向数据和数据大小的指针,所以我像这样更改了这个方法
int32_t NDK_extractor::decode()
{
FILE *fp = nullptr;
media_status_t err;
AMediaExtractor *ex = AMediaExtractor_new();
fp = fopen("/storage/emulated/0/Android/data/com.test.debug/files/Models/test.mp3", "rb");
fseek(fp, 0, SEEK_END);
long lSize = ftell(fp);
rewind(fp);
void *buf = new unsigned char[lSize];
fread(buf, 1, lSize, fp);
fclose(fp);
fp = fmemopen(buf, lSize, "r");
if (fp)
{
err = AMediaExtractor_setDataSourceFd(ex, fileno(fp), 0, dataSize);
}
else
{
LOGE("Failed open file");
return 0;
}
if (err != AMEDIA_OK)
{
LOGE("SOUND :: Error setting ex data source, err %d", err);
return 0;
}
...
}
所以,我在缓冲区中读取相同的数据(与之前的例子一样)也得到一个大小,然后我用 fmemopen
打开它,结果得到这样的错误 - AMEDIA_ERROR_BASE
这里有什么问题?为什么它在一种情况下有效而在其他情况下却不起作用,尽管它几乎相同?我错过了什么?
结果,问题原来是AMediaExtractor_setDataSourceFd
方法接受一个文件描述符作为参数。为了从 FILE
获取文件描述符,您需要在使用 fopen()
打开的 FILE
上调用 fileno()
方法然后一切正常,但是如果文件被打开使用 fmemopen()
然后 fileno()
returns -1。我试图通过管道 来完成,但这种方法不适用于 AMediaExtractor_setDataSourceFd
(我认为是因为管道不支持 seek())试图通过自定义 MediaExtractor
(方法 setDataSource() 之一),但它仅通过 api 29 引入(它不太适合我)最后我用一种解决方法做到了 - 我得到字节,写入临时文件并使用 fopen()
打开此文件并调用 fileno()
获取文件描述符并将其传递给 setDataSouceFd()