From: Stefano Sabatini <stefasab@gmail.com> To: FFmpeg development discussions and patches <ffmpeg-devel@ffmpeg.org> Cc: Stefano Sabatini <stefasab@gmail.com> Subject: [FFmpeg-devel] [PATCH 2/3] lavf/mkvtimestamp_v2: review implementation to match mkvextract behavior Date: Sat, 20 Apr 2024 13:48:34 +0200 Message-ID: <20240420114835.35645-3-stefasab@gmail.com> (raw) In-Reply-To: <20240420114835.35645-1-stefasab@gmail.com> Harmonize internal implementation with the mkvextract behavior: - print PTS in place of DTS values - ignore NOPTS values - sort PTS values --- libavformat/mkvtimestamp_v2.c | 69 +++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 4 deletions(-) diff --git a/libavformat/mkvtimestamp_v2.c b/libavformat/mkvtimestamp_v2.c index 1eb2daf10a..c6446ed489 100644 --- a/libavformat/mkvtimestamp_v2.c +++ b/libavformat/mkvtimestamp_v2.c @@ -22,30 +22,91 @@ #include "avformat.h" #include "internal.h" #include "mux.h" +#include "libavutil/qsort.h" + +#define PTSS_MAX_SIZE 128 +#define PTSS_HALF_SIZE (PTSS_MAX_SIZE >> 1) + +struct MkvTimestampContext { + int64_t ptss[PTSS_MAX_SIZE]; + size_t ptss_size; +}; static int write_header(AVFormatContext *s) { - static const char *header = "# timecode format v2\n"; + static const char *header = "# timestamp format v2\n"; avio_write(s->pb, header, strlen(header)); avpriv_set_pts_info(s->streams[0], 64, 1, 1000); + return 0; } +static int cmp_int64(const void *p1, const void *p2) +{ + int64_t left = *(const int64_t *)p1; + int64_t right = *(const int64_t *)p2; + return FFDIFFSIGN(left, right); +} + static int write_packet(AVFormatContext *s, AVPacket *pkt) { char buf[256]; + int i; + struct MkvTimestampContext *m = s->priv_data; + if (pkt->stream_index) av_log(s, AV_LOG_WARNING, "More than one stream unsupported\n"); - snprintf(buf, sizeof(buf), "%" PRId64 "\n", pkt->dts); - avio_write(s->pb, buf, strlen(buf)); + + if (pkt->pts == AV_NOPTS_VALUE) { + av_log(s, AV_LOG_WARNING, "Found PTS with no value, ignored\n"); + return 0; + } + + if (m->ptss_size > PTSS_MAX_SIZE) { + // sort all PTSs + AV_QSORT(m->ptss, PTSS_MAX_SIZE, int64_t, cmp_int64); + + // write only the first half and copy the second half to the + // beginning of the array + for (i = 0; i < PTSS_HALF_SIZE; i++) { + snprintf(buf, sizeof(buf), "%" PRId64 "\n", m->ptss[i]); + avio_write(s->pb, buf, strlen(buf)); + m->ptss[i] = m->ptss[i + PTSS_HALF_SIZE]; + } + + m->ptss_size = PTSS_HALF_SIZE; + } else { + m->ptss[m->ptss_size++] = pkt->pts; + } + + return 0; +} + +static int write_trailer(struct AVFormatContext *s) +{ + struct MkvTimestampContext *m = s->priv_data; + char buf[256]; + int i; + + // sort all PTSs + AV_QSORT(m->ptss, m->ptss_size, int64_t, cmp_int64); + + /* flush remaining timestamps */ + for (i = 0; i < m->ptss_size; i++) { + snprintf(buf, sizeof(buf), "%" PRId64 "\n", m->ptss[i]); + avio_write(s->pb, buf, strlen(buf)); + } + return 0; } const FFOutputFormat ff_mkvtimestamp_v2_muxer = { .p.name = "mkvtimestamp_v2", - .p.long_name = NULL_IF_CONFIG_SMALL("mkvtoolnix v2 timecode format"), + .p.long_name = NULL_IF_CONFIG_SMALL("mkvtoolnix v2 timestamp format"), .p.audio_codec = AV_CODEC_ID_NONE, .p.video_codec = AV_CODEC_ID_RAWVIDEO, .write_header = write_header, .write_packet = write_packet, + .write_trailer = write_trailer, + .priv_data_size = sizeof(struct MkvTimestampContext), }; -- 2.34.1 _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
next prev parent reply other threads:[~2024-04-20 11:49 UTC|newest] Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top 2024-04-20 11:48 [FFmpeg-devel] lavf/mkvtimestamp_v2: review mkvtimestamp_v2 implementation, add documentation Stefano Sabatini 2024-04-20 11:48 ` [FFmpeg-devel] [PATCH 1/3] lavf/mkvtimestamp_v2: use name in place of description in long name Stefano Sabatini 2024-04-20 11:48 ` Stefano Sabatini [this message] 2024-04-20 13:18 ` [FFmpeg-devel] [PATCH 2/3] lavf/mkvtimestamp_v2: review implementation to match mkvextract behavior Andreas Rheinhardt 2024-04-20 16:00 ` Stefano Sabatini 2024-04-20 16:47 ` Andreas Rheinhardt 2024-04-20 16:56 ` Stefano Sabatini 2024-04-22 13:55 ` Stefano Sabatini 2024-04-22 16:48 ` Andreas Rheinhardt 2024-04-20 11:48 ` [FFmpeg-devel] [PATCH 3/3] doc/muxers: add mkvtimestamp_v2 Stefano Sabatini 2024-04-20 11:53 ` Stefano Sabatini
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20240420114835.35645-3-stefasab@gmail.com \ --to=stefasab@gmail.com \ --cc=ffmpeg-devel@ffmpeg.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
Git Inbox Mirror of the ffmpeg-devel mailing list - see https://ffmpeg.org/mailman/listinfo/ffmpeg-devel This inbox may be cloned and mirrored by anyone: git clone --mirror https://master.gitmailbox.com/ffmpegdev/0 ffmpegdev/git/0.git # If you have public-inbox 1.1+ installed, you may # initialize and index your mirror using the following commands: public-inbox-init -V2 ffmpegdev ffmpegdev/ https://master.gitmailbox.com/ffmpegdev \ ffmpegdev@gitmailbox.com public-inbox-index ffmpegdev Example config snippet for mirrors. AGPL code for this site: git clone https://public-inbox.org/public-inbox.git