Как установить pts, dts и продолжительность в библиотеке ffmpeg? - PullRequest
0 голосов
/ 21 января 2019

Я хочу упаковать несколько сжатых видео пакетов (h.264) в контейнер ".mp4". Одно слово, Muxing, без декодирования и без кодирования. И я понятия не имею, как установить очки, точки и продолжительность.

  1. Я получаю пакеты с библиотекой "pcap".
  2. Я удалил заголовки, прежде чем показываются сжатые видеоданные. например Ethernet, VLAN.
  3. Я собирал данные до одного кадра и декодировал их для получения информации данных. например ширина высота. (Я не уверен, что это необходимо)
  4. Я инициализировал контекст вывода, поток и контекст кодека.
  5. Я снова начал получать пакеты с библиотекой "pcap". (теперь для муксинга)
  6. Я сделал один кадр и поместил эти данные в структуру AVPacket.
  7. Я пытаюсь установить PTS, DTS и продолжительность. (Я думаю, что здесь не та часть, но не уверен)

* 7-1. В первом кадре я сэкономил время (мсек) с помощью структуры заголовка пакета.

* 7-2. всякий раз, когда я делал один кадр, я устанавливал параметры следующим образом: PTS (текущее время - время начала), DTS (то же значение PTS), длительность (текущее PTS - до PTS)

Я думаю, что есть какая-то ошибка, потому что:

  1. Я не знаю, как далеко подходит точка для очков от очков.

  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, который можно воспроизводить.

...