gpt4 book ai didi

c++ - libvlc ffmpeg : No seek in mpegts h264 stream

转载 作者:行者123 更新时间:2023-12-04 23:27:32 28 4
gpt4 key购买 nike

我正在使用 ffmpeg 记录来自 GDI(Windows 屏幕录像机)的视频输入,以便稍后使用 VLC(通过 ActiveX 插件)+ ffmpeg 对其进行解码。

现在在视频中搜索无法通过插件在 VLC 中工作(这很关键)。 VLC 播放器本身提供搜索,但它更像是字节位置搜索(在比其他帧大的 I 帧上,它在水平滚动上的步长更大,也没有时间戳)。

使用下一个默认值打开编码器:

avformat_alloc_output_context2(&outputContext, NULL, "mpegts", "test.mpg");
outputFormat = outputContext->oformat;
encoder = avcodec_find_encoder(AV_CODEC_ID_H264);
outputStream = avformat_new_stream(outputContext, encoder);
outputStream->id = outputContext->nb_streams - 1;
encoderContext = outputStream->codec;
encoderContext->bit_rate = bitrate; // 800000 by default
encoderContext->rc_max_rate = bitrate;
encoderContext->width = imageWidth; // 1920
encoderContext->height = imageHeight; // 1080
encoderContext->time_base.num = 1;
encoderContext->time_base.den = fps; // 25 by default
encoderContext->gop_size = fps;
encoderContext->keyint_min = fps;
encoderContext->max_b_frames = 0;
encoderContext->pix_fmt = AV_PIX_FMT_YUV420P;
outputStream->time_base = encoderContext->time_base;
avcodec_open2(encoderContext, encoder, NULL);

录音是这样完成的:
// my impl of GDI recorder, returning AVFrame with only data and linesize filled.
AVFrame* tmp_frame = impl_->recorder->acquireFrame();

// converting RGB -> YUV420
sws_scale(impl_->scaleContext, tmp_frame->data, tmp_frame->linesize, 0, impl_->frame->height, impl_->frame->data, impl_->frame->linesize);

// pts variable is calculated by using QueryPerformanceCounter form WinAPI. It is strictly increasing
impl_->frame->pts = pts;

avcodec_encode_video2(impl_->encoderContext, impl_->packet, impl_->frame, &out_size);

if (out_size) {
impl_->packet->pts = pts;
impl_->packet->dts = pts;
impl_->packet->duration = 1; // here it is! It is set but has no effect
av_packet_rescale_ts(impl_->packet, impl_->encoderContext->time_base, impl_->outputStream->time_base);
// here pts = 3600*pts, dts = 3600*pts, duration = 3600 what I consider to be legit in terms of milliseconds
impl_->packet->stream_index = impl_->outputStream->index;
av_interleaved_write_frame(impl_->outputContext, impl_->packet);
av_packet_unref(impl_->packet);
out_size = 0;
}

ffprobe 正在提供有关帧的下一个信息:
[FRAME]
media_type=video
stream_index=0
key_frame=1
pkt_pts=3600
pkt_pts_time=0:00:00.040000
pkt_dts=3600
pkt_dts_time=0:00:00.040000
best_effort_timestamp=3600
best_effort_timestamp_time=0:00:00.040000
pkt_duration=N/A
pkt_duration_time=N/A
pkt_pos=564
pkt_size=97.018555 Kibyte
width=1920
height=1080
pix_fmt=yuv420p
sample_aspect_ratio=N/A
pict_type=I
coded_picture_number=0
display_picture_number=0
interlaced_frame=0
top_field_first=0
repeat_pict=0
[/FRAME]

我相信问题出在 pkt_duration变量,虽然它是设置的。
我在录制时做错了什么,所以我无法在视频中寻找?

附言在其他视频(也是 h264)上,正在寻找在 ActiveX VLC 插件中工作。

最佳答案

绝对错误的是:

impl_->packet->pts = pts;
impl_->packet->dts = pts;

PTS和DTS不相等!如果您只有 I 帧,则可能是这样,但这里不是这种情况。此外,您的评论说: pts 变量使用 QueryPerformanceCounter 计算窗体 WinAPI .如果您的帧速率是恒定的,我相信它是恒定的,那么您不需要 QueryPerformanceCounter API。 PTS 通常以 90kHz 为单位。以 90kHz 表示的 1 帧的持续时间计算如下:

90000 x denominator / numerator



如果 fps 为 25,则分子为 25,分母为 1。对于 29.97 fps,分子为 30000,分母为 1001。每个新帧的 PTS 应增加该数量(除非您有丢帧)。关于 DTS,编码器应提供该值。

关于c++ - libvlc ffmpeg : No seek in mpegts h264 stream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38572872/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com