0

我想将一些压缩视频包(h.264)打包到“.mp4”容器中。一个字,Muxing,不解码不编码。而且我不知道如何设置 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 视频文件。

4

0 回答 0