'lineize alignment'是什么意思?

Kud*_*ton 13 c++ ffmpeg

我正在http://dranger.com/ffmpeg/tutorial01.html上关注ffmpeg教程.

我刚刚发现该avpicture_get_size函数已被弃用.

所以我检查了ffmpeg的文件(https://www.ffmpeg.org/doxygen/3.0/group__lavu__picture.html#ga24a67963c3ae0054a2a4bab35930e694)并找到了替代品av_image_get_buffer_size.

但我无法理解align参数含义'lineize alignment'......

这是什么意思?

Ron*_*tje 16

FFmpeg的某些部分,特别是libavcodec,需要对齐的linesizes [],这意味着它需要:

assert(linesize[0] % 32 == 0);
assert(linesize[1] % 32 == 0);
assert(linesize[2] % 32 == 0);
Run Code Online (Sandbox Code Playgroud)

这允许它使用快速/对齐的SIMD例程(例如SSE2/AVX2 movdqavmovdqa指令)来进行数据访问,而不是使用较慢的未对齐的对应物.

alignav_image_get_buffer_size函数的参数是此行对齐,您需要它,因为缓冲区的大小受其影响.例如,YUV缓冲区中Y平面的大小实际上不是width*height,它是linesize [0]*height.您将看到(特别是对于不是16或32的倍数的图像大小),当您增加到align2的更高幂时,返回值会缓慢增加.

实际上,如果你打算使用这张图片作为输出缓冲区来调用,例如avcodec_decode_video2,这应该是32.对于swscale/avfilter,我认为没有绝对的要求,但你建议仍然使它32.


rot*_*ava 8

我的做法:

1.avpicture弃用问题,我用AVFrameimgutils函数替换avpicture函数.代码示例:

   //AVPicture           _picture;
   AVFrame             *_pictureFrame;
   uint8_t             *_pictureFrameData;
Run Code Online (Sandbox Code Playgroud)

...

//_pictureValid = avpicture_alloc(&_picture,
//                                AV_PIX_FMT_RGB24,
//                               _videoCodecCtx->width,
//                               _videoCodecCtx->height) == 0;

_pictureFrame = av_frame_alloc();
_pictureFrame->width = _videoCodecCtx->width;
_pictureFrame->height = _videoCodecCtx->height;
_pictureFrame->format = AV_PIX_FMT_RGB24;

int size = av_image_get_buffer_size(_pictureFrame->format,
                                    _pictureFrame->width,
                                    _pictureFrame->height,
                                    1);

//dont forget to free _pictureFrameData at last                                    
_pictureFrameData = (uint8_t*)av_malloc(size);

 av_image_fill_arrays(_pictureFrame->data,
                      _pictureFrame->linesize,
                      _pictureFrameData,
                      _pictureFrame->format,
                      _pictureFrame->width,
                      _pictureFrame->height,
                      1);
Run Code Online (Sandbox Code Playgroud)

...

if (_pictureFrame) {
    av_free(_pictureFrame);
    if (_pictureFrameData) {
        free(_pictureFrameData);
    }
}
Run Code Online (Sandbox Code Playgroud)

2.对齐参数

首先我将对齐设置为32,但对于某些视频流,它不起作用,导致图像失真.然后我将它设置为16(我的环境:mac,Xcode,iPhone6),一些流运行良好.但最后我将对齐设置为1,因为我发现了这一点

Fill in the AVPicture fields, always assume a linesize alignment of 1. 
Run Code Online (Sandbox Code Playgroud)

  • 那么最后如何为所有视频文件正确计算`align`? (2认同)

小智 5

如果您查看3.2 版中avpicture_get_size的定义,您会看到以下代码:

int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height)
{
    return av_image_get_buffer_size(pix_fmt, width, height, 1);
}
Run Code Online (Sandbox Code Playgroud)

它只是调用函数提示:av_image_get_buffer_sizealign参数设置1。我没有进一步了解为什么1用于折旧函数的全部意义。与 ffmpeg 一样,人们可以通过阅读正确的代码和足够的代码(通过一些代码实验)来弄清楚它。