FFmpeg 播放 HTTP 视频流:数据读取与处理全流程
·
FFmpeg 播放 HTTP 视频流:数据读取与处理全流程
FFmpeg 播放 HTTP 视频流涉及多个关键阶段,以下是完整的处理流程:
1. 协议层处理
- 网络连接
通过libavformat建立 HTTP/TCP 连接,发送请求头:
GET /video.mp4 HTTP/1.1
支持断点续传(Range: bytes=0-)和分块传输编码(Transfer-Encoding: chunked)。 - 数据接收
循环接收数据包,存储到内部缓冲区(默认 4KB),通过环形队列管理网络 I/O。
2. 解封装(Demuxing)
- 格式探测
根据文件签名(如ftyp盒子)判断容器格式(MP4/FLV/TS)。 - 提取流信息
解析音视频元数据:
输出流参数:编码类型、分辨率、时间基 $\left( \frac{1}{90000} \right)$ 等。AVFormatContext *fmt_ctx; avformat_open_input(&fmt_ctx, "http://example.com/video.mp4", NULL, NULL); avformat_find_stream_info(fmt_ctx, NULL);
3. 解码准备
- 选择解码器
根据AVCodecParameters匹配解码器(如 H.264 →libx264,AAC →aac):AVCodec *codec = avcodec_find_decoder(stream->codecpar->codec_id); AVCodecContext *codec_ctx = avcodec_alloc_context3(codec); avcodec_parameters_to_context(codec_ctx, stream->codecpar); avcodec_open2(codec_ctx, codec, NULL);
4. 数据读取循环
graph LR
A[av_read_frame] --> B[获取 AVPacket]
B --> C{视频流?}
C -->|是| D[视频解码队列]
C -->|否| E[音频解码队列]
D --> F[avcodec_send_packet]
E --> F
F --> G[avcodec_receive_frame]
G --> H[输出 AVFrame]
5. 解码与同步
- 视频解码
将AVPacket送入解码器,输出AVFrame的 YUV 数据: $$ \text{YUV} \rightarrow \begin{bmatrix} Y & U \ V & \end{bmatrix} $$ - 音频解码
输出 PCM 采样数据:$ \text{PCM} = \sum_{n=0}^{N-1} A \sin(2\pi f n / f_s) $ - 同步控制
基于时间戳 $\text{PTS} = \text{base_time} \times \text{time_base}$ 和主时钟(通常以音频为基准)进行 AV 同步。
6. 渲染输出
- 视频渲染
通过sws_scale()转换 YUV 到目标格式(如 RGB),送显。 - 音频播放
通过swr_convert()重采样,写入声卡缓冲区。
关键参数调优
| 参数 | 作用 | 典型值 |
|---|---|---|
max_delay | 网络缓冲阈值 | 3 秒 |
probesize | 格式探测数据量 | 5MB |
rtsp_transport | 底层传输协议 | tcp |
reconnect_on_net_error | 网络错误重连 | 1(启用) |
错误处理
- 网络中断:自动重连(需设置
reconnect标志) - 解码错误:跳过损坏帧,记录
AVERROR(EAGAIN) - 同步偏差:动态调整 $ \Delta t = \text{audio_pts} - \text{video_pts} $
注意事项
- 使用
av_dict_set(&options, "timeout", "5000000", 0)设置超时(单位 μs)- 实时流需启用低延迟模式:
av_dict_set(&options, "fflags", "nobuffer", 0)- 结束时释放资源:
avformat_close_input()→avcodec_free_context()
FFmpeg 播放 HTTP 视频流:数据读取与处理全流程
FFmpeg 播放 HTTP 视频流涉及多个关键阶段,以下是完整的处理流程:
1. 协议层处理
- 网络连接
通过libavformat建立 HTTP/TCP 连接,发送请求头:
GET /video.mp4 HTTP/1.1
支持断点续传(Range: bytes=0-)和分块传输编码(Transfer-Encoding: chunked)。 - 数据接收
循环接收数据包,存储到内部缓冲区(默认 4KB),通过环形队列管理网络 I/O。
2. 解封装(Demuxing)
- 格式探测
根据文件签名(如ftyp盒子)判断容器格式(MP4/FLV/TS)。 - 提取流信息
解析音视频元数据:
输出流参数:编码类型、分辨率、时间基 $\left( \frac{1}{90000} \right)$ 等。AVFormatContext *fmt_ctx; avformat_open_input(&fmt_ctx, "http://example.com/video.mp4", NULL, NULL); avformat_find_stream_info(fmt_ctx, NULL);
3. 解码准备
- 选择解码器
根据AVCodecParameters匹配解码器(如 H.264 →libx264,AAC →aac):AVCodec *codec = avcodec_find_decoder(stream->codecpar->codec_id); AVCodecContext *codec_ctx = avcodec_alloc_context3(codec); avcodec_parameters_to_context(codec_ctx, stream->codecpar); avcodec_open2(codec_ctx, codec, NULL);
4. 数据读取循环
graph LR
A[av_read_frame] --> B[获取 AVPacket]
B --> C{视频流?}
C -->|是| D[视频解码队列]
C -->|否| E[音频解码队列]
D --> F[avcodec_send_packet]
E --> F
F --> G[avcodec_receive_frame]
G --> H[输出 AVFrame]
5. 解码与同步
- 视频解码
将AVPacket送入解码器,输出AVFrame的 YUV 数据: $$ \text{YUV} \rightarrow \begin{bmatrix} Y & U \ V & \end{bmatrix} $$ - 音频解码
输出 PCM 采样数据:$ \text{PCM} = \sum_{n=0}^{N-1} A \sin(2\pi f n / f_s) $ - 同步控制
基于时间戳 $\text{PTS} = \text{base_time} \times \text{time_base}$ 和主时钟(通常以音频为基准)进行 AV 同步。
6. 渲染输出
- 视频渲染
通过sws_scale()转换 YUV 到目标格式(如 RGB),送显。 - 音频播放
通过swr_convert()重采样,写入声卡缓冲区。
关键参数调优
| 参数 | 作用 | 典型值 |
|---|---|---|
max_delay | 网络缓冲阈值 | 3 秒 |
probesize | 格式探测数据量 | 5MB |
rtsp_transport | 底层传输协议 | tcp |
reconnect_on_net_error | 网络错误重连 | 1(启用) |
错误处理
- 网络中断:自动重连(需设置
reconnect标志) - 解码错误:跳过损坏帧,记录
AVERROR(EAGAIN) - 同步偏差:动态调整 $ \Delta t = \text{audio_pts} - \text{video_pts} $
注意事项
- 使用
av_dict_set(&options, "timeout", "5000000", 0)设置超时(单位 μs)- 实时流需启用低延迟模式:
av_dict_set(&options, "fflags", "nobuffer", 0)- 结束时释放资源:
avformat_close_input()→avcodec_free_context()
更多推荐


所有评论(0)