如何在ffmpeg库中设置pts,dts和持续时间?

时间:2019-01-21 02:10:22

标签: c ffmpeg duration dts pts

我想将一些压缩的视频数据包(h.264)打包到“ .mp4”容器中。 一字,木星,无解码,无编码。 而且我不知道如何设置pts,dts和持续时间。

  1. 我通过“ pcap”库获取数据包。
  2. 我在显示压缩视频数据之前删除了标头。例如以太网,VLAN。
  3. 我收集数据直到一帧,然后解码以获取数据信息。例如宽度,高度。 (我不确定是否有必要)
  4. 我初始化了输出上下文,流和编解码器上下文。
  5. 我再次开始使用“ pcap”库接收数据包。 (现在用于混合)
  6. 我制作了一帧并将数据放入AVPacket结构中。
  7. 我尝试设置PTS,DTS和持续时间。 (我认为这是错误的部分,但不确定)

* 7-1。在第一帧,我用数据包头结构节省了时间(毫秒)。

* 7-2。每当制作一帧图像时,我都会设置如下参数:PTS(当前时间-开始时间),DTS(相同的PTS值),持续时间(当前PTS-在PTS之前)

我认为它有一些错误,因为:

  1. 我不知道距离pts的dts多远。

  2. 至少,我认为持续时间是指从现在到下一帧显示此帧的时间,因此它应该具有值(下一PTS-当前PTS),但是我当时不知道下一PTS的值

它只有I型框架。

// make input context for decoding

AVFormatContext *&ic = gInputContext;

ic = avformat_alloc_context();

AVCodec *cd = avcodec_find_decoder(AV_CODEC_ID_H264);

AVStream *st = avformat_new_stream(ic, cd);

AVCodecContext *cc = st->codec;

avcodec_open2(cc, cd, NULL);

// make packet and decode it after collect packets is be one frame

gPacket.stream_index = 0;

gPacket.size    = gPacketLength[0];

gPacket.data    = gPacketData[0];

gPacket.pts     = AV_NOPTS_VALUE;

gPacket.dts     = AV_NOPTS_VALUE;

gPacket.flags   = AV_PKT_FLAG_KEY;

avcodec_decode_video2(cc, gFrame, &got_picture, &gPacket);

// I checked automatically it initialized after "avcodec_decode_video2"

// put some info that I know that not initialized

cc->time_base.den   = 90000;

cc->time_base.num   = 1;

cc->bit_rate    = 2500000;

cc->gop_size    = 1;

// make output context with input context

AVFormatContext *&oc = gOutputContext;

avformat_alloc_output_context2(&oc, NULL, NULL, filename);

AVFormatContext *&ic = gInputContext;

AVStream *ist = ic->streams[0];

AVCodecContext *&icc = ist->codec;

AVStream *ost = avformat_new_stream(oc, icc->codec);

AVCodecContext *occ = ost->codec;

avcodec_copy_context(occ, icc);

occ->flags |= CODEC_FLAG_GLOBAL_HEADER;

avio_open(&(oc->pb), filename, AVIO_FLAG_WRITE);

// repeated part for muxing

AVRational Millisecond = { 1, 1000 };

gPacket.stream_index = 0;

gPacket.data = gPacketData[0];

gPacket.size = gPacketLength[0];

gPacket.pts = av_rescale_rnd(pkthdr->ts.tv_sec * 1000 /

    + pkthdr->ts.tv_usec / 1000 /

    - gStartTime, Millisecond.den, ost->time_base.den, /

    (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));

gPacket.dts = gPacket.pts;

gPacket.duration = gPacket.pts - gPrev;

gPacket.flags = AV_PKT_FLAG_KEY;

gPrev = gPacket.pts;

av_interleaved_write_frame(gOutputContext, &gPacket);

预期和实际结果是可以播放的.mp4视频文件。

0 个答案:

没有答案