如何对透明背景的视频进行编码

2024-01-02

我正在使用 OSX 的 cocoa(使用 AVAssetWriter)以 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 通道值吗?


您可能不能,至少在 H.264 中是这样。看:如何创建带有 Alpha 通道的 h264 视频以与 HTML5 Canvas 一起使用? https://stackoverflow.com/questions/5055962/how-to-create-an-h264-video-with-an-alpha-channel-for-use-with-html5-canvas

我猜想透明度可以在编码为 H.264 之前用于混合和效果处理,但不能用于最终输出。

一种解决方法可能是将透明区域设置为纯绿色值,并在以后的视频编辑过程中使用该颜色作为遮罩(例如当他们使用绿色背景进行天气预报时)。显然,只有当输出用于此类编辑过程而不是最终输出时,这才有效。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何对透明背景的视频进行编码 的相关文章

随机推荐