视频图像学习[2]--关于ffmpeg出现muxing overhead的分析

本文讨论了在视频转码过程中遇到的高比特率音频导致的问题,并提供了两种解决方案:一是通过设定特定参数使ffmpeg自动调整降低码率;二是仅设定视频编码参数,让ffmpeg自行处理音频部分。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个问题对我来讲主要是由于视频中的音频数据bit率很高造成的。

那我来说,如果我转码的时候设置是 -vcodec libx264 -acodec copy 音频自动copy原始数据的话,我转的影像的bit率会与一万多

但是如果我只设定了-vcodec libx264 不管音频acodec编码的话,ffmpeg会自动调整降低码率的,1080p或者720p的每一帧bit率也只有2000左右,同时这时候音频视频同步问题也很好解决了。

v4l2-ctl -d /dev/video0 --stream-mmap --stream-count=1 --stream-to=frame.raw < nvidia@tegra-ubuntu:~$ ffmpeg -f rawvideo -pix_fmt yuyv422 -s 640x480 -i frame.raw output.jpg ffmpeg version 4.4.2-1ubuntu0.1 Copyright (c) 2000-2021 the FFmpeg developers built with gcc 11 (Ubuntu 11.4.0-1ubuntu1~22.04) configuration: --prefix=/usr --enable-nvv4l2dec --enable-libv4l2 --enable-shared --extra-libs='-L/usr/lib/aarch64-linux-gnu/tegra -lv4l2 -lnvbufsurface -lnvbufsurftransform' --extra-cflags=-I/usr/src/jetson_multimedia_api/include/ --extra-version=1ubuntu0.1 --toolchain=hardened --libdir=/usr/lib/aarch64-linux-gnu --incdir=/usr/include/aarch64-linux-gnu --arch=arm64 --enable-gpl --disable-stripping --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libdav1d --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librabbitmq --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzimg --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-pocketsphinx --enable-librsvg --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared libavutil 56. 70.100 / 56. 70.100 libavcodec 58.134.100 / 58.134.100 libavformat 58. 76.100 / 58. 76.100 libavdevice 58. 13.100 / 58. 13.100 libavfilter 7.110.100 / 7.110.100 libswscale 5. 9.100 / 5. 9.100 libswresample 3. 9.100 / 3. 9.100 libpostproc 55. 9.100 / 55. 9.100 [rawvideo @ 0xaaab010f9a30] Packet corrupt (stream = 0, dts = 0). [rawvideo @ 0xaaab010f9a30] Estimating duration from bitrate, this may be inaccurate Input #0, rawvideo, from 'frame.raw': Duration: N/A, start: 0.000000, bitrate: 122880 kb/s Stream #0:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 640x480, 122880 kb/s, 25 tbr, 25 tbn, 25 tbc Stream mapping: Stream #0:0 -> #0:0 (rawvideo (native) -> mjpeg (native)) Press [q] to stop, [?] for help frame.raw: corrupt input packet in stream 0 [rawvideo @ 0xaaab011046e0] Invalid buffer size, packet size 48509 < expected frame_size 614400 Error while decoding stream #0:0: Invalid argument [swscaler @ 0xaaab011103a0] deprecated pixel format used, make sure you did set range correctly Output #0, image2, to 'output.jpg': Metadata: encoder : Lavf58.76.100 Stream #0:0: Video: mjpeg, yuvj422p(pc), 640x480, q=2-31, 200 kb/s, 25 fps, 25 tbn Metadata: encoder : Lavc58.134.100 mjpeg Side data: cpb: bitrate max/min/avg: 0/0/200000 buffer size: 0 vbv_delay: N/A frame= 0 fps=0.0 q=0.0 Lsize=N/A time=00:00:00.00 bitrate=N/A speed= 0x video:0kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown Output file is empty, nothing was encoded (check -ss / -t / -frames parameters if used) Conversion failed! nvidia@tegra-ubuntu:~$
最新发布
06-13
<think>我们正在处理的是使用FFmpeg处理rawvideo时出现的错误,具体是'corruptinputpacket'和'Invalidbuffersize'。根据引用内容,这些错误通常发生在处理原始视频数据(如YUYV422格式)时,输入数据包的大小与预期帧大小不匹配。用户提到在Jetson平台上遇到此问题,因此我们需要考虑平台特定的因素(如硬件加速、内存对齐等),但核心问题还是在于FFmpeg对原始视频帧大小的计算。分析错误信息:1."Invalidbuffersize,packetsize11985408<expectedframe_size3585"(注意:这里数字可能有误,根据引用[1]中实际是packetsize11985408被截断到3585,但错误信息中又出现packetsize3584<expectedframe_size11985408,这看起来矛盾,可能是不同例子)实际上,引用[1]中的错误信息是:"Invalidbuffersize,packetsize*<expectedframe_size*。Truncatingpacketofsize11985408to3585"[rawvideo@0x1bd5390]Packetcorrupt(stream=0,dts=1).image_3264_2448_0.yuv:corruptinputpacketinstream0[rawvideo@0x1bd7c60]Invalidbuffersize,packetsize3584<expectedframe_size11985408这里有两个错误:a)数据包被截断(从11985408截断到3585)->这可能是由于帧大小计算错误导致。b)然后又说数据包大小3584小于期望的帧大小11985408->这明显不匹配。根据引用[5],我们可以知道不同像素格式的帧大小计算公式:-YUYV422:每个像素占2字节,所以一帧的大小=宽度*高度*2-例如,3264x2448的YUYV422图像,帧大小=3264*2448*2=15998976字节(约16MB)但错误信息中期望的帧大小是11985408,这显然不对(因为11985408不等于3264*2448*2)。因此,问题可能出在FFmpeg没有正确获取或设置视频的宽度、高度或像素格式。解决方案步骤:1.明确指定输入参数:在使用FFmpeg处理原始视频时,必须明确指定视频的宽度(-s)、高度、像素格式(-pix_fmt)和帧率(-r)等。例如:```bashffmpeg-frawvideo-s3264x2448-pix_fmtyuyv422-r30-iinput.yuvoutput.mp4```2.检查输入文件大小:确保输入文件的大小等于(帧大小×帧数)。如果文件大小不匹配,FFmpeg可能会在最后一帧报错。可以计算一帧的大小(width*height*bytes_per_pixel),然后乘以帧数,看是否等于文件大小。3.对于从摄像头直接获取的数据流(如使用V4L2),引用[3]提到,如果摄像头输出的是rawvideo(如YUYV422),那么获取到的AVPacket就是这种格式。在FFmpeg中,我们需要正确设置解码器参数(如果是作为输入,则设置demuxer的参数)。4.在Jetson平台上,可能涉及到硬件加速。但原始视频的处理通常不涉及硬件解码(因为rawvideo不需要解码)。所以问题可能还是在于参数设置。5.错误信息中提到的“Packetcorrupt”可能是由于帧大小不匹配导致FFmpeg解析错误,进而认为数据包损坏。6.引用[4]展示了处理packet和frame的代码,当出现错误时(如avcodec_send_packet返回负值)需要正确处理。但我们的情况是输入数据包本身就被认为损坏,所以重点在输入参数设置。具体到用户的问题,可能是以下原因之一:-没有正确设置视频的宽度和高度。-像素格式设置错误(比如实际是YUYV422,但设置成了yuv420p)。-输入文件不完整(比如在录制过程中被截断)。因此,我们给出以下建议:步骤1:确认原始视频的参数-宽度(width)和高度(height)是多少?-像素格式是什么?YUYV422?还是其他?-帧率是多少?步骤2:在FFmpeg命令中明确指定这些参数。例如,对于YUYV422格式,使用`-pix_fmtyuyv422`,并设置正确的分辨率。示例命令(假设分辨率为640x480,帧率30):```bashffmpeg-frawvideo-s640x480-pix_fmtyuyv422-r30-iinput.rawoutput.mp4```步骤3:如果问题仍然存在,检查输入文件是否完整。计算一帧的大小:640x480x2(YUYV422每个像素2字节)=614400字节。然后检查文件大小是否是614400的整数倍。步骤4:如果是从摄像头实时获取数据,确保在打开摄像头时设置了正确的格式和分辨率(通过v4l2-ctl设置,然后在FFmpeg中保持一致)。步骤5:在Jetson平台上,如果使用硬件加速,可能需要额外的参数。但rawvideo通常不需要硬件加速。如果使用硬件编码,可以尝试使用NVIDIA的编码器(例如使用h264_nvenc),但输入数据仍需正确设置。示例命令(使用硬件编码):```bashffmpeg-frawvideo-s640x480-pix_fmtyuyv422-r30-iinput.raw-c:vh264_nvencoutput.mp4```步骤6:如果问题仍然存在,可以尝试将YUYV422转换为YUV420P(因为很多编码器要求YUV420P),再进行编码。可以使用FFmpeg的滤镜进行转换:```bashffmpeg-frawvideo-s640x480-pix_fmtyuyv422-r30-iinput.raw-vf"format=yuv420p"-c:vlibx264output.mp4```或者,如果使用硬件编码器:```bashffmpeg-frawvideo-s640x480-pix_fmtyuyv422-r30-iinput.raw-vf"format=yuv420p"-c:vh264_nvencoutput.mp4```步骤7:如果是在程序中处理(如引用[3]和[4]的代码),则需要确保在打开视频流后,正确设置了编解码器参数(尤其是宽度、高度和像素格式)。同时,在读取数据包后,发送到解码器之前,检查数据包的大小是否与预期的帧大小一致。在代码中,可以通过如下方式计算一帧应该有多大:```c//根据像素格式、宽度、高度计算一帧的大小intexpected_frame_size=av_image_get_buffer_size(codecContext->pix_fmt,codecContext->width,codecContext->height,1);```然后比较packet->size和expected_frame_size。如果不一致,则说明有问题。注意:对于原始视频(rawvideo),每一帧应该是一个完整的数据包,且大小固定(除非分辨率变化,但通常不会)。总结:核心问题是输入参数(分辨率、像素格式)设置不正确,导致FFmpeg计算期望帧大小错误。请仔细检查并明确指定这些参数。如果以上步骤无法解决,请提供具体的FFmpeg命令或代码片段以及完整的错误输出,以便进一步分析。引用说明:[^1]:出现了帧大小不匹配的错误,导致数据包被截断和损坏的报错。[^3]:说明了直接从摄像头获取YUYV422格式的数据包,并提到可以转换为YUV420P进行显示。[^5]:提供了不同像素格式的帧大小计算方法,特别是YUYV422的帧大小是宽度*高度*2。</think>### 解决 FFmpeg 处理 rawvideo 时的 `corrupt input packet` 和 `Invalid buffer size` 错误 根据引用内容,这些错误通常由 **原始视频参数不匹配** 或 **数据包损坏** 引起。以下是针对 YUYV422 格式的解决方案(特别适用于 Jetson 平台): --- #### 1. **确认并正确指定视频参数** [^1][^2][^5] 错误的核心是 FFmpeg 计算的帧大小与实际数据包大小不一致。YUYV422 格式的帧大小计算公式: ```math \text{frame\_size} = \text{width} \times \text{height} \times 2 \quad \text{(字节)} ``` 在命令行中必须明确指定参数: ```bash # 正确示例:指定分辨率、像素格式和输入格式 ffmpeg -f rawvideo -s 3264x2448 -pix_fmt yuyv422 -i input.yuv output.mp4 ``` - **关键参数**: - `-s WIDTHxHEIGHT`:分辨率(必须与实际一致) - `-pix_fmt yuyv422`:明确像素格式 - `-f rawvideo`:声明原始视频输入 --- #### 2. **验证输入文件完整性** [^1][^4] ```bash # 检查YUV文件大小是否符合预期 expected_size=$((3264 * 2448 * 2 * 帧数)) # YUYV422每帧大小=宽×高×2 actual_size=$(wc -c < input.yuv) if [ $expected_size -ne $actual_size ]; then echo "错误:文件大小不匹配!应为$expected_size 字节,实际$actual_size 字节" fi ``` --- #### 3. **处理 Jetson 平台的特殊情况** [^3] 在 Jetson 上使用硬件加速时: ```bash # 添加硬件解码器参数(NVIDIA专用) ffmpeg -hwaccel cuda -hwaccel_device 0 -f rawvideo -s 3264x2448 -pix_fmt yuyv422 -i input.yuv -c:v h264_nvenc output.mp4 ``` - 如果仍报错,尝试关闭硬件加速: ```bash ffmpeg -hwaccel none -f rawvideo ... ``` --- #### 4. **数据包损坏的修复方案** [^1][^4] 在代码中处理损坏的数据包: ```c AVPacket *packet = av_packet_alloc(); while (av_read_frame(fmt_ctx, packet) >= 0) { if (packet->stream_index == video_stream_index) { // 验证数据包大小 int expected_size = codec_ctx->width * codec_ctx->height * 2; // YUYV422 if (packet->size < expected_size) { av_log(NULL, AV_LOG_WARNING, "数据包损坏,跳过!"); av_packet_unref(packet); continue; // 跳过损坏帧 } // 正常处理... } } ``` --- #### 5. **YUYV422 → YUV420P 转换** [^3][^5] 许多编码器(如H.264)要求 YUV420P 输入: ```bash # 转换后再编码 ffmpeg -f rawvideo -s 3264x2448 -pix_fmt yuyv422 -i input.yuv \ -vf "format=yuv420p" -c:v libx264 output.mp4 ``` 在代码中转换: ```c // 初始化转换上下文 SwsContext *sws_ctx = sws_getContext(width, height, AV_PIX_FMT_YUYV422, width, height, AV_PIX_FMT_YUV420P, SWS_BILINEAR, NULL, NULL, NULL); // 转换并写入 sws_scale(sws_ctx, src_data, src_linesize, 0, height, dst_data, dst_linesize); ``` --- ### 关键检查点 1. **分辨率一致性**:摄像头输出、FFmpeg参数和实际数据必须完全匹配 2. **文件完整性**:通过 `ls -l` 验证文件大小是否符合 `width*height*2*帧数` 3. **Jetson 硬件加速**:尝试切换 `-hwaccel` 选项 4. **像素格式**:使用 `v4l2-ctl --all | grep Pixel` 确认摄像头实际格式 > **经验提示**:在 Jetson 上优先使用 `nvjpeg` 等硬件优化库处理原始视频流,效率更高且不易出错。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值