FFMPEG中的帧和数据包之间的差异

时间:2018-12-01 20:31:45

标签: codec libavcodec libav libavformat

我正在尝试使用LibAV解码mpeg视频文件。我无法正确理解两个术语:框架数据包

根据我目前的理解,是未压缩的视频帧,而数据包是已压缩的帧。

问题

  • 数据包有多个框架,对吧?
  • 一帧只能是一个数据包的一部分吗?我指的是帧信息的一半在数据包1中,另一半在数据包2中的情况?可能吗?
  • 我们如何知道LibAV中一个数据包中有多少帧?

2 个答案:

答案 0 :(得分:2)

要回答您的第一个和第三个问题:

  • 根据doc for the AVPacket class:“对于视频,通常应包含一个压缩帧。对于音频,可能应包含多个压缩帧。
  • decode video example提供了此代码,该代码可读取数据包内的所有帧;您还可以使用它来计算帧数:
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);
    }
}

答案 1 :(得分:1)

简单地说,数据包就是一个数据块。

这通常由带宽决定。如果设备的互联网速度有限,或者电话信号不连贯,则数据包大小将变小。如果它是具有专用服务的台式机,则数据包的大小可能会更大。

可以将一帧视为动画的一个单元,但是通常这些天由于压缩,它不是实际的关键帧图像,而仅仅是最后一个完整关键帧以来的变化。他们将每隔几秒钟左右发送一个关键帧,即一次实际图像,但是中间的每一帧只是数据的混合,用于指定自上一个图像(增量)以来哪些像素发生了变化。

是的,假设您的数据包大小为1024字节,那么您的分辨率将受限于流可以承载更改的像素数。他们可能会每包发送一帧以保持简单,但是我认为没有什么绝对可以保证的,因为从那些数据包中重建数据流时,通常是乱序的,然后生成帧增量所有这些小包都拼凑在一起。

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

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