如何使用透明背景进行视频编码

3

我正在使用AVAssetWriter在OSX上对视频进行h264编码。以下是配置:

// Configure video writer
AVAssetWriter *m_videoWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:@(outputFile)] fileType:AVFileTypeMPEG4 error:NULL];

// configure video input
NSDictionary *videoSettings = @{ AVVideoCodecKey : AVVideoCodecH264, AVVideoWidthKey : @(m_width), AVVideoHeightKey : @(m_height) };
AVAssetWriterInput* m_writerInput = [[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeVideo outputSettings:videoSettings];

// Add video input into video writer
[m_videoWriter addInput:m_writerInput];

// Start video writer
[m_videoWriter startWriting];
[m_videoWriter startSessionAtSourceTime:kCMTimeZero];

我正在使用'AVAssetWriterInputPixelBufferAdaptor'元素将帧添加到合成中,如下所示:
AVAssetWriterInputPixelBufferAdaptor *m_pixelBufferAdaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:m_writerInput sourcePixelBufferAttributes:NULL];

uint8_t* videobuffer = m_imageRGBA.data;


CVPixelBufferRef pixelBuffer = NULL;
CVReturn status = CVPixelBufferCreate (NULL, m_width, m_height, kCVPixelFormatType_32ARGB, NULL, &pixelBuffer);
if ((pixelBuffer == NULL) || (status != kCVReturnSuccess))
{
    NSLog(@"Error CVPixelBufferPoolCreatePixelBuffer[pixelBuffer=%@][status=%d]", pixelBuffer, status);
    return;
}
else
{
    uint8_t *videobuffertmp = videobuffer;
    CVPixelBufferLockBaseAddress(pixelBuffer, 0);
    GLubyte *pixelBufferData = (GLubyte *)CVPixelBufferGetBaseAddress(pixelBuffer);

    //printf("Video frame pixel: %d, %d, %d, %d\n", videobuffertmp[0], videobuffertmp[1], videobuffertmp[2], videobuffertmp[3]);

    for( int row=0 ; row<m_width ; ++row )
    {
        for( int col=0 ; col<m_height ; ++col )
        {
            memcpy(&pixelBufferData[0], &videobuffertmp[3], sizeof(uint8_t));       // alpha
            memcpy(&pixelBufferData[1], &videobuffertmp[2], sizeof(uint8_t));       // red
            memcpy(&pixelBufferData[2], &videobuffertmp[1], sizeof(uint8_t));       // green
            memcpy(&pixelBufferData[3], &videobuffertmp[0], sizeof(uint8_t));       // blue

            pixelBufferData += 4*sizeof(uint8_t);
            videobuffertmp  += 4*sizeof(uint8_t);
        }
    }

    CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
}

// transform new frame into pixel buffer
[m_pixelBufferAdaptor appendPixelBuffer:pixelBuffer
                   withPresentationTime:CMTimeMake(m_frameNumber, m_framesPerSecond)];

CFRelease(pixelBuffer);
pixelBuffer = nil;

在像素数据中,像素的alpha值被定义为透明的,但视频没有透明区域。我不确定编码器是否忽略了alpha值,或者是不可能对具有透明区域的视频进行编码。是否有任何方法可以在编码过程中包含alpha通道值?

可以在此答案中找到一个可行的实现:http://stackoverflow.com/a/26965602/763355 - MoDJ
1个回答

2
您可能无法在H.264中实现透明度。请参见:如何创建带有Alpha通道的h264视频以供HTML5 Canvas使用? 我猜透明度可以在编码为H.264之前的混合和效果处理中使用,但不能在最终输出中使用。
一种解决方法是将透明区域设置为纯绿色值,并在以后的视频编辑过程中使用该颜色作为蒙版(就像天气预报中使用绿色背景一样)。显然,这仅适用于输出旨在进行此类编辑过程而不是作为最终输出的情况。

是的,你说得对。编码器忽略了 alpha 值。我正在使用支持 alpha 通道的格式。在这种情况下是 Pro Res 4444。谢谢。 - goe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接