有什么方法可以在 ANativeWindow 上渲染原始视频,同时将其写入文件?
Any way to render a raw video on a ANativeWindow and at the same time write it to a file?
我尝试将原始 h264 视频渲染到表面(解码后)并同时将其写入文件。
渲染工作正常,但是当我想获取当前输出缓冲区时,它的大小始终为 8,输出文件的大小为 3,87 Ko。
输出缓冲区似乎被表面(ANativeWindow)锁定了?
任何人都可以给我一个建议,让我在不创建另一个编解码器的情况下做到这一点?
编解码器配置有输出表面:
if (AMEDIA_OK == AMediaCodec_configure(d->codec, d->format, d->window /*the native window */, NULL, 0)
这是我尝试获取输出缓冲区时的代码片段:
if (!d->sawOutputEOS) {
AMediaCodecBufferInfo info;
auto status = AMediaCodec_dequeueOutputBuffer(d->codec, &info, -1);
if (status >= 0) {
if (info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) {
LOGV("output EOS");
d->sawOutputEOS = true;
d->isPlaying = false;
}
int64_t delay = 333000;
usleep((useconds_t )delay / 15);
size_t size;
// here i get the output buffer
uint8_t *outputbuffer = AMediaCodec_getOutputBuffer(d->codec,status,&size);
write(d->fd1,outputbuffer,size); // the output is always 0
LOGV("%d",size); // the size is always 8
LOGV("FRAME num : %d", counter[d->nb]++);
AMediaCodec_releaseOutputBuffer(d->codec, status, info.size != 0);
if (d->renderonce) {
d->renderonce = false;
return;
}
} else if (status == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED) {
LOGV("output buffers changed");
} else if (status == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED) {
auto format = AMediaCodec_getOutputFormat(d->codec);
LOGV("format changed to: %s", AMediaFormat_toString(format));
AMediaFormat_delete(format);
d->formatChanged = true;
} else if (status == AMEDIACODEC_INFO_TRY_AGAIN_LATER) {
LOGV("no output buffer right now");
} else {
LOGV("unexpected info code: %zd", status);
}
}
提前致谢
没有上锁;您要求解码器为显示工作,因此它使用最快的显示路径,而不会将像素暴露给可读内存。您可能会发现格式是不透明的 COLOR_FormatSurface, as explained .
我尝试将原始 h264 视频渲染到表面(解码后)并同时将其写入文件。 渲染工作正常,但是当我想获取当前输出缓冲区时,它的大小始终为 8,输出文件的大小为 3,87 Ko。
输出缓冲区似乎被表面(ANativeWindow)锁定了? 任何人都可以给我一个建议,让我在不创建另一个编解码器的情况下做到这一点?
编解码器配置有输出表面:
if (AMEDIA_OK == AMediaCodec_configure(d->codec, d->format, d->window /*the native window */, NULL, 0)
这是我尝试获取输出缓冲区时的代码片段:
if (!d->sawOutputEOS) {
AMediaCodecBufferInfo info;
auto status = AMediaCodec_dequeueOutputBuffer(d->codec, &info, -1);
if (status >= 0) {
if (info.flags & AMEDIACODEC_BUFFER_FLAG_END_OF_STREAM) {
LOGV("output EOS");
d->sawOutputEOS = true;
d->isPlaying = false;
}
int64_t delay = 333000;
usleep((useconds_t )delay / 15);
size_t size;
// here i get the output buffer
uint8_t *outputbuffer = AMediaCodec_getOutputBuffer(d->codec,status,&size);
write(d->fd1,outputbuffer,size); // the output is always 0
LOGV("%d",size); // the size is always 8
LOGV("FRAME num : %d", counter[d->nb]++);
AMediaCodec_releaseOutputBuffer(d->codec, status, info.size != 0);
if (d->renderonce) {
d->renderonce = false;
return;
}
} else if (status == AMEDIACODEC_INFO_OUTPUT_BUFFERS_CHANGED) {
LOGV("output buffers changed");
} else if (status == AMEDIACODEC_INFO_OUTPUT_FORMAT_CHANGED) {
auto format = AMediaCodec_getOutputFormat(d->codec);
LOGV("format changed to: %s", AMediaFormat_toString(format));
AMediaFormat_delete(format);
d->formatChanged = true;
} else if (status == AMEDIACODEC_INFO_TRY_AGAIN_LATER) {
LOGV("no output buffer right now");
} else {
LOGV("unexpected info code: %zd", status);
}
}
提前致谢
没有上锁;您要求解码器为显示工作,因此它使用最快的显示路径,而不会将像素暴露给可读内存。您可能会发现格式是不透明的 COLOR_FormatSurface, as explained