FFmpeg中帧与包的区别

17

我正在尝试使用LibAV解码MPEG视频文件。有两个术语我无法很好地理解,即数据包

根据我的理解,是未经压缩的视频帧,数据包是经过压缩的帧。

问题:

  • 一个数据包中可以有多个帧,对吗?
  • 一个帧是否只能作为一个数据包的一部分?我指的是一半帧信息在packet1中,另一半在packet2中的情况。这种情况可能发生吗?
  • 在LibAV中,我们如何知道一个数据包中有多少帧?

3
你找到答案了吗? - 404pio
1
我也对此感到困惑。虽然还没有弄清楚,但这是我的笔记 - https://dev.to/nsrcodes/packets-and-frames-in-libav-transcoding-pipeline-d0h - nsrCodes
3个回答

9

回答你的第一个和第三个问题:

  • AVPacket类的文档中指出:“对于视频,它通常应该包含一个压缩帧。对于音频,它可能包含多个压缩帧。”
  • 解码视频示例给出了以下代码,读取数据包中的所有帧;你也可以使用它来计算帧数:
static void decode(AVCodecContext *dec_ctx, AVFrame *frame, AVPacket *pkt,
                   const char *filename)
{
    char buf[1024];
    int ret;
    ret = avcodec_send_packet(dec_ctx, pkt);
    if (ret < 0) {
        fprintf(stderr, "Error sending a packet for decoding\n");
        exit(1);
    }
    while (ret >= 0) {
        ret = avcodec_receive_frame(dec_ctx, frame);
        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
            return;
        else if (ret < 0) {
            fprintf(stderr, "Error during decoding\n");
            exit(1);
        }
        printf("saving frame %3d\n", dec_ctx->frame_number);
        fflush(stdout);
        /* the picture is allocated by the decoder. no need to
           free it */
        snprintf(buf, sizeof(buf), filename, dec_ctx->frame_number);
        pgm_save(frame->data[0], frame->linesize[0],
                 frame->width, frame->height, buf);
    }
}

7

基本上,帧是自然的,而数据包是人工制造的。

帧是实质性的,数据包是辅助性的-它们通过可接受大小的小部分连续处理流(而不是整个流)。"分而治之"。

enter image description here

数据包有多个帧,对吗?

一个数据包可能有多个(已编码的)帧,也可能只有一个甚至是不完整的。

一个帧是否可以只属于一个数据包的一部分?

不行。它可能跨越多个数据包。请参见图片中的帧1

我指的是一个帧的一半信息在第一个数据包中,另一半在第二个数据包中,这种情况是否可能?

是的。请参见帧1

如何知道LibAV中一个数据包中有多少个帧?

不同的多媒体文件可能每个数据包中的帧数都不同,这取决于特定流的编码方式。

即使在同一个流中,也可能存在具有不同数量的(已编码的)帧的数据包 – 比较数据包0数据包1

一个数据包中没有关于其中包含多少(已编码的)帧的信息。

同一个数据包中的帧通常具有不同的大小(如上图所示),因此数据包不是由相等大小的元素(帧)组成的数组。


你的 Packet 1 的例子是否适用于I帧(关键帧)?我知道预测帧(p-frames,b-frames等)的帧数据可以在多个数据包中传输。它们建立在前一帧的基础上,因此隐含地在前一个或多个数据包中具有一些数据。但是,我找不到FFMPEG API中允许我将关键帧存储在多个数据包中的任何内容。 - FirefoxMetzger

3

简单来说,数据包就是数据块。

数据包的大小通常由带宽决定。如果设备的互联网速度有限或手机信号不佳,则数据包大小将更小。如果是专用服务的台式机,则数据包大小可能会相当大。

帧可以被视为一帧动画,但通常这些天,由于压缩,它不是实际的关键帧图像,而只是自上一个完整关键帧以来所发生变化的内容。他们会发送一个关键帧,即一个实际图像,每隔几秒钟左右,但在此期间的每个帧都只是指定自上一个图像以来哪些像素已经发生了改变的数据混合,即增量。

因此,假设您的数据包大小为1024字节,则您的分辨率将受到该流能够携带更改的像素数量的限制。他们可能会每个数据包发送一个帧以保持简单,但我认为没有任何东西能绝对保证它,因为数据流是从那些包重建的,通常是无序的,然后在拼接所有这些包后生成帧增量。

音频占用的空间比视频少得多,因此他们可能只需要为每50个视频数据包发送一个音频数据包。

我知道这些家伙在他们的频道上做了一些有关从数据包重新组合视频流的小视频 -- https://www.youtube.com/watch?v=DkIhI59ysXI


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