鉴于两个编码流,我想并排加入它们。假设我有两个独立的H.264编码的1024x768视频具有相同的帧速率。我希望将这两者结合起来,使视频1和视频2并排形成一个宽度为(1024 * 2)x768或2048x768的流。我的第一个尝试是解码流并组合各个帧然后重新编码单个流。解码和重新编码很好,但这很有效,但它非常慢(就像ffmpeg一样)。看起来问题在于将帧从YUV转换为RGB或将它们组合成YUV形式的计算时间。 Android解码器生成YUV,用于并排组合帧的数学对于该形式是密集的。所以我的问题是;
1)如果它们是YUV形式,是否有更快或更有效的方法来组合帧?
2a)如果没有,如果它们是RGB形式,它们在计算上组合得更快吗?
2b)如果是这样,我将如何将H.264流解码为Android中的RGB帧?
P.S。尝试ffmpeg和openCV都需要YUV到RGB转换,这使得它非常慢(~5fps)
谢谢!
答案 0 :(得分:1)
解码后的帧AVFrame在结构中具有uint_t *data[]
和int linesize[]
。 YUV帧具有三个数据指针和三个线条。通常线条尺寸大于宽度,因此请注意这一点。
这是一些可能有用的伪代码。希望没有太多错字。
// No proper checks in here, it's just for reference
// You could just as easily pass the data pointers for the outframe as uint8_t *data[]
void mergeFrames(AVFrame *frame1, AVFrame *frame2, AVFrame *outframe)
{
// do Y frame
uint32_t *out = outframe->data[0]; // 1 and 2 are for the U and V frames
uint8_t *in1 = frame1->data[0];
uint8_t *in2 = frame2->data[0];
int height = outframe->height;
int inwidth = frame1->width;
int stride = frame1->linesize[0];
int pos = 0;
while (pos++ < height) {
// left side
uint32_t *in = (uint32_t*)(in1 + pos * stride); // <- stride, not width
int c = frame1->width >> 2; // assume 4 bytes
while (c--) *out++ = *in++;
// right side
in = (uint32_t*)(in2 + pos * stride);
c = width >> 2;
while (c--) *out++ = *in++;
}
// And the same for the U and V frames
}
编译器应该很好地优化它。
另请注意,使用U和V框架时,它们是Y框架宽度的一半和高度的一半。
答案 1 :(得分:0)
为了组合这些图像需要什么复杂的数学?
您需要做的就是将每行从frameOfVideo1复制到索引0到1023,每行从frameOfVideo2复制到索引1024到2047。 (组合图像的行)
(这些是y平面的索引.u,v平面或uv平面(例如nv12)数字不同。但概念是相同的)