[FFmpeg-devel] [PATCH] lavf/mux: bypass interleave delay early when waiting on subtitle streams
This avoids long delays when converting live streams that have sparse subtitles --- libavformat/avformat.h | 9 + libavformat/mux.c | 25 + libavformat/options_table.h | 1 + libavformat/version.h | 2 +- 4 files changed, 32 insertions(+), 5 deletions(-) diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 9b9b634ec3..da7e5755e8 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1957,6 +1957,15 @@ typedef struct AVFormatContext { * - decoding: set by user */ int max_probe_packets; + +/** + * Maximum buffering duration for interleaving sparse streams. + * + * @see max_interleave_delta + * + * Applies only to subtitle and data streams. + */ +int64_t max_sparse_interleave_delta; } AVFormatContext; #if FF_API_FORMAT_GET_SET diff --git a/libavformat/mux.c b/libavformat/mux.c index d88746e8c5..f2f272cf65 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -1033,6 +1033,7 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, AVPacketList *pktl; int stream_count = 0; int noninterleaved_count = 0; +int sparse_count = 0; int i, ret; int eof = flush; @@ -1044,6 +1045,9 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, for (i = 0; i < s->nb_streams; i++) { if (s->streams[i]->last_in_packet_buffer) { ++stream_count; +} else if (s->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE || + s->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_DATA) { +++sparse_count; } else if (s->streams[i]->codecpar->codec_type != AVMEDIA_TYPE_ATTACHMENT && s->streams[i]->codecpar->codec_id != AV_CODEC_ID_VP8 && s->streams[i]->codecpar->codec_id != AV_CODEC_ID_VP9) { @@ -1054,10 +1058,12 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, if (s->internal->nb_interleaved_streams == stream_count) flush = 1; -if (s->max_interleave_delta > 0 && -s->internal->packet_buffer && +if (s->internal->packet_buffer && !flush && -s->internal->nb_interleaved_streams == stream_count+noninterleaved_count +((s->max_interleave_delta > 0 && + s->internal->nb_interleaved_streams == stream_count+noninterleaved_count+sparse_count) || + (s->max_sparse_interleave_delta > 0 && + s->internal->nb_interleaved_streams == stream_count+sparse_count)) ) { AVPacket *top_pkt = &s->internal->packet_buffer->pkt; int64_t delta_dts = INT64_MIN; @@ -1078,12 +1084,23 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, delta_dts = FFMAX(delta_dts, last_dts - top_dts); } -if (delta_dts > s->max_interleave_delta) { +if (s->max_interleave_delta > 0 && +delta_dts > s->max_interleave_delta && +s->internal->nb_interleaved_streams == stream_count+noninterleaved_count+sparse_count) { av_log(s, AV_LOG_DEBUG, "Delay between the first packet and last packet in the " "muxing queue is %"PRId64" > %"PRId64": forcing output\n", delta_dts, s->max_interleave_delta); flush = 1; +} else if (s->max_sparse_interleave_delta > 0 && + delta_dts > s->max_sparse_interleave_delta && + s->internal->nb_interleaved_streams == stream_count+sparse_count) { +av_log(s, AV_LOG_DEBUG, + "Delay between the first packet and last packet in the " + "muxing queue is %"PRId64" > %"PRId64" and all delayed " + "streams are sparse: forcing output\n", + delta_dts, s->max_sparse_interleave_delta); +flush = 1; } } diff --git a/libavformat/options_table.h b/libavformat/options_table.h index e26b512440..db04f970e2 100644 --- a/libavformat/options_table.h +++ b/libavformat/options_table.h @@ -91,6 +91,7 @@ static const AVOption avformat_options[] = { {"metadata_header_padding", "set number of bytes to be written as padding in a metadata header", OFFSET(metadata_header_padding), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, E}, {"output_ts_offset", "set output timestamp offset", OFFSET(output_ts_offset), AV_OPT_TYPE_DURATION, {.i64 = 0}, -INT64_MAX, INT64_MAX, E}, {"max_interleave_delta", "maximum buffering duration for interleaving", OFFSET(max_interleave_delta), AV_OPT_TYPE_INT64, { .i64 = 1000 }, 0, INT64_MAX, E }, +{"max_sparse_interleave_delta", "maximum buffering duration for interleaving sparse streams", OFFSET(max_sparse_interleave_delta), AV_OPT_TYPE_INT64, { .i64 = 100 }, 0, INT64_MAX, E }, {"f_strict", "how strictly to follow the standards (deprecated; use strict, save via avconv)", OFFSET(strict_std_compliance), AV_OPT_
Re: [FFmpeg-devel] [PATCH] lavf/mux: bypass interleave delay early when waiting on subtitle streams
> On Mar 12, 2020, at 02:51, Andreas Rheinhardt > wrote: > > rcombs: >> This avoids long delays when converting live streams that have sparse >> subtitles >> --- >> libavformat/avformat.h | 9 + >> libavformat/mux.c | 25 + >> libavformat/options_table.h | 1 + >> libavformat/version.h | 2 +- >> 4 files changed, 32 insertions(+), 5 deletions(-) >> >> diff --git a/libavformat/avformat.h b/libavformat/avformat.h >> index 9b9b634ec3..da7e5755e8 100644 >> --- a/libavformat/avformat.h >> +++ b/libavformat/avformat.h >> @@ -1957,6 +1957,15 @@ typedef struct AVFormatContext { >> * - decoding: set by user >> */ >> int max_probe_packets; >> + >> +/** >> + * Maximum buffering duration for interleaving sparse streams. >> + * >> + * @see max_interleave_delta >> + * >> + * Applies only to subtitle and data streams. >> + */ >> +int64_t max_sparse_interleave_delta; >> } AVFormatContext; >> >> #if FF_API_FORMAT_GET_SET >> diff --git a/libavformat/mux.c b/libavformat/mux.c >> index d88746e8c5..f2f272cf65 100644 >> --- a/libavformat/mux.c >> +++ b/libavformat/mux.c >> @@ -1033,6 +1033,7 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, >> AVPacket *out, >> AVPacketList *pktl; >> int stream_count = 0; >> int noninterleaved_count = 0; >> +int sparse_count = 0; >> int i, ret; >> int eof = flush; >> >> @@ -1044,6 +1045,9 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, >> AVPacket *out, >> for (i = 0; i < s->nb_streams; i++) { >> if (s->streams[i]->last_in_packet_buffer) { >> ++stream_count; >> +} else if (s->streams[i]->codecpar->codec_type == >> AVMEDIA_TYPE_SUBTITLE || >> + s->streams[i]->codecpar->codec_type == >> AVMEDIA_TYPE_DATA) { >> +++sparse_count; >> } else if (s->streams[i]->codecpar->codec_type != >> AVMEDIA_TYPE_ATTACHMENT && >>s->streams[i]->codecpar->codec_id != AV_CODEC_ID_VP8 && >>s->streams[i]->codecpar->codec_id != AV_CODEC_ID_VP9) { >> @@ -1054,10 +1058,12 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, >> AVPacket *out, >> if (s->internal->nb_interleaved_streams == stream_count) >> flush = 1; >> >> -if (s->max_interleave_delta > 0 && >> -s->internal->packet_buffer && >> +if (s->internal->packet_buffer && >> !flush && >> -s->internal->nb_interleaved_streams == >> stream_count+noninterleaved_count >> +((s->max_interleave_delta > 0 && >> + s->internal->nb_interleaved_streams == >> stream_count+noninterleaved_count+sparse_count) || >> + (s->max_sparse_interleave_delta > 0 && >> + s->internal->nb_interleaved_streams == stream_count+sparse_count)) > > If max_sparse_interleave_delta has its default value and > max_interleave_delta has been explicitly set to zero (thereby > indicating that one should wait until one has one packet for each > stream), the check used here might output a packet even if one does > not have packets for some of the sparse streams. This is in > contradiction to the documentation of max_interleave_delta. Hm, is that any different from how this changes the default behavior? Maybe I should just clarify in the docs? > > (Nit: Use stream_count+sparse_count+noninterleaved_count.) Sure. > >> ) { >> AVPacket *top_pkt = &s->internal->packet_buffer->pkt; >> int64_t delta_dts = INT64_MIN; >> @@ -1078,12 +1084,23 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, >> AVPacket *out, >> delta_dts = FFMAX(delta_dts, last_dts - top_dts); >> } >> >> -if (delta_dts > s->max_interleave_delta) { >> +if (s->max_interleave_delta > 0 && >> +delta_dts > s->max_interleave_delta && >> +s->internal->nb_interleaved_streams == >> stream_count+noninterleaved_count+sparse_count) { >> av_log(s, AV_LOG_DEBUG, >>"Delay between the first packet and last packet in the " >>"muxing queue is %"PRId64" > %"PRId64"
[FFmpeg-devel] [PATCH] lavf/dashdec: support larger manifests
--- libavformat/dashdec.c | 29 +++-- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 5ba7feb245..bde4b0846d 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -29,6 +29,8 @@ #include "dash.h" #define INITIAL_BUFFER_SIZE 32768 +#define MAX_MANIFEST_SIZE 50 * 1024 +#define DEFAULT_MANIFEST_SIZE 8 * 1024 struct fragment { int64_t url_offset; @@ -1220,7 +1222,7 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) int close_in = 0; uint8_t *new_url = NULL; int64_t filesize = 0; -char *buffer = NULL; +AVBPrint buf; AVDictionary *opts = NULL; xmlDoc *doc = NULL; xmlNodePtr root_element = NULL; @@ -1254,24 +1256,23 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) } filesize = avio_size(in); -if (filesize <= 0) { -filesize = 8 * 1024; +if (filesize > MAX_MANIFEST_SIZE) { +av_log(s, AV_LOG_ERROR, "Manifest too large: %"PRId64"\n", filesize); +return AVERROR_INVALIDDATA; } -buffer = av_mallocz(filesize); -if (!buffer) { -av_free(c->base_url); -return AVERROR(ENOMEM); -} +av_bprint_init(&buf, (filesize > 0) ? filesize + 1 : DEFAULT_MANIFEST_SIZE, AV_BPRINT_SIZE_UNLIMITED); -filesize = avio_read(in, buffer, filesize); -if (filesize <= 0) { -av_log(s, AV_LOG_ERROR, "Unable to read to offset '%s'\n", url); -ret = AVERROR_INVALIDDATA; +if ((ret = avio_read_to_bprint(in, &buf, MAX_MANIFEST_SIZE)) < 0 || +!avio_feof(in) || +(filesize = buf.len) == 0) { +av_log(s, AV_LOG_ERROR, "Unable to read to manifest '%s'\n", url); +if (ret == 0) +ret = AVERROR_INVALIDDATA; } else { LIBXML_TEST_VERSION -doc = xmlReadMemory(buffer, filesize, c->base_url, NULL, 0); +doc = xmlReadMemory(buf.str, filesize, c->base_url, NULL, 0); root_element = xmlDocGetRootElement(doc); node = root_element; @@ -1394,7 +1395,7 @@ cleanup: } av_free(new_url); -av_free(buffer); +av_bprint_finalize(&buf, NULL); if (close_in) { avio_close(in); } -- 2.24.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 3/3] lavf/dashdec: avoid reading the first data segment in read_header
This reduces the number of requests that have to be made during startup. --- libavformat/dashdec.c | 41 ++--- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index ec2aadcee3..1bd070c7cb 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -1798,6 +1798,19 @@ static int read_data(void *opaque, uint8_t *buf, int buf_size) DASHContext *c = v->parent->priv_data; restart: +/* load/update Media Initialization Section, if any */ +if ((ret = update_init_section(v)) < 0) +goto end; + +if (v->init_sec_buf_read_offset < v->init_sec_data_len) { +/* Push init section out first before first actual fragment */ +int copy_size = FFMIN(v->init_sec_data_len - v->init_sec_buf_read_offset, buf_size); +memcpy(buf, v->init_sec_buf, copy_size); +v->init_sec_buf_read_offset += copy_size; +ret = copy_size; +goto end; +} + if (!v->input) { free_fragment(&v->cur_seg); v->cur_seg = get_current_fragment(v); @@ -1806,11 +1819,6 @@ restart: goto end; } -/* load/update Media Initialization Section, if any */ -ret = update_init_section(v); -if (ret) -goto end; - ret = open_input(c, v, v->cur_seg); if (ret < 0) { if (ff_check_interrupt(c->interrupt_callback)) { @@ -1823,15 +1831,6 @@ restart: } } -if (v->init_sec_buf_read_offset < v->init_sec_data_len) { -/* Push init section out first before first actual fragment */ -int copy_size = FFMIN(v->init_sec_data_len - v->init_sec_buf_read_offset, buf_size); -memcpy(buf, v->init_sec_buf, copy_size); -v->init_sec_buf_read_offset += copy_size; -ret = copy_size; -goto end; -} - /* check the v->cur_seg, if it is null, get current and double check if the new v->cur_seg*/ if (!v->cur_seg) { v->cur_seg = get_current_fragment(v); @@ -1940,10 +1939,19 @@ static int reopen_demux_for_component(AVFormatContext *s, struct representation if ((ret = ff_copy_whiteblacklists(pls->ctx, s)) < 0) goto fail; + +if (pls->init_sec_data_len <= 0) { +/* load/update Media Initialization Section, if any */ +if ((ret = update_init_section(pls)) < 0) +goto fail; +} + pls->ctx->flags = AVFMT_FLAG_CUSTOM_IO; pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4; +if (pls->init_sec_data_len > 0) +pls->ctx->probesize = FFMIN(pls->ctx->probesize, pls->init_sec_data_len); pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE; -ret = av_probe_input_buffer(&pls->pb, &in_fmt, "", NULL, 0, 0); +ret = av_probe_input_buffer(&pls->pb, &in_fmt, "", NULL, 0, pls->ctx->probesize); if (ret < 0) { av_log(s, AV_LOG_ERROR, "Error when loading first fragment, playlist %d\n", (int)pls->rep_idx); avformat_free_context(pls->ctx); @@ -1954,6 +1962,9 @@ static int reopen_demux_for_component(AVFormatContext *s, struct representation pls->ctx->pb = &pls->pb; pls->ctx->io_open = nested_io_open; +if (pls->init_sec_data_len > 0) +av_dict_set_int(&in_fmt_opts, "header_size", pls->init_sec_data_len, 0); + // provide additional information from mpd if available ret = avformat_open_input(&pls->ctx, "", in_fmt, &in_fmt_opts); //pls->init_section->url av_dict_free(&in_fmt_opts); -- 2.26.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/3] lavf/format: handle max probe buffer sizes <2048
This can be useful in chained demuxers, where the header size is known. --- libavformat/format.c | 7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/libavformat/format.c b/libavformat/format.c index c47490c8eb..7309b0019b 100644 --- a/libavformat/format.c +++ b/libavformat/format.c @@ -231,11 +231,6 @@ int av_probe_input_buffer2(AVIOContext *pb, ff_const59 AVInputFormat **fmt, if (!max_probe_size) max_probe_size = PROBE_BUF_MAX; -else if (max_probe_size < PROBE_BUF_MIN) { -av_log(logctx, AV_LOG_ERROR, - "Specified probe size value %u cannot be < %u\n", max_probe_size, PROBE_BUF_MIN); -return AVERROR(EINVAL); -} if (offset >= max_probe_size) return AVERROR(EINVAL); @@ -251,7 +246,7 @@ int av_probe_input_buffer2(AVIOContext *pb, ff_const59 AVInputFormat **fmt, } } -for (probe_size = PROBE_BUF_MIN; probe_size <= max_probe_size && !*fmt; +for (probe_size = FFMIN(PROBE_BUF_MIN, max_probe_size); probe_size <= max_probe_size && !*fmt; probe_size = FFMIN(probe_size << 1, FFMAX(max_probe_size, probe_size + 1))) { score = probe_size < max_probe_size ? AVPROBE_SCORE_RETRY : 0; -- 2.26.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/3] lavf/movdec: allow setting the header size in advance
This is useful for chained demuxers, to avoid reading past the end of a shared initialization segment and into the first data segment unnecessarily. --- libavformat/isom.h | 1 + libavformat/mov.c | 10 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/libavformat/isom.h b/libavformat/isom.h index 41a9c64c11..3479553da6 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -291,6 +291,7 @@ typedef struct MOVContext { int decryption_key_len; int enable_drefs; int32_t movie_display_matrix[3][3]; ///< display matrix from mvhd +int64_t header_size; } MOVContext; int ff_mp4_read_descr_len(AVIOContext *pb); diff --git a/libavformat/mov.c b/libavformat/mov.c index e11c9f4457..51d3204582 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -7574,6 +7574,9 @@ static int mov_read_header(AVFormatContext *s) else atom.size = INT64_MAX; +if (mov->header_size > 0) +atom.size = mov->header_size; + /* check MOV header */ do { if (mov->moov_retry) @@ -7591,6 +7594,9 @@ static int mov_read_header(AVFormatContext *s) } av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb)); +if (mov->header_size > 0) +mov->next_root_atom = mov->header_size; + if (pb->seekable & AVIO_SEEKABLE_NORMAL) { if (mov->nb_chapter_tracks > 0 && !mov->ignore_chapters) mov_read_chapters(s); @@ -8162,7 +8168,9 @@ static const AVOption mov_options[] = { { "decryption_key", "The media decryption key (hex)", OFFSET(decryption_key), AV_OPT_TYPE_BINARY, .flags = AV_OPT_FLAG_DECODING_PARAM }, { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, FLAGS }, - +{ "header_size", "size of initial header, ", +OFFSET(header_size), AV_OPT_TYPE_INT64, {.i64 = -1}, +-1, INT64_MAX, FLAGS }, { NULL }, }; -- 2.26.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/2] compat/cuda/ptx2c: remove shell loop
This improves build times dramatically --- compat/cuda/ptx2c.sh | 8 +++- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/compat/cuda/ptx2c.sh b/compat/cuda/ptx2c.sh index 0750e7a3b7..435a9b4b6c 100755 --- a/compat/cuda/ptx2c.sh +++ b/compat/cuda/ptx2c.sh @@ -27,10 +27,8 @@ IN="$2" NAME="$(basename "$IN" | sed 's/\..*//')" printf "const char %s_ptx[] = \\" "$NAME" > "$OUT" -while IFS= read -r LINE -do -printf "\n\t\"%s\\\n\"" "$(printf "%s" "$LINE" | sed -e 's/\r//g' -e 's/["\\]/\\&/g')" >> "$OUT" -done < "$IN" -printf ";\n" >> "$OUT" +echo >> "$OUT" +sed -e 's/\r//g' -e 's/["\\]/\\&/g' -e 's/^[[:space:]]*/\t"/' -e 's/$/\\n"/' < "$IN" >> "$OUT" +echo ";" >> "$OUT" exit 0 -- 2.26.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/2] compat/cuda/ptx2c: fix BSD sed compatibility
This fixes cross-compiling from macOS to other platforms --- compat/cuda/ptx2c.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compat/cuda/ptx2c.sh b/compat/cuda/ptx2c.sh index 435a9b4b6c..c41875a2d4 100755 --- a/compat/cuda/ptx2c.sh +++ b/compat/cuda/ptx2c.sh @@ -28,7 +28,7 @@ NAME="$(basename "$IN" | sed 's/\..*//')" printf "const char %s_ptx[] = \\" "$NAME" > "$OUT" echo >> "$OUT" -sed -e 's/\r//g' -e 's/["\\]/\\&/g' -e 's/^[[:space:]]*/\t"/' -e 's/$/\\n"/' < "$IN" >> "$OUT" +sed -e $'s/\r//g' -e 's/["\\]/\\&/g' -e $'s/^[[:space:]]*/\t"/' -e 's/$/\\n"/' < "$IN" >> "$OUT" echo ";" >> "$OUT" exit 0 -- 2.26.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] compat/cuda/ptx2c: remove shell loop; fix BSD sed compat
This improves build times dramatically, and fixes building on macOS --- compat/cuda/ptx2c.sh | 8 +++- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/compat/cuda/ptx2c.sh b/compat/cuda/ptx2c.sh index 0750e7a3b7..c41875a2d4 100755 --- a/compat/cuda/ptx2c.sh +++ b/compat/cuda/ptx2c.sh @@ -27,10 +27,8 @@ IN="$2" NAME="$(basename "$IN" | sed 's/\..*//')" printf "const char %s_ptx[] = \\" "$NAME" > "$OUT" -while IFS= read -r LINE -do -printf "\n\t\"%s\\\n\"" "$(printf "%s" "$LINE" | sed -e 's/\r//g' -e 's/["\\]/\\&/g')" >> "$OUT" -done < "$IN" -printf ";\n" >> "$OUT" +echo >> "$OUT" +sed -e $'s/\r//g' -e 's/["\\]/\\&/g' -e $'s/^[[:space:]]*/\t"/' -e 's/$/\\n"/' < "$IN" >> "$OUT" +echo ";" >> "$OUT" exit 0 -- 2.26.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/4] lavf: matroska subtitle muxer
--- configure | 1 + libavformat/allformats.c | 1 + libavformat/matroskaenc.c | 30 ++ libavformat/version.h | 2 +- 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 8569a60bf8..9929c29006 100755 --- a/configure +++ b/configure @@ -3305,6 +3305,7 @@ ismv_muxer_select="mov_muxer" ivf_muxer_select="av1_metadata_bsf vp9_superframe_bsf" latm_muxer_select="aac_adtstoasc_bsf" matroska_audio_muxer_select="matroska_muxer" +matroska_subtitle_muxer_select="matroska_muxer" matroska_demuxer_select="iso_media riffdec" matroska_demuxer_suggest="bzlib lzo zlib" matroska_muxer_select="iso_media riffenc vp9_superframe_bsf aac_adtstoasc_bsf" diff --git a/libavformat/allformats.c b/libavformat/allformats.c index 3919c9e4c1..1bae208195 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -233,6 +233,7 @@ extern AVOutputFormat ff_md5_muxer; extern AVInputFormat ff_matroska_demuxer; extern AVOutputFormat ff_matroska_muxer; extern AVOutputFormat ff_matroska_audio_muxer; +extern AVOutputFormat ff_matroska_subtitle_muxer; extern AVInputFormat ff_mgsts_demuxer; extern AVInputFormat ff_microdvd_demuxer; extern AVOutputFormat ff_microdvd_muxer; diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 1c1ea71f59..1f7a9528de 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -2891,3 +2891,33 @@ AVOutputFormat ff_matroska_audio_muxer = { .priv_class= &mka_class, }; #endif + +#if CONFIG_MATROSKA_SUBTITLE_MUXER +static const AVClass mks_class = { +.class_name = "matroska subtitle muxer", +.item_name = av_default_item_name, +.option = options, +.version= LIBAVUTIL_VERSION_INT, +}; +AVOutputFormat ff_matroska_subtitle_muxer = { +.name = "matroska", +.long_name = NULL_IF_CONFIG_SMALL("Matroska Subtitle"), +.extensions= "mks", +.priv_data_size= sizeof(MatroskaMuxContext), +.audio_codec = AV_CODEC_ID_NONE, +.video_codec = AV_CODEC_ID_NONE, +.subtitle_codec= AV_CODEC_ID_ASS, +.init = mkv_init, +.deinit= mkv_deinit, +.write_header = mkv_write_header, +.write_packet = mkv_write_flush_packet, +.write_trailer = mkv_write_trailer, +.check_bitstream = mkv_check_bitstream, +.flags = AVFMT_GLOBALHEADER | AVFMT_TS_NONSTRICT | + AVFMT_ALLOW_FLUSH, +.codec_tag = (const AVCodecTag* const []){ + additional_subtitle_tags, 0 +}, +.priv_class= &mks_class, +}; +#endif diff --git a/libavformat/version.h b/libavformat/version.h index 493a0b337f..e0135fc7d3 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ // Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium) // Also please add any ticket numbers that you believe might be affected here #define LIBAVFORMAT_VERSION_MAJOR 58 -#define LIBAVFORMAT_VERSION_MINOR 43 +#define LIBAVFORMAT_VERSION_MINOR 44 #define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ -- 2.26.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 3/4] lavf/matroskadec: support standard (non-WebM) WebVTT formatting
Fixes ticket #5641 --- libavformat/matroska.c| 11 ++-- libavformat/matroskadec.c | 111 -- 2 files changed, 77 insertions(+), 45 deletions(-) diff --git a/libavformat/matroska.c b/libavformat/matroska.c index 7c56aba403..962fa496f4 100644 --- a/libavformat/matroska.c +++ b/libavformat/matroska.c @@ -60,16 +60,12 @@ const CodecTags ff_mkv_codec_tags[]={ {"A_VORBIS" , AV_CODEC_ID_VORBIS}, {"A_WAVPACK4" , AV_CODEC_ID_WAVPACK}, -{"D_WEBVTT/SUBTITLES" , AV_CODEC_ID_WEBVTT}, -{"D_WEBVTT/CAPTIONS", AV_CODEC_ID_WEBVTT}, -{"D_WEBVTT/DESCRIPTIONS", AV_CODEC_ID_WEBVTT}, -{"D_WEBVTT/METADATA", AV_CODEC_ID_WEBVTT}, - {"S_TEXT/UTF8" , AV_CODEC_ID_SUBRIP}, {"S_TEXT/UTF8" , AV_CODEC_ID_TEXT}, {"S_TEXT/ASCII" , AV_CODEC_ID_TEXT}, {"S_TEXT/ASS" , AV_CODEC_ID_ASS}, {"S_TEXT/SSA" , AV_CODEC_ID_ASS}, +{"S_TEXT/WEBVTT", AV_CODEC_ID_WEBVTT}, {"S_ASS", AV_CODEC_ID_ASS}, {"S_SSA", AV_CODEC_ID_ASS}, {"S_VOBSUB" , AV_CODEC_ID_DVD_SUBTITLE}, @@ -77,6 +73,11 @@ const CodecTags ff_mkv_codec_tags[]={ {"S_HDMV/PGS" , AV_CODEC_ID_HDMV_PGS_SUBTITLE}, {"S_HDMV/TEXTST", AV_CODEC_ID_HDMV_TEXT_SUBTITLE}, +{"D_WEBVTT/SUBTITLES" , AV_CODEC_ID_WEBVTT}, +{"D_WEBVTT/CAPTIONS", AV_CODEC_ID_WEBVTT}, +{"D_WEBVTT/DESCRIPTIONS", AV_CODEC_ID_WEBVTT}, +{"D_WEBVTT/METADATA", AV_CODEC_ID_WEBVTT}, + {"V_AV1", AV_CODEC_ID_AV1}, {"V_DIRAC" , AV_CODEC_ID_DIRAC}, {"V_FFV1" , AV_CODEC_ID_FFV1}, diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index bb3a126c29..1170f57be3 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -3306,62 +3306,81 @@ static int matroska_parse_webvtt(MatroskaDemuxContext *matroska, uint8_t *data, int data_len, uint64_t timecode, uint64_t duration, - int64_t pos) + int64_t pos, + uint8_t *additional, uint64_t additional_id, int additional_size) { AVPacket pktl, *pkt = &pktl; -uint8_t *id, *settings, *text, *buf; -int id_len, settings_len, text_len; +uint8_t *id, *settings, *comment, *text, *buf; +int id_len = 0, settings_len = 0, comment_len = 0, text_len; uint8_t *p, *q; int err; +int webm_style = !strncmp(track->codec_id, "D_WEBVTT/", 9); if (data_len <= 0) return AVERROR_INVALIDDATA; -p = data; -q = data + data_len; - -id = p; -id_len = -1; -while (p < q) { -if (*p == '\r' || *p == '\n') { -id_len = p - id; -if (*p == '\r') -p++; -break; +p = webm_style ? data : additional; +q = webm_style ? (data + data_len) : (additional + additional_size); + +if (p) { +id = p; +id_len = -1; +while (p < q) { +if (*p == '\r' || *p == '\n') { +id_len = p - id; +if (*p == '\r') +p++; +break; +} +p++; } + +if (p >= q || *p != '\n') +return AVERROR_INVALIDDATA; p++; -} -if (p >= q || *p != '\n') -return AVERROR_INVALIDDATA; -p++; - -settings = p; -settings_len = -1; -while (p < q) { -if (*p == '\r' || *p == '\n') { -settings_len = p - settings; -if (*p == '\r') -p++; -break; +settings = p; +settings_len = -1; +while (p < q) { +if (*p == '\r' || *p == '\n') { +settings_len = p - settings; +if (*p == '\r') +p++; +break; +} +p++; } + +if (p >= q || *p != '\n') +return AVERROR_INVALIDDATA; p++; + +if (!webm_style && p < q) { +if (q[-1] != '\r' && q[-1] != '\n') +return AVERROR_INVALIDDATA; + +comment = p; +comment_len = q - p; +} } -if (p >= q || *p != '\n') -return AVERROR_INVALIDDATA; -p++; - -text = p; -text_len = q - p; -while (text_len > 0) { -const int len = text_len - 1; -const uint8_t c = p[len]; -if (c != '\r' && c != '\n') -break; -text_len = len; +if (webm_style) { +text = p; +text_len = q - p; + +while (text_len > 0) { +const int len = text_len - 1; +const uint8_t c = p[len]; +if (c != '\r' && c != '\n') +break; +text_len = len; +} +} else { +text = data; +text_len = data_len; } + if (tex
[FFmpeg-devel] [PATCH 4/4] lavf/matroskaenc: mux WebVTT using standard (non-WebM) formatting
--- libavformat/matroskaenc.c | 33 + 1 file changed, 25 insertions(+), 8 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 1f7a9528de..d34a47e646 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -1351,7 +1351,7 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, return AVERROR(ENOSYS); } -if (mkv->mode != MODE_WEBM || par->codec_id != AV_CODEC_ID_WEBVTT) +if (mkv->mode != MODE_WEBM) native_id = MATROSKA_TRACK_TYPE_SUBTITLE; put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, native_id); @@ -1361,7 +1361,7 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, return AVERROR(EINVAL); } -if (mkv->mode != MODE_WEBM || par->codec_id != AV_CODEC_ID_WEBVTT) { +if (mkv->mode != MODE_WEBM) { track->codecpriv_offset = avio_tell(pb); ret = mkv_write_codecprivate(s, pb, par, native_id, qt_id); if (ret < 0) @@ -2117,20 +2117,22 @@ static int mkv_write_vtt_blocks(AVFormatContext *s, AVIOContext *pb, const AVPac MatroskaMuxContext *mkv = s->priv_data; mkv_track *track = &mkv->tracks[pkt->stream_index]; ebml_master blockgroup; -int id_size, settings_size, size; -uint8_t *id, *settings; +int id_size = 0, settings_size = 0, comment_size = 0, size = pkt->size; +uint8_t *id, *settings, *comment; int64_t ts = track->write_dts ? pkt->dts : pkt->pts; const int flags = 0; -id_size = 0; id = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_IDENTIFIER, &id_size); -settings_size = 0; settings = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_SETTINGS, &settings_size); -size = id_size + 1 + settings_size + 1 + pkt->size; +comment = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_COMMENT, + &comment_size); + +if (mkv->mode == MODE_WEBM) +size += id_size + 1 + settings_size + 1; /* The following string is identical to the one in mkv_write_block so that * only one copy needs to exist in binaries. */ @@ -2149,7 +2151,22 @@ static int mkv_write_vtt_blocks(AVFormatContext *s, AVIOContext *pb, const AVPac put_ebml_num(pb, track->track_num, track->track_num_size); avio_wb16(pb, ts - mkv->cluster_pts); avio_w8(pb, flags); -avio_printf(pb, "%.*s\n%.*s\n%.*s", id_size, id, settings_size, settings, pkt->size, pkt->data); +if (mkv->mode == MODE_WEBM) +avio_printf(pb, "%.*s\n%.*s\n", id_size, id, settings_size, settings); +avio_write(pb, pkt->data, pkt->size); + +if (mkv->mode != MODE_WEBM && (id_size || settings_size || comment_size)) { +ebml_master block_additions = start_ebml_master(pb, MATROSKA_ID_BLOCKADDITIONS, 0); +ebml_master block_more = start_ebml_master(pb, MATROSKA_ID_BLOCKMORE, 0); +/* Until dbc50f8a our demuxer used a wrong default value + * of BlockAddID, so we write it unconditionally. */ +put_ebml_uint (pb, MATROSKA_ID_BLOCKADDID, 1); +put_ebml_id(pb, MATROSKA_ID_BLOCKADDITIONAL); +put_ebml_length(pb, id_size + 1 + settings_size + 1 + comment_size, 0); +avio_printf(pb, "%.*s\n%.*s\n%.*s", id_size, id, settings_size, settings, comment_size, comment); +end_ebml_master(pb, block_more); +end_ebml_master(pb, block_additions); +} put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, pkt->duration); end_ebml_master(pb, blockgroup); -- 2.26.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/4] lavf/webvtt: preserve comments
--- libavcodec/avpacket.c | 1 + libavcodec/packet.h | 6 ++ libavformat/webvttdec.c | 25 ++--- libavformat/webvttenc.c | 10 -- 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c index 033f2d8f26..d62d93346c 100644 --- a/libavcodec/avpacket.c +++ b/libavcodec/avpacket.c @@ -399,6 +399,7 @@ const char *av_packet_side_data_name(enum AVPacketSideDataType type) case AV_PKT_DATA_PRFT: return "Producer Reference Time"; case AV_PKT_DATA_ICC_PROFILE:return "ICC Profile"; case AV_PKT_DATA_DOVI_CONF: return "DOVI configuration record"; +case AV_PKT_DATA_WEBVTT_COMMENT: return "WebVTT Comment"; } return NULL; } diff --git a/libavcodec/packet.h b/libavcodec/packet.h index 41485f4527..6b282f04c9 100644 --- a/libavcodec/packet.h +++ b/libavcodec/packet.h @@ -282,6 +282,12 @@ enum AVPacketSideDataType { */ AV_PKT_DATA_DOVI_CONF, +/** + * The optional comment data that comes before the identifier or timing block + * of a WebVTT cue. Must end with a line break. + */ +AV_PKT_DATA_WEBVTT_COMMENT, + /** * The number of side data types. * This is not part of the public API/ABI in the sense that it may diff --git a/libavformat/webvttdec.c b/libavformat/webvttdec.c index 6c4d5f6736..bc4ef45fb6 100644 --- a/libavformat/webvttdec.c +++ b/libavformat/webvttdec.c @@ -60,7 +60,7 @@ static int64_t read_ts(const char *s) static int webvtt_read_header(AVFormatContext *s) { WebVTTContext *webvtt = s->priv_data; -AVBPrint cue; +AVBPrint cue, com; int res = 0; AVStream *st = avformat_new_stream(s, NULL); @@ -72,6 +72,7 @@ static int webvtt_read_header(AVFormatContext *s) st->disposition |= webvtt->kind; av_bprint_init(&cue,0, AV_BPRINT_SIZE_UNLIMITED); +av_bprint_init(&com,0, AV_BPRINT_SIZE_UNLIMITED); for (;;) { int i; @@ -91,10 +92,15 @@ static int webvtt_read_header(AVFormatContext *s) /* ignore header chunk */ if (!strncmp(p, "\xEF\xBB\xBFWEBVTT", 9) || -!strncmp(p, "WEBVTT", 6) || -!strncmp(p, "NOTE", 4)) +!strncmp(p, "WEBVTT", 6)) continue; +if (!strncmp(p, "NOTE", 4) && +(p[4] == ' ' || p[4] == '\t' || p[4] == '\n' || p[4] == '\r')) { +av_bprintf(&com, "%s%s\n", com.len ? "\n" : "", p); +continue; +} + /* optional cue identifier (can be a number like in SRT or some kind of * chaptering id) */ for (i = 0; p[i] && p[i] != '\n' && p[i] != '\r'; i++) { @@ -159,12 +165,25 @@ static int webvtt_read_header(AVFormatContext *s) SET_SIDE_DATA(identifier, AV_PKT_DATA_WEBVTT_IDENTIFIER); SET_SIDE_DATA(settings, AV_PKT_DATA_WEBVTT_SETTINGS); +if (com.len) { +char *com_str; +if ((res = av_bprint_finalize(&com, &com_str)) < 0) +goto end; + +if ((res = av_packet_add_side_data(sub, AV_PKT_DATA_WEBVTT_COMMENT, com_str, com.len)) < 0) { +av_free(com_str); +goto end; +} + +av_bprint_init(&com,0, AV_BPRINT_SIZE_UNLIMITED); +} } ff_subtitles_queue_finalize(s, &webvtt->q); end: av_bprint_finalize(&cue,NULL); +av_bprint_finalize(&com,NULL); return res; } diff --git a/libavformat/webvttenc.c b/libavformat/webvttenc.c index cbd989dcb6..ecd508db65 100644 --- a/libavformat/webvttenc.c +++ b/libavformat/webvttenc.c @@ -64,11 +64,17 @@ static int webvtt_write_header(AVFormatContext *ctx) static int webvtt_write_packet(AVFormatContext *ctx, AVPacket *pkt) { AVIOContext *pb = ctx->pb; -int id_size, settings_size; -uint8_t *id, *settings; +int id_size, settings_size, comment_size; +uint8_t *id, *settings, *comment; avio_printf(pb, "\n"); +comment = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_COMMENT, + &comment_size); + +if (comment && comment_size > 0) +avio_printf(pb, "%.*s\n", comment_size, comment); + id = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_IDENTIFIER, &id_size); -- 2.26.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 4/4] lavf/matroskaenc: mux WebVTT using standard (non-WebM) formatting
--- libavformat/matroskaenc.c | 29 +++-- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 1f7a9528de..61b0fe9f51 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -2117,20 +2117,22 @@ static int mkv_write_vtt_blocks(AVFormatContext *s, AVIOContext *pb, const AVPac MatroskaMuxContext *mkv = s->priv_data; mkv_track *track = &mkv->tracks[pkt->stream_index]; ebml_master blockgroup; -int id_size, settings_size, size; -uint8_t *id, *settings; +int id_size = 0, settings_size = 0, comment_size = 0, size = pkt->size; +uint8_t *id, *settings, *comment; int64_t ts = track->write_dts ? pkt->dts : pkt->pts; const int flags = 0; -id_size = 0; id = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_IDENTIFIER, &id_size); -settings_size = 0; settings = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_SETTINGS, &settings_size); -size = id_size + 1 + settings_size + 1 + pkt->size; +comment = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_COMMENT, + &comment_size); + +if (mkv->mode == MODE_WEBM) +size += id_size + 1 + settings_size + 1; /* The following string is identical to the one in mkv_write_block so that * only one copy needs to exist in binaries. */ @@ -2149,7 +2151,22 @@ static int mkv_write_vtt_blocks(AVFormatContext *s, AVIOContext *pb, const AVPac put_ebml_num(pb, track->track_num, track->track_num_size); avio_wb16(pb, ts - mkv->cluster_pts); avio_w8(pb, flags); -avio_printf(pb, "%.*s\n%.*s\n%.*s", id_size, id, settings_size, settings, pkt->size, pkt->data); +if (mkv->mode == MODE_WEBM) +avio_printf(pb, "%.*s\n%.*s\n", id_size, id, settings_size, settings); +avio_write(pb, pkt->data, pkt->size); + +if (mkv->mode != MODE_WEBM && (id_size || settings_size || comment_size)) { +ebml_master block_additions = start_ebml_master(pb, MATROSKA_ID_BLOCKADDITIONS, 0); +ebml_master block_more = start_ebml_master(pb, MATROSKA_ID_BLOCKMORE, 0); +/* Until dbc50f8a our demuxer used a wrong default value + * of BlockAddID, so we write it unconditionally. */ +put_ebml_uint (pb, MATROSKA_ID_BLOCKADDID, 1); +put_ebml_id(pb, MATROSKA_ID_BLOCKADDITIONAL); +put_ebml_length(pb, id_size + 1 + settings_size + 1 + comment_size, 0); +avio_printf(pb, "%.*s\n%.*s\n%.*s", id_size, id, settings_size, settings, comment_size, comment); +end_ebml_master(pb, block_more); +end_ebml_master(pb, block_additions); +} put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, pkt->duration); end_ebml_master(pb, blockgroup); -- 2.26.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 3/4] lavf/matroskadec: support standard (non-WebM) WebVTT formatting
Fixes ticket #5641 --- libavformat/matroska.c| 11 ++-- libavformat/matroskadec.c | 111 -- 2 files changed, 77 insertions(+), 45 deletions(-) diff --git a/libavformat/matroska.c b/libavformat/matroska.c index 7c56aba403..962fa496f4 100644 --- a/libavformat/matroska.c +++ b/libavformat/matroska.c @@ -60,16 +60,12 @@ const CodecTags ff_mkv_codec_tags[]={ {"A_VORBIS" , AV_CODEC_ID_VORBIS}, {"A_WAVPACK4" , AV_CODEC_ID_WAVPACK}, -{"D_WEBVTT/SUBTITLES" , AV_CODEC_ID_WEBVTT}, -{"D_WEBVTT/CAPTIONS", AV_CODEC_ID_WEBVTT}, -{"D_WEBVTT/DESCRIPTIONS", AV_CODEC_ID_WEBVTT}, -{"D_WEBVTT/METADATA", AV_CODEC_ID_WEBVTT}, - {"S_TEXT/UTF8" , AV_CODEC_ID_SUBRIP}, {"S_TEXT/UTF8" , AV_CODEC_ID_TEXT}, {"S_TEXT/ASCII" , AV_CODEC_ID_TEXT}, {"S_TEXT/ASS" , AV_CODEC_ID_ASS}, {"S_TEXT/SSA" , AV_CODEC_ID_ASS}, +{"S_TEXT/WEBVTT", AV_CODEC_ID_WEBVTT}, {"S_ASS", AV_CODEC_ID_ASS}, {"S_SSA", AV_CODEC_ID_ASS}, {"S_VOBSUB" , AV_CODEC_ID_DVD_SUBTITLE}, @@ -77,6 +73,11 @@ const CodecTags ff_mkv_codec_tags[]={ {"S_HDMV/PGS" , AV_CODEC_ID_HDMV_PGS_SUBTITLE}, {"S_HDMV/TEXTST", AV_CODEC_ID_HDMV_TEXT_SUBTITLE}, +{"D_WEBVTT/SUBTITLES" , AV_CODEC_ID_WEBVTT}, +{"D_WEBVTT/CAPTIONS", AV_CODEC_ID_WEBVTT}, +{"D_WEBVTT/DESCRIPTIONS", AV_CODEC_ID_WEBVTT}, +{"D_WEBVTT/METADATA", AV_CODEC_ID_WEBVTT}, + {"V_AV1", AV_CODEC_ID_AV1}, {"V_DIRAC" , AV_CODEC_ID_DIRAC}, {"V_FFV1" , AV_CODEC_ID_FFV1}, diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index bb3a126c29..1170f57be3 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -3306,62 +3306,81 @@ static int matroska_parse_webvtt(MatroskaDemuxContext *matroska, uint8_t *data, int data_len, uint64_t timecode, uint64_t duration, - int64_t pos) + int64_t pos, + uint8_t *additional, uint64_t additional_id, int additional_size) { AVPacket pktl, *pkt = &pktl; -uint8_t *id, *settings, *text, *buf; -int id_len, settings_len, text_len; +uint8_t *id, *settings, *comment, *text, *buf; +int id_len = 0, settings_len = 0, comment_len = 0, text_len; uint8_t *p, *q; int err; +int webm_style = !strncmp(track->codec_id, "D_WEBVTT/", 9); if (data_len <= 0) return AVERROR_INVALIDDATA; -p = data; -q = data + data_len; - -id = p; -id_len = -1; -while (p < q) { -if (*p == '\r' || *p == '\n') { -id_len = p - id; -if (*p == '\r') -p++; -break; +p = webm_style ? data : additional; +q = webm_style ? (data + data_len) : (additional + additional_size); + +if (p) { +id = p; +id_len = -1; +while (p < q) { +if (*p == '\r' || *p == '\n') { +id_len = p - id; +if (*p == '\r') +p++; +break; +} +p++; } + +if (p >= q || *p != '\n') +return AVERROR_INVALIDDATA; p++; -} -if (p >= q || *p != '\n') -return AVERROR_INVALIDDATA; -p++; - -settings = p; -settings_len = -1; -while (p < q) { -if (*p == '\r' || *p == '\n') { -settings_len = p - settings; -if (*p == '\r') -p++; -break; +settings = p; +settings_len = -1; +while (p < q) { +if (*p == '\r' || *p == '\n') { +settings_len = p - settings; +if (*p == '\r') +p++; +break; +} +p++; } + +if (p >= q || *p != '\n') +return AVERROR_INVALIDDATA; p++; + +if (!webm_style && p < q) { +if (q[-1] != '\r' && q[-1] != '\n') +return AVERROR_INVALIDDATA; + +comment = p; +comment_len = q - p; +} } -if (p >= q || *p != '\n') -return AVERROR_INVALIDDATA; -p++; - -text = p; -text_len = q - p; -while (text_len > 0) { -const int len = text_len - 1; -const uint8_t c = p[len]; -if (c != '\r' && c != '\n') -break; -text_len = len; +if (webm_style) { +text = p; +text_len = q - p; + +while (text_len > 0) { +const int len = text_len - 1; +const uint8_t c = p[len]; +if (c != '\r' && c != '\n') +break; +text_len = len; +} +} else { +text = data; +text_len = data_len; } + if (tex
[FFmpeg-devel] [PATCH 1/4] lavf: matroska subtitle muxer
--- configure | 1 + libavformat/allformats.c | 1 + libavformat/matroskaenc.c | 30 ++ libavformat/version.h | 2 +- 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 8569a60bf8..9929c29006 100755 --- a/configure +++ b/configure @@ -3305,6 +3305,7 @@ ismv_muxer_select="mov_muxer" ivf_muxer_select="av1_metadata_bsf vp9_superframe_bsf" latm_muxer_select="aac_adtstoasc_bsf" matroska_audio_muxer_select="matroska_muxer" +matroska_subtitle_muxer_select="matroska_muxer" matroska_demuxer_select="iso_media riffdec" matroska_demuxer_suggest="bzlib lzo zlib" matroska_muxer_select="iso_media riffenc vp9_superframe_bsf aac_adtstoasc_bsf" diff --git a/libavformat/allformats.c b/libavformat/allformats.c index 3919c9e4c1..1bae208195 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -233,6 +233,7 @@ extern AVOutputFormat ff_md5_muxer; extern AVInputFormat ff_matroska_demuxer; extern AVOutputFormat ff_matroska_muxer; extern AVOutputFormat ff_matroska_audio_muxer; +extern AVOutputFormat ff_matroska_subtitle_muxer; extern AVInputFormat ff_mgsts_demuxer; extern AVInputFormat ff_microdvd_demuxer; extern AVOutputFormat ff_microdvd_muxer; diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 1c1ea71f59..1f7a9528de 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -2891,3 +2891,33 @@ AVOutputFormat ff_matroska_audio_muxer = { .priv_class= &mka_class, }; #endif + +#if CONFIG_MATROSKA_SUBTITLE_MUXER +static const AVClass mks_class = { +.class_name = "matroska subtitle muxer", +.item_name = av_default_item_name, +.option = options, +.version= LIBAVUTIL_VERSION_INT, +}; +AVOutputFormat ff_matroska_subtitle_muxer = { +.name = "matroska", +.long_name = NULL_IF_CONFIG_SMALL("Matroska Subtitle"), +.extensions= "mks", +.priv_data_size= sizeof(MatroskaMuxContext), +.audio_codec = AV_CODEC_ID_NONE, +.video_codec = AV_CODEC_ID_NONE, +.subtitle_codec= AV_CODEC_ID_ASS, +.init = mkv_init, +.deinit= mkv_deinit, +.write_header = mkv_write_header, +.write_packet = mkv_write_flush_packet, +.write_trailer = mkv_write_trailer, +.check_bitstream = mkv_check_bitstream, +.flags = AVFMT_GLOBALHEADER | AVFMT_TS_NONSTRICT | + AVFMT_ALLOW_FLUSH, +.codec_tag = (const AVCodecTag* const []){ + additional_subtitle_tags, 0 +}, +.priv_class= &mks_class, +}; +#endif diff --git a/libavformat/version.h b/libavformat/version.h index 493a0b337f..e0135fc7d3 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,7 +32,7 @@ // Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium) // Also please add any ticket numbers that you believe might be affected here #define LIBAVFORMAT_VERSION_MAJOR 58 -#define LIBAVFORMAT_VERSION_MINOR 43 +#define LIBAVFORMAT_VERSION_MINOR 44 #define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ -- 2.26.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/4] lavf/webvtt: preserve comments
--- libavcodec/avpacket.c | 1 + libavcodec/packet.h | 6 ++ libavformat/webvttdec.c | 25 ++--- libavformat/webvttenc.c | 10 -- 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c index 033f2d8f26..d62d93346c 100644 --- a/libavcodec/avpacket.c +++ b/libavcodec/avpacket.c @@ -399,6 +399,7 @@ const char *av_packet_side_data_name(enum AVPacketSideDataType type) case AV_PKT_DATA_PRFT: return "Producer Reference Time"; case AV_PKT_DATA_ICC_PROFILE:return "ICC Profile"; case AV_PKT_DATA_DOVI_CONF: return "DOVI configuration record"; +case AV_PKT_DATA_WEBVTT_COMMENT: return "WebVTT Comment"; } return NULL; } diff --git a/libavcodec/packet.h b/libavcodec/packet.h index 41485f4527..6b282f04c9 100644 --- a/libavcodec/packet.h +++ b/libavcodec/packet.h @@ -282,6 +282,12 @@ enum AVPacketSideDataType { */ AV_PKT_DATA_DOVI_CONF, +/** + * The optional comment data that comes before the identifier or timing block + * of a WebVTT cue. Must end with a line break. + */ +AV_PKT_DATA_WEBVTT_COMMENT, + /** * The number of side data types. * This is not part of the public API/ABI in the sense that it may diff --git a/libavformat/webvttdec.c b/libavformat/webvttdec.c index 6c4d5f6736..bc4ef45fb6 100644 --- a/libavformat/webvttdec.c +++ b/libavformat/webvttdec.c @@ -60,7 +60,7 @@ static int64_t read_ts(const char *s) static int webvtt_read_header(AVFormatContext *s) { WebVTTContext *webvtt = s->priv_data; -AVBPrint cue; +AVBPrint cue, com; int res = 0; AVStream *st = avformat_new_stream(s, NULL); @@ -72,6 +72,7 @@ static int webvtt_read_header(AVFormatContext *s) st->disposition |= webvtt->kind; av_bprint_init(&cue,0, AV_BPRINT_SIZE_UNLIMITED); +av_bprint_init(&com,0, AV_BPRINT_SIZE_UNLIMITED); for (;;) { int i; @@ -91,10 +92,15 @@ static int webvtt_read_header(AVFormatContext *s) /* ignore header chunk */ if (!strncmp(p, "\xEF\xBB\xBFWEBVTT", 9) || -!strncmp(p, "WEBVTT", 6) || -!strncmp(p, "NOTE", 4)) +!strncmp(p, "WEBVTT", 6)) continue; +if (!strncmp(p, "NOTE", 4) && +(p[4] == ' ' || p[4] == '\t' || p[4] == '\n' || p[4] == '\r')) { +av_bprintf(&com, "%s%s\n", com.len ? "\n" : "", p); +continue; +} + /* optional cue identifier (can be a number like in SRT or some kind of * chaptering id) */ for (i = 0; p[i] && p[i] != '\n' && p[i] != '\r'; i++) { @@ -159,12 +165,25 @@ static int webvtt_read_header(AVFormatContext *s) SET_SIDE_DATA(identifier, AV_PKT_DATA_WEBVTT_IDENTIFIER); SET_SIDE_DATA(settings, AV_PKT_DATA_WEBVTT_SETTINGS); +if (com.len) { +char *com_str; +if ((res = av_bprint_finalize(&com, &com_str)) < 0) +goto end; + +if ((res = av_packet_add_side_data(sub, AV_PKT_DATA_WEBVTT_COMMENT, com_str, com.len)) < 0) { +av_free(com_str); +goto end; +} + +av_bprint_init(&com,0, AV_BPRINT_SIZE_UNLIMITED); +} } ff_subtitles_queue_finalize(s, &webvtt->q); end: av_bprint_finalize(&cue,NULL); +av_bprint_finalize(&com,NULL); return res; } diff --git a/libavformat/webvttenc.c b/libavformat/webvttenc.c index cbd989dcb6..ecd508db65 100644 --- a/libavformat/webvttenc.c +++ b/libavformat/webvttenc.c @@ -64,11 +64,17 @@ static int webvtt_write_header(AVFormatContext *ctx) static int webvtt_write_packet(AVFormatContext *ctx, AVPacket *pkt) { AVIOContext *pb = ctx->pb; -int id_size, settings_size; -uint8_t *id, *settings; +int id_size, settings_size, comment_size; +uint8_t *id, *settings, *comment; avio_printf(pb, "\n"); +comment = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_COMMENT, + &comment_size); + +if (comment && comment_size > 0) +avio_printf(pb, "%.*s\n", comment_size, comment); + id = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_IDENTIFIER, &id_size); -- 2.26.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/4] lavf/tls_openssl: add support for verifying the server hostname on >=1.1.0
--- libavformat/tls_openssl.c | 14 +++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c index 002197fa76..d66845cf48 100644 --- a/libavformat/tls_openssl.c +++ b/libavformat/tls_openssl.c @@ -272,8 +272,6 @@ static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **op ret = AVERROR(EIO); goto fail; } -// Note, this doesn't check that the peer certificate actually matches -// the requested hostname. if (c->verify) SSL_CTX_set_verify(p->ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); p->ssl = SSL_new(p->ctx); @@ -297,8 +295,18 @@ static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **op bio->ptr = c->tcp; #endif SSL_set_bio(p->ssl, bio, bio); -if (!c->listen && !c->numerichost) +if (!c->listen && !c->numerichost) { SSL_set_tlsext_host_name(p->ssl, c->host); +if (c->verify) +#if OPENSSL_VERSION_NUMBER >= 0x101fL +SSL_set1_host(p->ssl, c->host); +#else +av_log(h, AV_LOG_WARNING, "ffmpeg was built against an old version of OpenSSL\n" + "which doesn't provide peer name verification, so this connection\n" + "will be made insecurely. To make this connection securely,\n" + "upgrade to a newer OpenSSL version, or use GNUTLS instead.\n"); +#endif +} ret = c->listen ? SSL_accept(p->ssl) : SSL_connect(p->ssl); if (ret == 0) { av_log(h, AV_LOG_ERROR, "Unable to negotiate TLS/SSL session\n"); -- 2.26.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/4] lavf/tls_openssl: use the system cert store by default
--- libavformat/tls_openssl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c index d66845cf48..b44dd3136d 100644 --- a/libavformat/tls_openssl.c +++ b/libavformat/tls_openssl.c @@ -259,6 +259,9 @@ static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **op if (c->ca_file) { if (!SSL_CTX_load_verify_locations(p->ctx, c->ca_file, NULL)) av_log(h, AV_LOG_ERROR, "SSL_CTX_load_verify_locations %s\n", ERR_error_string(ERR_get_error(), NULL)); +} else { +if (!SSL_CTX_set_default_verify_paths(p->ctx)) +av_log(h, AV_LOG_ERROR, "SSL_CTX_set_default_verify_paths %s\n", ERR_error_string(ERR_get_error(), NULL)); } if (c->cert_file && !SSL_CTX_use_certificate_chain_file(p->ctx, c->cert_file)) { av_log(h, AV_LOG_ERROR, "Unable to load cert file %s: %s\n", -- 2.26.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 4/4] lavf/tls: verify TLS connections by default whenever possible
--- libavformat/tls.c | 13 + libavformat/tls.h | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/libavformat/tls.c b/libavformat/tls.c index 10e0792e29..3cf24ca056 100644 --- a/libavformat/tls.c +++ b/libavformat/tls.c @@ -64,6 +64,19 @@ int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AV set_options(c, uri); +if (c->verify < 0) { +c->verify = c->listen; +#if CONFIG_MBEDTLS +if (!c->listen && !c->ca_file) { +av_log(parent, AV_LOG_WARNING, "ffmpeg was configured with mbedTLS and no root CA store was provided,\n" + "so this connection will be made insecurely.\n" + "To make this connection securely, specify a path to a root bundle\n" + "with the 'ca_file' option."); +c->verify = 0; +} +#endif +} + if (c->listen) snprintf(opts, sizeof(opts), "?listen=1"); diff --git a/libavformat/tls.h b/libavformat/tls.h index 6c2d025f6c..e4854c28da 100644 --- a/libavformat/tls.h +++ b/libavformat/tls.h @@ -45,7 +45,7 @@ typedef struct TLSShared { #define TLS_COMMON_OPTIONS(pstruct, options_field) \ {"ca_file","Certificate Authority database file", offsetof(pstruct, options_field . ca_file), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \ {"cafile", "Certificate Authority database file", offsetof(pstruct, options_field . ca_file), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \ -{"tls_verify", "Verify the peer certificate", offsetof(pstruct, options_field . verify),AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = TLS_OPTFL }, \ +{"tls_verify", "Verify the peer certificate", offsetof(pstruct, options_field . verify),AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, .flags = TLS_OPTFL }, \ {"cert_file", "Certificate file",offsetof(pstruct, options_field . cert_file), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \ {"key_file", "Private key file",offsetof(pstruct, options_field . key_file), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \ {"listen", "Listen for incoming connections", offsetof(pstruct, options_field . listen),AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = TLS_OPTFL }, \ -- 2.26.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 3/4] lavf/tls: use AV_OPT_TYPE_BOOL
--- libavformat/tls.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/tls.h b/libavformat/tls.h index beb19d6d55..6c2d025f6c 100644 --- a/libavformat/tls.h +++ b/libavformat/tls.h @@ -45,10 +45,10 @@ typedef struct TLSShared { #define TLS_COMMON_OPTIONS(pstruct, options_field) \ {"ca_file","Certificate Authority database file", offsetof(pstruct, options_field . ca_file), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \ {"cafile", "Certificate Authority database file", offsetof(pstruct, options_field . ca_file), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \ -{"tls_verify", "Verify the peer certificate", offsetof(pstruct, options_field . verify),AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = TLS_OPTFL }, \ +{"tls_verify", "Verify the peer certificate", offsetof(pstruct, options_field . verify),AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = TLS_OPTFL }, \ {"cert_file", "Certificate file",offsetof(pstruct, options_field . cert_file), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \ {"key_file", "Private key file",offsetof(pstruct, options_field . key_file), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL }, \ -{"listen", "Listen for incoming connections", offsetof(pstruct, options_field . listen),AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = TLS_OPTFL }, \ +{"listen", "Listen for incoming connections", offsetof(pstruct, options_field . listen),AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = TLS_OPTFL }, \ {"verifyhost", "Verify against a specific hostname", offsetof(pstruct, options_field . host), AV_OPT_TYPE_STRING, .flags = TLS_OPTFL } int ff_tls_open_underlying(TLSShared *c, URLContext *parent, const char *uri, AVDictionary **options); -- 2.26.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] configure: allow OpenSSL>=3.0.0 with GPL
--- configure | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 8569a60bf8..cbe8b25001 100755 --- a/configure +++ b/configure @@ -1731,7 +1731,6 @@ EXTERNAL_LIBRARY_GPL_LIST=" EXTERNAL_LIBRARY_NONFREE_LIST=" decklink libfdk_aac -openssl libtls " @@ -1820,6 +1819,7 @@ EXTERNAL_LIBRARY_LIST=" mediacodec openal opengl +openssl pocketsphinx vapoursynth " @@ -6469,6 +6469,8 @@ enabled openssl && { check_pkg_config openssl openssl openssl/ssl.h OP check_lib openssl openssl/ssl.h SSL_library_init -lssl32 -leay32 || check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 || die "ERROR: openssl not found"; } +enabled openssl && enabled gpl && ! enabled nonfree && { test_cpp_condition "openssl/opensslv.h" "defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3" || + die "OpenSSL versions prior to 3.0.0 are incompatible with the gpl and --enable-nonfree is not specified."; } enabled pocketsphinx && require_pkg_config pocketsphinx pocketsphinx pocketsphinx/pocketsphinx.h ps_init enabled rkmpp && { require_pkg_config rkmpp rockchip_mpp rockchip/rk_mpi.h mpp_create && require_pkg_config rockchip_mpp "rockchip_mpp >= 1.3.7" rockchip/rk_mpi.h mpp_create && -- 2.26.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] configure: allow OpenSSL>=3.0.0 with GPLv3
--- configure | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 8569a60bf8..a525611cc8 100755 --- a/configure +++ b/configure @@ -1731,7 +1731,6 @@ EXTERNAL_LIBRARY_GPL_LIST=" EXTERNAL_LIBRARY_NONFREE_LIST=" decklink libfdk_aac -openssl libtls " @@ -1820,6 +1819,7 @@ EXTERNAL_LIBRARY_LIST=" mediacodec openal opengl +openssl pocketsphinx vapoursynth " @@ -6469,6 +6469,9 @@ enabled openssl && { check_pkg_config openssl openssl openssl/ssl.h OP check_lib openssl openssl/ssl.h SSL_library_init -lssl32 -leay32 || check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto -lws2_32 -lgdi32 || die "ERROR: openssl not found"; } +enabled openssl && enabled gpl && { test_cpp_condition "openssl/opensslv.h" "defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3" && +{ ! enabled gplv3 && die "OpenSSL is not compatible with gpl version 2 and --enable-version3 is not specified." || true; } || +{ ! enabled nonfree && die "OpenSSL versions prior to 3.0.0 are incompatible with the gpl and --enable-nonfree is not specified."; } ; } enabled pocketsphinx && require_pkg_config pocketsphinx pocketsphinx pocketsphinx/pocketsphinx.h ps_init enabled rkmpp && { require_pkg_config rkmpp rockchip_mpp rockchip/rk_mpi.h mpp_create && require_pkg_config rockchip_mpp "rockchip_mpp >= 1.3.7" rockchip/rk_mpi.h mpp_create && -- 2.26.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/5] lavf/dashdec: fix 'adaption' typo
--- libavformat/dashdec.c | 96 +-- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 1bd070c7cb..c94ce2caca 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -148,7 +148,7 @@ typedef struct DASHContext { uint64_t period_start; /* AdaptationSet Attribute */ -char *adaptionset_lang; +char *adaptationset_lang; int is_live; AVIOInterruptCB *interrupt_callback; @@ -822,16 +822,16 @@ end: static int parse_manifest_representation(AVFormatContext *s, const char *url, xmlNodePtr node, - xmlNodePtr adaptionset_node, + xmlNodePtr adaptationset_node, xmlNodePtr mpd_baseurl_node, xmlNodePtr period_baseurl_node, xmlNodePtr period_segmenttemplate_node, xmlNodePtr period_segmentlist_node, xmlNodePtr fragment_template_node, xmlNodePtr content_component_node, - xmlNodePtr adaptionset_baseurl_node, - xmlNodePtr adaptionset_segmentlist_node, - xmlNodePtr adaptionset_supplementalproperty_node) + xmlNodePtr adaptationset_baseurl_node, + xmlNodePtr adaptationset_segmentlist_node, + xmlNodePtr adaptationset_supplementalproperty_node) { int32_t ret = 0; int32_t subtitle_rep_idx = 0; @@ -866,9 +866,9 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, // try get information from contentComponen if (type == AVMEDIA_TYPE_UNKNOWN) type = get_content_type(content_component_node); -// try get information from adaption set +// try get information from adaptation set if (type == AVMEDIA_TYPE_UNKNOWN) -type = get_content_type(adaptionset_node); +type = get_content_type(adaptationset_node); if (type == AVMEDIA_TYPE_UNKNOWN) { av_log(s, AV_LOG_VERBOSE, "Parsing '%s' - skipp not supported representation type\n", url); } else if (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO || type == AVMEDIA_TYPE_SUBTITLE) { @@ -878,8 +878,8 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, ret = AVERROR(ENOMEM); goto end; } -if (c->adaptionset_lang) { -rep->lang = av_strdup(c->adaptionset_lang); +if (c->adaptationset_lang) { +rep->lang = av_strdup(c->adaptationset_lang); if (!rep->lang) { av_log(s, AV_LOG_ERROR, "alloc language memory failure\n"); av_freep(&rep); @@ -894,7 +894,7 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, baseurl_nodes[0] = mpd_baseurl_node; baseurl_nodes[1] = period_baseurl_node; -baseurl_nodes[2] = adaptionset_baseurl_node; +baseurl_nodes[2] = adaptationset_baseurl_node; baseurl_nodes[3] = representation_baseurl_node; ret = resolve_content_path(s, url, &c->max_url_size, baseurl_nodes, 4); @@ -907,7 +907,7 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, if (representation_segmenttemplate_node || fragment_template_node || period_segmenttemplate_node) { fragment_timeline_node = NULL; fragment_templates_tab[0] = representation_segmenttemplate_node; -fragment_templates_tab[1] = adaptionset_segmentlist_node; +fragment_templates_tab[1] = adaptationset_segmentlist_node; fragment_templates_tab[2] = fragment_template_node; fragment_templates_tab[3] = period_segmenttemplate_node; fragment_templates_tab[4] = period_segmentlist_node; @@ -964,11 +964,11 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, av_log(s, AV_LOG_TRACE, "rep->first_seq_no = [%"PRId64"]\n", rep->first_seq_no); xmlFree(startnumber_val); } -if (adaptionset_supplementalproperty_node) { -if (!av_strcasecmp(xmlGetProp(adaptionset_supplementalproperty_node,"schemeIdUri"), "http://dashif.org/guidelines/last-segment-number";)) { -val = xmlGetProp(adaptionset_supplementalproperty_node,"value"); +if (adaptationset_supplementalproperty_node) { +if (!av_strcasecmp(xmlGetProp(adaptationset_supplementalproperty_node,"schemeIdUri"), "http://dashif.org/guidelines/last-segment-number
[FFmpeg-devel] [PATCH 3/5] lavc/h264dec: loosen new-extradata check
--- libavcodec/h264dec.c | 13 ++--- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 6270ea80df..0d7492cfad 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -988,6 +988,8 @@ static int h264_decode_frame(AVCodecContext *avctx, void *data, AVFrame *pict = data; int buf_index; int ret; +const uint8_t *new_extra; +int new_extra_size; h->flags = avctx->flags; h->setup_finished = 0; @@ -999,13 +1001,10 @@ static int h264_decode_frame(AVCodecContext *avctx, void *data, if (buf_size == 0) return send_next_delayed_frame(h, pict, got_frame, 0); -if (h->is_avc && av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, NULL)) { -int side_size; -uint8_t *side = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size); -if (is_extra(side, side_size)) -ff_h264_decode_extradata(side, side_size, - &h->ps, &h->is_avc, &h->nal_length_size, - avctx->err_recognition, avctx); +if ((new_extra = av_packet_get_side_data(avpkt, AV_PKT_DATA_NEW_EXTRADATA, &new_extra_size))) { +ff_h264_decode_extradata(new_extra, new_extra_size, + &h->ps, &h->is_avc, &h->nal_length_size, + avctx->err_recognition, avctx); } if (h->is_avc && buf_size >= 9 && buf[0]==1 && buf[2]==0 && (buf[4]&0xFC)==0xFC) { if (is_extra(buf, buf_size)) -- 2.26.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 4/5] lavf/dashdec: improve memory handling
- Fixes a couple leaks - Adds an av_freep equivalent for libxml buffers - Avoids some redundant copying --- libavformat/dashdec.c | 44 +++ 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index c94ce2caca..378c892b87 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -147,9 +147,6 @@ typedef struct DASHContext { uint64_t period_duration; uint64_t period_start; -/* AdaptationSet Attribute */ -char *adaptationset_lang; - int is_live; AVIOInterruptCB *interrupt_callback; char *allowed_extensions; @@ -162,6 +159,15 @@ typedef struct DASHContext { } DASHContext; +static void xml_freep(void* arg) +{ +void *val; + +memcpy(&val, arg, sizeof(val)); +memcpy(arg, &(void *){ NULL }, sizeof(val)); +xmlFree(val); +} + static int ishttp(char *url) { const char *proto_name = avio_find_protocol_name(url); @@ -362,6 +368,8 @@ static void free_representation(struct representation *pls) avformat_close_input(&pls->ctx); } +xml_freep(&pls->lang); + av_freep(&pls->url_template); av_freep(&pls); } @@ -878,15 +886,9 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, ret = AVERROR(ENOMEM); goto end; } -if (c->adaptationset_lang) { -rep->lang = av_strdup(c->adaptationset_lang); -if (!rep->lang) { -av_log(s, AV_LOG_ERROR, "alloc language memory failure\n"); -av_freep(&rep); -ret = AVERROR(ENOMEM); -goto end; -} -} + +rep->lang = xmlGetProp(adaptationset_node, "lang"); + rep->parent = s; representation_segmenttemplate_node = find_child_node_by_name(representation_node, "SegmentTemplate"); representation_baseurl_node = find_child_node_by_name(representation_node, "BaseURL"); @@ -965,7 +967,8 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, xmlFree(startnumber_val); } if (adaptationset_supplementalproperty_node) { -if (!av_strcasecmp(xmlGetProp(adaptationset_supplementalproperty_node,"schemeIdUri"), "http://dashif.org/guidelines/last-segment-number";)) { +char *schemeIdUri = xmlGetProp(adaptationset_supplementalproperty_node, "schemeIdUri"); +if (!av_strcasecmp(schemeIdUri, "http://dashif.org/guidelines/last-segment-number";)) { val = xmlGetProp(adaptationset_supplementalproperty_node,"value"); if (!val) { av_log(s, AV_LOG_ERROR, "Missing value attribute in adaptationset_supplementalproperty_node\n"); @@ -974,6 +977,7 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, xmlFree(val); } } +xmlFree(schemeIdUri); } fragment_timeline_node = find_child_node_by_name(representation_segmenttemplate_node, "SegmentTimeline"); @@ -1120,13 +1124,10 @@ end: static int parse_manifest_adaptationset_attr(AVFormatContext *s, xmlNodePtr adaptationset_node) { -DASHContext *c = s->priv_data; - if (!adaptationset_node) { av_log(s, AV_LOG_WARNING, "Cannot get AdaptationSet\n"); return AVERROR(EINVAL); } -c->adaptationset_lang = xmlGetProp(adaptationset_node, "lang"); return 0; } @@ -1139,7 +1140,6 @@ static int parse_manifest_adaptationset(AVFormatContext *s, const char *url, xmlNodePtr period_segmentlist_node) { int ret = 0; -DASHContext *c = s->priv_data; xmlNodePtr fragment_template_node = NULL; xmlNodePtr content_component_node = NULL; xmlNodePtr adaptationset_baseurl_node = NULL; @@ -1182,7 +1182,6 @@ static int parse_manifest_adaptationset(AVFormatContext *s, const char *url, } err: -av_freep(&c->adaptationset_lang); return ret; } @@ -2157,6 +2156,10 @@ static int dash_read_header(AVFormatContext *s) av_dict_set_int(&rep->assoc_stream->metadata, "variant_bitrate", rep->bandwidth, 0); if (rep->id[0]) av_dict_set(&rep->assoc_stream->metadata, "id", rep->id, 0); +if (rep->lang) { +av_dict_set(&rep->assoc_stream->metadata, "language", rep->lang, 0); +xml_freep(&rep->lang); +} } for (i = 0; i < c->n_audios; i++) { rep = c->audios[i]; @@ -2168,7 +2171,7 @@ static int dash_read_header(AVFormatContext *s) av_dict_set(&rep->assoc_stream->metadata, "id", rep->id, 0); if (rep->lang) { av_dict_set(&rep->assoc_stream->metadata, "language", rep->lang, 0); -av_freep(&rep->lang); +
[FFmpeg-devel] [PATCH 2/5] lavc: add avpriv_h264_get_profile
--- libavcodec/h264_parse.c | 21 + libavcodec/h264_parse.h | 2 ++ libavcodec/version.h| 2 +- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/libavcodec/h264_parse.c b/libavcodec/h264_parse.c index 352ffea948..3069579926 100644 --- a/libavcodec/h264_parse.c +++ b/libavcodec/h264_parse.c @@ -528,18 +528,31 @@ int ff_h264_decode_extradata(const uint8_t *data, int size, H264ParamSets *ps, */ int ff_h264_get_profile(const SPS *sps) { -int profile = sps->profile_idc; +return avpriv_h264_get_profile(sps->profile_idc, sps->constraint_set_flags); +} + +/** + * Compute profile from profile_idc and constraint_set?_flags. + * + * @param profile_idc profile_idc field from SPS + * @param constraint_set_flags constraint_set_flags field from SPS + * + * @return profile as defined by FF_PROFILE_H264_* + */ +int avpriv_h264_get_profile(int profile_idc, int constraint_set_flags) +{ +int profile = profile_idc; -switch (sps->profile_idc) { +switch (profile_idc) { case FF_PROFILE_H264_BASELINE: // constraint_set1_flag set to 1 -profile |= (sps->constraint_set_flags & 1 << 1) ? FF_PROFILE_H264_CONSTRAINED : 0; +profile |= (constraint_set_flags & 1 << 1) ? FF_PROFILE_H264_CONSTRAINED : 0; break; case FF_PROFILE_H264_HIGH_10: case FF_PROFILE_H264_HIGH_422: case FF_PROFILE_H264_HIGH_444_PREDICTIVE: // constraint_set3_flag set to 1 -profile |= (sps->constraint_set_flags & 1 << 3) ? FF_PROFILE_H264_INTRA : 0; +profile |= (constraint_set_flags & 1 << 3) ? FF_PROFILE_H264_INTRA : 0; break; } diff --git a/libavcodec/h264_parse.h b/libavcodec/h264_parse.h index 4d01620125..a1462ad8fd 100644 --- a/libavcodec/h264_parse.h +++ b/libavcodec/h264_parse.h @@ -90,4 +90,6 @@ int ff_h264_decode_extradata(const uint8_t *data, int size, H264ParamSets *ps, */ int ff_h264_get_profile(const SPS *sps); +int avpriv_h264_get_profile(int profile_idc, int constraint_set_flags); + #endif /* AVCODEC_H264_PARSE_H */ diff --git a/libavcodec/version.h b/libavcodec/version.h index 60c0f2460d..03593026b3 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 58 -#define LIBAVCODEC_VERSION_MINOR 92 +#define LIBAVCODEC_VERSION_MINOR 93 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ -- 2.26.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 5/5] lavf/dashdec: don't require opening all playlists during read_header
This improves startup performance massively when the consumer doesn't make a call to avformat_find_stream_info(). Also makes the requirement that each rendition only have 1 stream more clear (this is required by DASH), and generally improves error handling. --- libavformat/dashdec.c | 283 +++--- libavformat/version.h | 2 +- 2 files changed, 265 insertions(+), 20 deletions(-) diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 378c892b87..b04a2596a9 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -27,6 +27,11 @@ #include "internal.h" #include "avio_internal.h" #include "dash.h" +#include "isom.h" + +#if CONFIG_H264PARSE +#include "libavcodec/h264_parse.h" +#endif #define INITIAL_BUFFER_SIZE 32768 #define MAX_MANIFEST_SIZE 50 * 1024 @@ -112,6 +117,14 @@ struct representation { int64_t cur_seg_size; struct fragment *cur_seg; +/* Media parameters */ +char *mimeType; +char *codecs; +char *audioSamplingRate; +char *sar; +char *width; +char *height; + /* Currently active Media Initialization Section */ struct fragment *init_section; uint8_t *init_sec_buf; @@ -120,6 +133,12 @@ struct representation { uint32_t init_sec_buf_read_offset; int64_t cur_timestamp; int is_restart_needed; + +int streams_initialized; +int open_failed; + +char *new_extradata; +int new_extradata_size; }; typedef struct DASHContext { @@ -152,6 +171,7 @@ typedef struct DASHContext { char *allowed_extensions; AVDictionary *avio_opts; int max_url_size; +int open_all; /* Flags for init section*/ int is_init_section_common_video; @@ -369,6 +389,11 @@ static void free_representation(struct representation *pls) } xml_freep(&pls->lang); +xml_freep(&pls->mimeType); +xml_freep(&pls->codecs); +xml_freep(&pls->audioSamplingRate); +xml_freep(&pls->width); +xml_freep(&pls->height); av_freep(&pls->url_template); av_freep(&pls); @@ -888,6 +913,16 @@ static int parse_manifest_representation(AVFormatContext *s, const char *url, } rep->lang = xmlGetProp(adaptationset_node, "lang"); +#define GET_VALUE(name) \ +if (!(rep->name = xmlGetProp(node, #name))) \ +rep->name = xmlGetProp(adaptationset_node, #name) + +GET_VALUE(mimeType); +GET_VALUE(codecs); +GET_VALUE(audioSamplingRate); +GET_VALUE(sar); +GET_VALUE(width); +GET_VALUE(height); rep->parent = s; representation_segmenttemplate_node = find_child_node_by_name(representation_node, "SegmentTemplate"); @@ -1905,7 +1940,7 @@ static int reopen_demux_for_component(AVFormatContext *s, struct representation ff_const59 AVInputFormat *in_fmt = NULL; AVDictionary *in_fmt_opts = NULL; uint8_t *avio_ctx_buffer = NULL; -int ret = 0, i; +int ret = 0; if (pls->ctx) { close_demux_for_component(pls); @@ -1969,12 +2004,14 @@ static int reopen_demux_for_component(AVFormatContext *s, struct representation av_dict_free(&in_fmt_opts); if (ret < 0) goto fail; +if (pls->ctx->nb_streams < 1) { +ret = AVERROR_INVALIDDATA; +goto fail; +} if (pls->n_fragments) { #if FF_API_R_FRAME_RATE -if (pls->framerate.den) { -for (i = 0; i < pls->ctx->nb_streams; i++) -pls->ctx->streams[i]->r_frame_rate = pls->framerate; -} +if (pls->framerate.den) +pls->ctx->streams[0]->r_frame_rate = pls->framerate; #endif ret = avformat_find_stream_info(pls->ctx, NULL); if (ret < 0) @@ -1985,10 +2022,157 @@ fail: return ret; } +static int parse_codecs(AVFormatContext *s, AVCodecParameters *params, const struct representation *pls) +{ +if (pls->mimeType && !strcmp(pls->mimeType, "text/vtt")) { +params->codec_id = AV_CODEC_ID_WEBVTT; +return 1; +} else if (pls->mimeType && !strcmp(pls->mimeType, "application/ttml+xml")) { +params->codec_id = AV_CODEC_ID_TTML; +return 1; +} else if (!pls->codecs) { +return 0; +} else if (!strncmp(pls->codecs, "avc1.", 5) || + !strncmp(pls->codecs, "avc3.", 5)) { +int len = strlen(pls->codecs); + +params->codec_id = AV_CODEC_ID_H264; + +if (len >= 11) { +char buf[3] = {0}; +char *end = NULL; +int profile_idc, level_idc; + +memcpy(buf, pls->codecs + 5, 2); +profile_idc = strtoul(buf, &end, 16); +if (end == &buf[2]) { +#if CONFIG_H264PARSE +int constraint_set_flags; +memcpy(buf, pls->codecs + 7, 2); +constraint_set_flags = strtoul(buf, &end, 16); +if (end != &buf[2]) // If this isn't a hex byte, assume no constraints +constraint_set_flags = 0; + +
[FFmpeg-devel] [PATCH 5/5] lavf/webvttdec: ignore unrecognized blocks
The WebVTT spec expects this behavior and it fixes some files --- libavformat/webvttdec.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libavformat/webvttdec.c b/libavformat/webvttdec.c index 38c281fe00..2e832b86eb 100644 --- a/libavformat/webvttdec.c +++ b/libavformat/webvttdec.c @@ -78,7 +78,7 @@ static int webvtt_read_header(AVFormatContext *s) int i; int64_t pos; AVPacket *sub; -const char *p, *identifier, *settings; +const char *p, *identifier, *settings, *arrow; int identifier_len, settings_len; int64_t ts_start, ts_end; @@ -120,12 +120,13 @@ static int webvtt_read_header(AVFormatContext *s) p++; } +if (!(arrow = strstr(p, "-->"))) +continue; + /* cue timestamps */ if ((ts_start = read_ts(p)) == AV_NOPTS_VALUE) break; -if (!(p = strstr(p, "-->"))) -break; -p += 2; +p = arrow + 2; do p++; while (*p == ' ' || *p == '\t'); if ((ts_end = read_ts(p)) == AV_NOPTS_VALUE) break; -- 2.26.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 3/5] lavf/matroskadec: support standard (non-WebM) WebVTT formatting
Fixes ticket #5641 --- libavformat/matroska.c| 11 ++-- libavformat/matroskadec.c | 111 -- 2 files changed, 77 insertions(+), 45 deletions(-) diff --git a/libavformat/matroska.c b/libavformat/matroska.c index 7c56aba403..962fa496f4 100644 --- a/libavformat/matroska.c +++ b/libavformat/matroska.c @@ -60,16 +60,12 @@ const CodecTags ff_mkv_codec_tags[]={ {"A_VORBIS" , AV_CODEC_ID_VORBIS}, {"A_WAVPACK4" , AV_CODEC_ID_WAVPACK}, -{"D_WEBVTT/SUBTITLES" , AV_CODEC_ID_WEBVTT}, -{"D_WEBVTT/CAPTIONS", AV_CODEC_ID_WEBVTT}, -{"D_WEBVTT/DESCRIPTIONS", AV_CODEC_ID_WEBVTT}, -{"D_WEBVTT/METADATA", AV_CODEC_ID_WEBVTT}, - {"S_TEXT/UTF8" , AV_CODEC_ID_SUBRIP}, {"S_TEXT/UTF8" , AV_CODEC_ID_TEXT}, {"S_TEXT/ASCII" , AV_CODEC_ID_TEXT}, {"S_TEXT/ASS" , AV_CODEC_ID_ASS}, {"S_TEXT/SSA" , AV_CODEC_ID_ASS}, +{"S_TEXT/WEBVTT", AV_CODEC_ID_WEBVTT}, {"S_ASS", AV_CODEC_ID_ASS}, {"S_SSA", AV_CODEC_ID_ASS}, {"S_VOBSUB" , AV_CODEC_ID_DVD_SUBTITLE}, @@ -77,6 +73,11 @@ const CodecTags ff_mkv_codec_tags[]={ {"S_HDMV/PGS" , AV_CODEC_ID_HDMV_PGS_SUBTITLE}, {"S_HDMV/TEXTST", AV_CODEC_ID_HDMV_TEXT_SUBTITLE}, +{"D_WEBVTT/SUBTITLES" , AV_CODEC_ID_WEBVTT}, +{"D_WEBVTT/CAPTIONS", AV_CODEC_ID_WEBVTT}, +{"D_WEBVTT/DESCRIPTIONS", AV_CODEC_ID_WEBVTT}, +{"D_WEBVTT/METADATA", AV_CODEC_ID_WEBVTT}, + {"V_AV1", AV_CODEC_ID_AV1}, {"V_DIRAC" , AV_CODEC_ID_DIRAC}, {"V_FFV1" , AV_CODEC_ID_FFV1}, diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index cff7f0cb54..1e4947e209 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -3305,62 +3305,81 @@ static int matroska_parse_webvtt(MatroskaDemuxContext *matroska, uint8_t *data, int data_len, uint64_t timecode, uint64_t duration, - int64_t pos) + int64_t pos, + uint8_t *additional, uint64_t additional_id, int additional_size) { AVPacket pktl, *pkt = &pktl; -uint8_t *id, *settings, *text, *buf; -int id_len, settings_len, text_len; +uint8_t *id, *settings, *comment, *text, *buf; +int id_len = 0, settings_len = 0, comment_len = 0, text_len; uint8_t *p, *q; int err; +int webm_style = !strncmp(track->codec_id, "D_WEBVTT/", 9); if (data_len <= 0) return AVERROR_INVALIDDATA; -p = data; -q = data + data_len; - -id = p; -id_len = -1; -while (p < q) { -if (*p == '\r' || *p == '\n') { -id_len = p - id; -if (*p == '\r') -p++; -break; +p = webm_style ? data : additional; +q = webm_style ? (data + data_len) : (additional + additional_size); + +if (p) { +id = p; +id_len = -1; +while (p < q) { +if (*p == '\r' || *p == '\n') { +id_len = p - id; +if (*p == '\r') +p++; +break; +} +p++; } + +if (p >= q || *p != '\n') +return AVERROR_INVALIDDATA; p++; -} -if (p >= q || *p != '\n') -return AVERROR_INVALIDDATA; -p++; - -settings = p; -settings_len = -1; -while (p < q) { -if (*p == '\r' || *p == '\n') { -settings_len = p - settings; -if (*p == '\r') -p++; -break; +settings = p; +settings_len = -1; +while (p < q) { +if (*p == '\r' || *p == '\n') { +settings_len = p - settings; +if (*p == '\r') +p++; +break; +} +p++; } + +if (p >= q || *p != '\n') +return AVERROR_INVALIDDATA; p++; + +if (!webm_style && p < q) { +if (q[-1] != '\r' && q[-1] != '\n') +return AVERROR_INVALIDDATA; + +comment = p; +comment_len = q - p; +} } -if (p >= q || *p != '\n') -return AVERROR_INVALIDDATA; -p++; - -text = p; -text_len = q - p; -while (text_len > 0) { -const int len = text_len - 1; -const uint8_t c = p[len]; -if (c != '\r' && c != '\n') -break; -text_len = len; +if (webm_style) { +text = p; +text_len = q - p; + +while (text_len > 0) { +const int len = text_len - 1; +const uint8_t c = p[len]; +if (c != '\r' && c != '\n') +break; +text_len = len; +} +} else { +text = data; +text_len = data_len; } + if (tex
[FFmpeg-devel] [PATCH 4/5] lavf/matroskaenc: mux WebVTT using standard (non-WebM) formatting
--- libavformat/matroskaenc.c | 30 -- 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 63d6b50e6a..94e6cc542a 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -2117,22 +2117,25 @@ static int mkv_write_vtt_blocks(AVFormatContext *s, AVIOContext *pb, const AVPac MatroskaMuxContext *mkv = s->priv_data; mkv_track *track = &mkv->tracks[pkt->stream_index]; ebml_master blockgroup; -int id_size, settings_size, size; -const char *id, *settings; +int id_size = 0, settings_size = 0, comment_size = 0, size = pkt->size; +const char *id, *settings, *comment; int64_t ts = track->write_dts ? pkt->dts : pkt->pts; const int flags = 0; -id_size = 0; id = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_IDENTIFIER, &id_size); id = id ? id : ""; -settings_size = 0; settings = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_SETTINGS, &settings_size); settings = settings ? settings : ""; -size = id_size + 1 + settings_size + 1 + pkt->size; +comment = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_COMMENT, + &comment_size); +comment = comment ? comment : ""; + +if (mkv->mode == MODE_WEBM) +size += id_size + 1 + settings_size + 1; /* The following string is identical to the one in mkv_write_block so that * only one copy needs to exist in binaries. */ @@ -2151,7 +2154,22 @@ static int mkv_write_vtt_blocks(AVFormatContext *s, AVIOContext *pb, const AVPac put_ebml_num(pb, track->track_num, track->track_num_size); avio_wb16(pb, ts - mkv->cluster_pts); avio_w8(pb, flags); -avio_printf(pb, "%.*s\n%.*s\n%.*s", id_size, id, settings_size, settings, pkt->size, pkt->data); +if (mkv->mode == MODE_WEBM) +avio_printf(pb, "%.*s\n%.*s\n", id_size, id, settings_size, settings); +avio_write(pb, pkt->data, pkt->size); + +if (mkv->mode != MODE_WEBM && (id_size || settings_size || comment_size)) { +ebml_master block_additions = start_ebml_master(pb, MATROSKA_ID_BLOCKADDITIONS, 0); +ebml_master block_more = start_ebml_master(pb, MATROSKA_ID_BLOCKMORE, 0); +/* Until dbc50f8a our demuxer used a wrong default value + * of BlockAddID, so we write it unconditionally. */ +put_ebml_uint (pb, MATROSKA_ID_BLOCKADDID, 1); +put_ebml_id(pb, MATROSKA_ID_BLOCKADDITIONAL); +put_ebml_length(pb, id_size + 1 + settings_size + 1 + comment_size, 0); +avio_printf(pb, "%.*s\n%.*s\n%.*s", id_size, id, settings_size, settings, comment_size, comment); +end_ebml_master(pb, block_more); +end_ebml_master(pb, block_additions); +} put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, pkt->duration); end_ebml_master(pb, blockgroup); -- 2.26.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/5] lavf: matroska subtitle muxer
--- configure | 1 + libavformat/allformats.c | 1 + libavformat/matroskaenc.c | 30 ++ libavformat/version.h | 4 ++-- 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 7495f35faa..28686ce2e8 100755 --- a/configure +++ b/configure @@ -3305,6 +3305,7 @@ ismv_muxer_select="mov_muxer" ivf_muxer_select="av1_metadata_bsf vp9_superframe_bsf" latm_muxer_select="aac_adtstoasc_bsf" matroska_audio_muxer_select="matroska_muxer" +matroska_subtitle_muxer_select="matroska_muxer" matroska_demuxer_select="iso_media riffdec" matroska_demuxer_suggest="bzlib lzo zlib" matroska_muxer_select="iso_media riffenc vp9_superframe_bsf aac_adtstoasc_bsf" diff --git a/libavformat/allformats.c b/libavformat/allformats.c index a7c5c9db89..9d6f6c2ad5 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -234,6 +234,7 @@ extern AVOutputFormat ff_md5_muxer; extern AVInputFormat ff_matroska_demuxer; extern AVOutputFormat ff_matroska_muxer; extern AVOutputFormat ff_matroska_audio_muxer; +extern AVOutputFormat ff_matroska_subtitle_muxer; extern AVInputFormat ff_mgsts_demuxer; extern AVInputFormat ff_microdvd_demuxer; extern AVOutputFormat ff_microdvd_muxer; diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index eaed02bc92..63d6b50e6a 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -2893,3 +2893,33 @@ AVOutputFormat ff_matroska_audio_muxer = { .priv_class= &mka_class, }; #endif + +#if CONFIG_MATROSKA_SUBTITLE_MUXER +static const AVClass mks_class = { +.class_name = "matroska subtitle muxer", +.item_name = av_default_item_name, +.option = options, +.version= LIBAVUTIL_VERSION_INT, +}; +AVOutputFormat ff_matroska_subtitle_muxer = { +.name = "matroska", +.long_name = NULL_IF_CONFIG_SMALL("Matroska Subtitle"), +.extensions= "mks", +.priv_data_size= sizeof(MatroskaMuxContext), +.audio_codec = AV_CODEC_ID_NONE, +.video_codec = AV_CODEC_ID_NONE, +.subtitle_codec= AV_CODEC_ID_ASS, +.init = mkv_init, +.deinit= mkv_deinit, +.write_header = mkv_write_header, +.write_packet = mkv_write_flush_packet, +.write_trailer = mkv_write_trailer, +.check_bitstream = mkv_check_bitstream, +.flags = AVFMT_GLOBALHEADER | AVFMT_TS_NONSTRICT | + AVFMT_ALLOW_FLUSH, +.codec_tag = (const AVCodecTag* const []){ + additional_subtitle_tags, 0 +}, +.priv_class= &mks_class, +}; +#endif diff --git a/libavformat/version.h b/libavformat/version.h index 59151a71a0..3c1957b00c 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,8 +32,8 @@ // Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium) // Also please add any ticket numbers that you believe might be affected here #define LIBAVFORMAT_VERSION_MAJOR 58 -#define LIBAVFORMAT_VERSION_MINOR 46 -#define LIBAVFORMAT_VERSION_MICRO 101 +#define LIBAVFORMAT_VERSION_MINOR 47 +#define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ -- 2.26.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/5] lavf/webvtt: preserve comments
--- libavcodec/avpacket.c | 1 + libavcodec/packet.h | 6 ++ libavformat/webvttdec.c | 25 ++--- libavformat/webvttenc.c | 10 -- 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c index dce26cb31a..5b7842e434 100644 --- a/libavcodec/avpacket.c +++ b/libavcodec/avpacket.c @@ -400,6 +400,7 @@ const char *av_packet_side_data_name(enum AVPacketSideDataType type) case AV_PKT_DATA_PRFT: return "Producer Reference Time"; case AV_PKT_DATA_ICC_PROFILE:return "ICC Profile"; case AV_PKT_DATA_DOVI_CONF: return "DOVI configuration record"; +case AV_PKT_DATA_WEBVTT_COMMENT: return "WebVTT Comment"; } return NULL; } diff --git a/libavcodec/packet.h b/libavcodec/packet.h index 41485f4527..6b282f04c9 100644 --- a/libavcodec/packet.h +++ b/libavcodec/packet.h @@ -282,6 +282,12 @@ enum AVPacketSideDataType { */ AV_PKT_DATA_DOVI_CONF, +/** + * The optional comment data that comes before the identifier or timing block + * of a WebVTT cue. Must end with a line break. + */ +AV_PKT_DATA_WEBVTT_COMMENT, + /** * The number of side data types. * This is not part of the public API/ABI in the sense that it may diff --git a/libavformat/webvttdec.c b/libavformat/webvttdec.c index bd3d45b382..38c281fe00 100644 --- a/libavformat/webvttdec.c +++ b/libavformat/webvttdec.c @@ -60,7 +60,7 @@ static int64_t read_ts(const char *s) static int webvtt_read_header(AVFormatContext *s) { WebVTTContext *webvtt = s->priv_data; -AVBPrint cue; +AVBPrint cue, com; int res = 0; AVStream *st = avformat_new_stream(s, NULL); @@ -72,6 +72,7 @@ static int webvtt_read_header(AVFormatContext *s) st->disposition |= webvtt->kind; av_bprint_init(&cue,0, AV_BPRINT_SIZE_UNLIMITED); +av_bprint_init(&com,0, AV_BPRINT_SIZE_UNLIMITED); for (;;) { int i; @@ -91,10 +92,15 @@ static int webvtt_read_header(AVFormatContext *s) /* ignore header chunk */ if (!strncmp(p, "\xEF\xBB\xBFWEBVTT", 9) || -!strncmp(p, "WEBVTT", 6) || -!strncmp(p, "NOTE", 4)) +!strncmp(p, "WEBVTT", 6)) continue; +if (!strncmp(p, "NOTE", 4) && +(p[4] == ' ' || p[4] == '\t' || p[4] == '\n' || p[4] == '\r')) { +av_bprintf(&com, "%s%s\n", com.len ? "\n" : "", p); +continue; +} + /* optional cue identifier (can be a number like in SRT or some kind of * chaptering id) */ for (i = 0; p[i] && p[i] != '\n' && p[i] != '\r'; i++) { @@ -159,6 +165,18 @@ static int webvtt_read_header(AVFormatContext *s) SET_SIDE_DATA(identifier, AV_PKT_DATA_WEBVTT_IDENTIFIER); SET_SIDE_DATA(settings, AV_PKT_DATA_WEBVTT_SETTINGS); +if (com.len) { +char *com_str; +if ((res = av_bprint_finalize(&com, &com_str)) < 0) +goto end; + +if ((res = av_packet_add_side_data(sub, AV_PKT_DATA_WEBVTT_COMMENT, com_str, com.len)) < 0) { +av_free(com_str); +goto end; +} + +av_bprint_init(&com,0, AV_BPRINT_SIZE_UNLIMITED); +} } ff_subtitles_queue_finalize(s, &webvtt->q); @@ -167,6 +185,7 @@ end: if (res < 0) ff_subtitles_queue_clean(&webvtt->q); av_bprint_finalize(&cue,NULL); +av_bprint_finalize(&com,NULL); return res; } diff --git a/libavformat/webvttenc.c b/libavformat/webvttenc.c index cbd989dcb6..ecd508db65 100644 --- a/libavformat/webvttenc.c +++ b/libavformat/webvttenc.c @@ -64,11 +64,17 @@ static int webvtt_write_header(AVFormatContext *ctx) static int webvtt_write_packet(AVFormatContext *ctx, AVPacket *pkt) { AVIOContext *pb = ctx->pb; -int id_size, settings_size; -uint8_t *id, *settings; +int id_size, settings_size, comment_size; +uint8_t *id, *settings, *comment; avio_printf(pb, "\n"); +comment = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_COMMENT, + &comment_size); + +if (comment && comment_size > 0) +avio_printf(pb, "%.*s\n", comment_size, comment); + id = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_IDENTIFIER, &id_size); -- 2.26.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] lavu: make AV_TIME_BASE_Q work in C++ code
--- libavutil/avutil.h | 4 1 file changed, 4 insertions(+) diff --git a/libavutil/avutil.h b/libavutil/avutil.h index 4d633156d1..c11b33f466 100644 --- a/libavutil/avutil.h +++ b/libavutil/avutil.h @@ -257,7 +257,11 @@ const char *av_get_media_type_string(enum AVMediaType media_type); * Internal time base represented as fractional value */ +#ifdef __cplusplus +#define AV_TIME_BASE_Q AVRational{1, AV_TIME_BASE} +#else #define AV_TIME_BASE_Q (AVRational){1, AV_TIME_BASE} +#endif /** * @} -- 2.27.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 01/13] lavc/ass: realign ff_ass_subtitle_header_default
--- libavcodec/ass.c | 16 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libavcodec/ass.c b/libavcodec/ass.c index b4f081c819..da05a83d69 100644 --- a/libavcodec/ass.c +++ b/libavcodec/ass.c @@ -80,14 +80,14 @@ int ff_ass_subtitle_header(AVCodecContext *avctx, int ff_ass_subtitle_header_default(AVCodecContext *avctx) { return ff_ass_subtitle_header(avctx, ASS_DEFAULT_FONT, - ASS_DEFAULT_FONT_SIZE, - ASS_DEFAULT_COLOR, - ASS_DEFAULT_BACK_COLOR, - ASS_DEFAULT_BOLD, - ASS_DEFAULT_ITALIC, - ASS_DEFAULT_UNDERLINE, - ASS_DEFAULT_BORDERSTYLE, - ASS_DEFAULT_ALIGNMENT); + ASS_DEFAULT_FONT_SIZE, + ASS_DEFAULT_COLOR, + ASS_DEFAULT_BACK_COLOR, + ASS_DEFAULT_BOLD, + ASS_DEFAULT_ITALIC, + ASS_DEFAULT_UNDERLINE, + ASS_DEFAULT_BORDERSTYLE, + ASS_DEFAULT_ALIGNMENT); } char *ff_ass_get_dialog(int readorder, int layer, const char *style, -- 2.24.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 02/13] lavc/ass: add support for configuring default style via AVOptions
--- libavcodec/ass.c | 154 ++- libavcodec/ass.h | 106 +++- 2 files changed, 215 insertions(+), 45 deletions(-) diff --git a/libavcodec/ass.c b/libavcodec/ass.c index da05a83d69..65942a2567 100644 --- a/libavcodec/ass.c +++ b/libavcodec/ass.c @@ -24,57 +24,119 @@ #include "libavutil/avassert.h" #include "libavutil/avstring.h" #include "libavutil/bprint.h" +#include "libavutil/bswap.h" #include "libavutil/common.h" +static int invert_ass_alpha(uint32_t c) +{ +uint32_t a = c >> 24; +return ((255 - a) << 24) | (c & 0xff); +} + +#define CL_FF2ASS(c) invert_ass_alpha(av_le2ne32(c)) +#define CL_ASS2FF(c) av_le2ne32(invert_ass_alpha(c)) + +int ff_ass_bprint_style(AVBPrint *buf, const FFASSStyle *style) +{ +av_bprintf(buf, + "Style: " + "%s," /* Name */ + "%s,%g," /* Font{name,size} */ + "&H%x,&H%x,&H%x,&H%x," /* {Primary,Secondary,Outline,Back}Colour */ + "%d,%d,%d,%d," /* Bold, Italic, Underline, StrikeOut */ + "%g,%g," /* Scale{X,Y} */ + "%g,%g," /* Spacing, Angle */ + "%d,%g,%g,"/* BorderStyle, Outline, Shadow */ + "%d,%d,%d,%d," /* Alignment, Margin[LRV] */ + "0\r\n", /* Encoding */ + style->name ? style->name : "Default", + style->font ? style->font : ASS_DEFAULT_FONT, style->font_size, + CL_FF2ASS(style->color), CL_FF2ASS(style->color2), + CL_FF2ASS(style->outline_color), CL_FF2ASS(style->back_color), + style->bold, style->italic, style->underline, style->strikeout, + style->scale_x, style->scale_y, + style->spacing, style->angle, + style->border_style, style->outline, style->shadow, + style->alignment, style->margin_l, style->margin_r, style->margin_v); + +return 0; // Not currently possible to detect bprintf errors +} + +int ff_ass_subtitle_header2(AVCodecContext *avctx, int res_x, int res_y, const FFASSStyle *style) +{ +int ret = 0; +AVBPrint buf; +av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC); +av_bprintf(&buf, + "[Script Info]\r\n" + "; Script generated by FFmpeg/Lavc%s\r\n" + "ScriptType: v4.00+\r\n" + "PlayResX: %d\r\n" + "PlayResY: %d\r\n" + "\r\n" + "[V4+ Styles]\r\n" + + /* ASSv4+ header */ + "Format: Name, " + "Fontname, Fontsize, " + "PrimaryColour, SecondaryColour, OutlineColour, BackColour, " + "Bold, Italic, Underline, StrikeOut, " + "ScaleX, ScaleY, " + "Spacing, Angle, " + "BorderStyle, Outline, Shadow, " + "Alignment, MarginL, MarginR, MarginV, " + "Encoding\r\n", + !(avctx->flags & AV_CODEC_FLAG_BITEXACT) ? AV_STRINGIFY(LIBAVCODEC_VERSION) : "", + res_x, res_y); + +if ((ret = ff_ass_bprint_style(&buf, style) < 0)) +goto fail; + +av_bprintf(&buf, + "\r\n" + "[Events]\r\n" + "Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text\r\n"); + +if ((ret = av_bprint_finalize(&buf, (char**)&avctx->subtitle_header)) < 0) +return ret; + +avctx->subtitle_header_size = buf.len; +return 0; + +fail: +av_bprint_finalize(&buf, NULL); +return ret; +} + +int ff_ass_subtitle_header_from_opts(AVCodecContext *avctx, const FFASSHeaderOptions *opts) +{ +return ff_ass_subtitle_header2(avctx, opts->res_x, opts->res_y, &opts->style); +} + int ff_ass_subtitle_header(AVCodecContext *avctx, const char *font, int font_size, int color, int back_color, int bold, int italic, int underline, int border_style, int alignment) { -avctx->subtitle_header = av_asprintf( - "[Script Info]\r\n" - "; Script generated by FFmpeg/Lavc%s\r\n" - "ScriptType: v4.00+\r\n" - "PlayResX: %d\r\n" - "PlayResY: %d\r\n" - "\r\n" - "[V4+ Styles]\r\n" - - /* ASSv4 header */ - "Format: Name, " - "Fontname, Fontsize, " - "PrimaryColour, SecondaryColour, OutlineColour, BackColour, " - "Bold, Italic, Underline, StrikeOut, " - "ScaleX, ScaleY, " - "Spacing, Angle, " - "BorderStyle, Outline, Shadow, " - "Alignment, MarginL, MarginR, MarginV, " - "Encoding\r\n" - - "Style: " - "Default," /* Name */ - "%s,%d," /* Font{nam
[FFmpeg-devel] [PATCH 03/13] lavc/srtdec: add support for configuring default style via AVOptions
--- libavcodec/srtdec.c | 8 +++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libavcodec/srtdec.c b/libavcodec/srtdec.c index ecc0801595..8d3b3cfc9e 100644 --- a/libavcodec/srtdec.c +++ b/libavcodec/srtdec.c @@ -85,6 +85,8 @@ static int srt_decode_frame(AVCodecContext *avctx, return avpkt->size; } +ASS_GENERIC_CLASS(srt, SubRip) + #if CONFIG_SRT_DECODER /* deprecated decoder */ AVCodec ff_srt_decoder = { @@ -96,18 +98,22 @@ AVCodec ff_srt_decoder = { .decode = srt_decode_frame, .flush= ff_ass_decoder_flush, .priv_data_size = sizeof(FFASSDecoderContext), +.priv_class = &srt_decoder_class, }; #endif +ASS_GENERIC_CLASS(subrip, SubRip) + #if CONFIG_SUBRIP_DECODER AVCodec ff_subrip_decoder = { .name = "subrip", .long_name= NULL_IF_CONFIG_SMALL("SubRip subtitle"), .type = AVMEDIA_TYPE_SUBTITLE, .id = AV_CODEC_ID_SUBRIP, -.init = ff_ass_subtitle_header_default, +.init = ff_ass_subtitle_header_options, .decode = srt_decode_frame, .flush= ff_ass_decoder_flush, .priv_data_size = sizeof(FFASSDecoderContext), +.priv_class = &subrip_decoder_class, }; #endif -- 2.24.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 04/13] lavc/webvttdec: add support for configuring default style via AVOptions
--- libavcodec/webvttdec.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/webvttdec.c b/libavcodec/webvttdec.c index 7b2d1750de..494de08884 100644 --- a/libavcodec/webvttdec.c +++ b/libavcodec/webvttdec.c @@ -98,13 +98,16 @@ static int webvtt_decode_frame(AVCodecContext *avctx, return avpkt->size; } +ASS_GENERIC_CLASS(webvtt, WebVTT) + AVCodec ff_webvtt_decoder = { .name = "webvtt", .long_name = NULL_IF_CONFIG_SMALL("WebVTT subtitle"), .type = AVMEDIA_TYPE_SUBTITLE, .id = AV_CODEC_ID_WEBVTT, .decode = webvtt_decode_frame, -.init = ff_ass_subtitle_header_default, +.init = ff_ass_subtitle_header_options, .flush = ff_ass_decoder_flush, .priv_data_size = sizeof(FFASSDecoderContext), +.priv_class = &webvtt_decoder_class, }; -- 2.24.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 11/13] lavc/samidec: add support for configuring default style via AVOptions
--- libavcodec/samidec.c | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libavcodec/samidec.c b/libavcodec/samidec.c index e32f238c62..8804210700 100644 --- a/libavcodec/samidec.c +++ b/libavcodec/samidec.c @@ -30,12 +30,14 @@ #include "htmlsubtitles.h" typedef struct { +AVClass *class; +int readorder; +FFASSHeaderOptions common; AVBPrint source; AVBPrint content; AVBPrint encoded_source; AVBPrint encoded_content; AVBPrint full; -int readorder; } SAMIContext; static int sami_paragraph_to_ass(AVCodecContext *avctx, const char *src) @@ -159,7 +161,7 @@ static av_cold int sami_init(AVCodecContext *avctx) av_bprint_init(&sami->encoded_source, 0, 2048); av_bprint_init(&sami->encoded_content, 0, 2048); av_bprint_init(&sami->full,0, 2048); -return ff_ass_subtitle_header_default(avctx); +return ff_ass_subtitle_header_from_opts(avctx, &sami->common); } static av_cold int sami_close(AVCodecContext *avctx) @@ -180,6 +182,8 @@ static void sami_flush(AVCodecContext *avctx) sami->readorder = 0; } +ASS_GENERIC_CLASS(sami, SAMI) + AVCodec ff_sami_decoder = { .name = "sami", .long_name = NULL_IF_CONFIG_SMALL("SAMI subtitle"), @@ -190,4 +194,5 @@ AVCodec ff_sami_decoder = { .close = sami_close, .decode = sami_decode_frame, .flush = sami_flush, +.priv_class = &sami_decoder_class, }; -- 2.24.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 07/13] lavc/subviewerdec: add support for configuring default style via AVOptions
--- libavcodec/subviewerdec.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/subviewerdec.c b/libavcodec/subviewerdec.c index 805c7dd547..7fbcf54d4c 100644 --- a/libavcodec/subviewerdec.c +++ b/libavcodec/subviewerdec.c @@ -65,13 +65,16 @@ static int subviewer_decode_frame(AVCodecContext *avctx, return avpkt->size; } +ASS_GENERIC_CLASS(subviewer, SubViewer) + AVCodec ff_subviewer_decoder = { .name = "subviewer", .long_name = NULL_IF_CONFIG_SMALL("SubViewer subtitle"), .type = AVMEDIA_TYPE_SUBTITLE, .id = AV_CODEC_ID_SUBVIEWER, .decode = subviewer_decode_frame, -.init = ff_ass_subtitle_header_default, +.init = ff_ass_subtitle_header_options, .flush = ff_ass_decoder_flush, .priv_data_size = sizeof(FFASSDecoderContext), +.priv_class = &subviewer_decoder_class, }; -- 2.24.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 09/13] lavc/mpl2dec: add support for configuring default style via AVOptions
--- libavcodec/mpl2dec.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/mpl2dec.c b/libavcodec/mpl2dec.c index 409e4b3708..f426f3080b 100644 --- a/libavcodec/mpl2dec.c +++ b/libavcodec/mpl2dec.c @@ -81,13 +81,16 @@ static int mpl2_decode_frame(AVCodecContext *avctx, void *data, return avpkt->size; } +ASS_GENERIC_CLASS(mpl2, MPL2) + AVCodec ff_mpl2_decoder = { .name = "mpl2", .long_name = NULL_IF_CONFIG_SMALL("MPL2 subtitle"), .type = AVMEDIA_TYPE_SUBTITLE, .id = AV_CODEC_ID_MPL2, .decode = mpl2_decode_frame, -.init = ff_ass_subtitle_header_default, +.init = ff_ass_subtitle_header_options, .flush = ff_ass_decoder_flush, .priv_data_size = sizeof(FFASSDecoderContext), +.priv_class = &mpl2_decoder_class, }; -- 2.24.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 06/13] lavc/jacosubdec: add support for configuring default style via AVOptions
--- libavcodec/jacosubdec.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/jacosubdec.c b/libavcodec/jacosubdec.c index cdb372af58..b0d8327b35 100644 --- a/libavcodec/jacosubdec.c +++ b/libavcodec/jacosubdec.c @@ -193,13 +193,16 @@ end: return avpkt->size; } +ASS_GENERIC_CLASS(jacosub, JACOsub) + AVCodec ff_jacosub_decoder = { .name = "jacosub", .long_name = NULL_IF_CONFIG_SMALL("JACOsub subtitle"), .type = AVMEDIA_TYPE_SUBTITLE, .id = AV_CODEC_ID_JACOSUB, -.init = ff_ass_subtitle_header_default, +.init = ff_ass_subtitle_header_options, .decode = jacosub_decode_frame, .flush = ff_ass_decoder_flush, .priv_data_size = sizeof(FFASSDecoderContext), +.priv_class = &jacosub_decoder_class, }; -- 2.24.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 13/13] lavc: bump micro version
--- libavcodec/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/version.h b/libavcodec/version.h index 195e21bfbe..d11beb7885 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #define LIBAVCODEC_VERSION_MAJOR 58 #define LIBAVCODEC_VERSION_MINOR 52 -#define LIBAVCODEC_VERSION_MICRO 100 +#define LIBAVCODEC_VERSION_MICRO 101 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ -- 2.24.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 12/13] lavc/libzvbi-teletextdec: add support for configuring default style via AVOptions
--- libavcodec/libzvbi-teletextdec.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libavcodec/libzvbi-teletextdec.c b/libavcodec/libzvbi-teletextdec.c index 3515f33924..018b350511 100644 --- a/libavcodec/libzvbi-teletextdec.c +++ b/libavcodec/libzvbi-teletextdec.c @@ -78,11 +78,14 @@ typedef struct TeletextContext int last_pgno; int last_p5; int last_ass_alignment; + +FFASSHeaderOptions common; } TeletextContext; static int my_ass_subtitle_header(AVCodecContext *avctx) { -int ret = ff_ass_subtitle_header_default(avctx); +TeletextContext *ctx = avctx->priv_data; +int ret = ff_ass_subtitle_header_from_opts(avctx, &ctx->common); char *new_header; uint8_t *event_pos; @@ -756,7 +759,7 @@ static int teletext_init_decoder(AVCodecContext *avctx) case 0: return 0; case 1: -return ff_ass_subtitle_header_default(avctx); +return ff_ass_subtitle_header_from_opts(avctx, &ctx->common); case 2: return my_ass_subtitle_header(avctx); } @@ -803,6 +806,7 @@ static const AVOption options[] = { {"txt_duration","display duration of teletext pages in msecs", OFFSET(sub_duration), AV_OPT_TYPE_INT,{.i64 = -1}, -1, 8640, SD}, {"txt_transparent", "force transparent background of the teletext", OFFSET(transparent_bg), AV_OPT_TYPE_INT,{.i64 = 0},0, 1,SD}, {"txt_opacity", "set opacity of the transparent background", OFFSET(opacity),AV_OPT_TYPE_INT,{.i64 = -1}, -1, 255, SD}, +ASS_HEADER_AVOPTIONS(TeletextContext, common) { NULL }, }; -- 2.24.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 05/13] lavc/realtextdec: add support for configuring default style via AVOptions
--- libavcodec/realtextdec.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/realtextdec.c b/libavcodec/realtextdec.c index 5084781123..e888946f13 100644 --- a/libavcodec/realtextdec.c +++ b/libavcodec/realtextdec.c @@ -74,13 +74,16 @@ static int realtext_decode_frame(AVCodecContext *avctx, return avpkt->size; } +ASS_GENERIC_CLASS(realtext, RealText) + AVCodec ff_realtext_decoder = { .name = "realtext", .long_name = NULL_IF_CONFIG_SMALL("RealText subtitle"), .type = AVMEDIA_TYPE_SUBTITLE, .id = AV_CODEC_ID_REALTEXT, .decode = realtext_decode_frame, -.init = ff_ass_subtitle_header_default, +.init = ff_ass_subtitle_header_options, .flush = ff_ass_decoder_flush, .priv_data_size = sizeof(FFASSDecoderContext), +.priv_class = &realtext_decoder_class, }; -- 2.24.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 08/13] lavc/samidec: add support for configuring default style via AVOptions
--- libavcodec/textdec.c | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libavcodec/textdec.c b/libavcodec/textdec.c index 964da72ad5..72eb7c4795 100644 --- a/libavcodec/textdec.c +++ b/libavcodec/textdec.c @@ -30,15 +30,17 @@ typedef struct { AVClass *class; +int readorder; +FFASSHeaderOptions common; const char *linebreaks; int keep_ass_markup; -int readorder; } TextContext; #define OFFSET(x) offsetof(TextContext, x) #define SD AV_OPT_FLAG_SUBTITLE_PARAM | AV_OPT_FLAG_DECODING_PARAM static const AVOption options[] = { { "keep_ass_markup", "Set if ASS tags must be escaped", OFFSET(keep_ass_markup), AV_OPT_TYPE_BOOL, {.i64=0}, 0, 1, .flags=SD }, +ASS_HEADER_AVOPTIONS(TextContext, common) { NULL } }; @@ -88,7 +90,7 @@ AVCodec ff_text_decoder = { .type = AVMEDIA_TYPE_SUBTITLE, .id = AV_CODEC_ID_TEXT, .decode = text_decode_frame, -.init = ff_ass_subtitle_header_default, +.init = ff_ass_subtitle_header_options, .priv_class = &text_decoder_class, .flush = text_flush, }; @@ -100,7 +102,7 @@ static int linebreak_init(AVCodecContext *avctx) { TextContext *text = avctx->priv_data; text->linebreaks = "|"; -return ff_ass_subtitle_header_default(avctx); +return ff_ass_subtitle_header_from_opts(avctx, &text->common); } #if CONFIG_VPLAYER_DECODER -- 2.24.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 10/13] lavc/movtextdec: add support for configuring default style via AVOptions
--- libavcodec/movtextdec.c | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libavcodec/movtextdec.c b/libavcodec/movtextdec.c index c38c5edce6..0bb03fc141 100644 --- a/libavcodec/movtextdec.c +++ b/libavcodec/movtextdec.c @@ -86,6 +86,9 @@ typedef struct { } TextWrapBox; typedef struct { +AVClass *class; +int readorder; +FFASSHeaderOptions common; StyleBox **s; StyleBox *s_temp; HighlightBox h; @@ -99,7 +102,6 @@ typedef struct { uint64_t tracksize; int size_var; int count_s, count_f; -int readorder; } MovTextContext; typedef struct { @@ -453,7 +455,7 @@ static int mov_text_init(AVCodecContext *avctx) { m->d.underline, ASS_DEFAULT_BORDERSTYLE, m->d.alignment); } else -return ff_ass_subtitle_header_default(avctx); +return ff_ass_subtitle_header_from_opts(avctx, &m->common); } static int mov_text_decode_frame(AVCodecContext *avctx, @@ -567,6 +569,8 @@ static void mov_text_flush(AVCodecContext *avctx) m->readorder = 0; } +ASS_GENERIC_CLASS(mov_text, "3GPP Timed Text") + AVCodec ff_movtext_decoder = { .name = "mov_text", .long_name= NULL_IF_CONFIG_SMALL("3GPP Timed Text subtitle"), @@ -577,4 +581,5 @@ AVCodec ff_movtext_decoder = { .decode = mov_text_decode_frame, .close= mov_text_decode_close, .flush= mov_text_flush, +.priv_class = &mov_text_decoder_class, }; -- 2.24.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-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH 02/13] lavc/ass: add support for configuring default style via AVOptions
> On Jan 27, 2020, at 08:28, Moritz Barsnick wrote: > > On Fri, Jan 24, 2020 at 20:01:49 -0600, rcombs wrote: >> +static int invert_ass_alpha(uint32_t c) >> +{ >> +uint32_t a = c >> 24; >> +return ((255 - a) << 24) | (c & 0xff); >> +} > > You're inverting the "leftmost" 8 bits of c? Can't you just make this > > return (c ^ 0xff00); > > ? Even inline, or just a macro? (Or perhaps I'm missing something, and > (255 - a) is not always the same as (a ^ 0xff). These are indeed equivalent, but I thought this more clearly conveyed the intent here ("convert between 0=transparent and 0=opaque by inverting the 0-255 alpha field"). > >> +#define ASS_HEADER_AVOPTIONS(cls, obj) \ >> +{ "res", "script resolution", offsetof(cls, obj.res_x), >> AV_OPT_TYPE_IMAGE_SIZE, { .str = ASS_DEFAULT_PLAYRES_STR }, 1, INT_MAX, >> ASS_DS }, \ >> +{ "font", "default font name", offsetof(cls, obj.style.font), >> AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, ASS_DS }, \ >> +{ "font_size", "default font name", offsetof(cls, obj.style.font_size), >> AV_OPT_TYPE_DOUBLE, { .dbl = ASS_DEFAULT_FONT_SIZE }, 0, INT_MAX, ASS_DS }, >> \ >> +{ "color", "default text color", offsetof(cls, obj.style.color), >> AV_OPT_TYPE_COLOR, { .str = ASS_DEFAULT_COLOR_STR }, 0, 0, ASS_DS }, \ >> +{ "color2", "default secondary text color", offsetof(cls, >> obj.style.color2), AV_OPT_TYPE_COLOR, { .str = ASS_DEFAULT_COLOR_STR }, 0, >> 0, ASS_DS }, \ >> +{ "outline_color", "default text outline color", offsetof(cls, >> obj.style.outline_color), AV_OPT_TYPE_COLOR, { .str = ASS_DEFAULT_BCOLOR_STR >> }, 0, 0, ASS_DS }, \ >> +{ "back_color", "default text background/shadow color", offsetof(cls, >> obj.style.back_color), AV_OPT_TYPE_COLOR, { .str = ASS_DEFAULT_BCOLOR_STR }, >> 0, 0, ASS_DS }, \ >> +{ "bold", "default text boldness (0/1/weight value)", offsetof(cls, >> obj.style.bold), AV_OPT_TYPE_INT, { .i64 = ASS_DEFAULT_BOLD }, 0, INT_MAX, >> ASS_DS }, \ >> +{ "italic", "default text italics", offsetof(cls, obj.style.bold), >> AV_OPT_TYPE_BOOL, { .i64 = ASS_DEFAULT_ITALIC }, 0, 1, ASS_DS }, \ >> +{ "underline", "default text italics", offsetof(cls, >> obj.style.underline), AV_OPT_TYPE_BOOL, { .i64 = ASS_DEFAULT_UNDERLINE }, 0, >> 1, ASS_DS }, \ >> +{ "strikeout", "default text strikeout", offsetof(cls, >> obj.style.strikeout), AV_OPT_TYPE_BOOL, { .i64 = ASS_DEFAULT_STRIKEOUT }, 0, >> 1, ASS_DS }, \ >> +{ "scale_x", "default horizontal text scale", offsetof(cls, >> obj.style.scale_x), AV_OPT_TYPE_DOUBLE, { .dbl = ASS_DEFAULT_SCALE_X }, 0, >> INT_MAX, ASS_DS }, \ >> +{ "scale_y", "default vertical text scale", offsetof(cls, >> obj.style.scale_y), AV_OPT_TYPE_DOUBLE, { .dbl = ASS_DEFAULT_SCALE_Y }, 0, >> INT_MAX, ASS_DS }, \ >> +{ "border_style", "default text border style", offsetof(cls, >> obj.style.border_style), AV_OPT_TYPE_INT, { .i64 = ASS_DEFAULT_BORDERSTYLE >> }, 1, 4, ASS_DS }, \ >> +{ "outline", "default text outline width", offsetof(cls, >> obj.style.outline), AV_OPT_TYPE_DOUBLE, { .dbl = ASS_DEFAULT_OUTLINE }, 0, >> INT_MAX, ASS_DS }, \ >> +{ "shadow", "default text shadow drop", offsetof(cls, >> obj.style.shadow), AV_OPT_TYPE_DOUBLE, { .dbl = ASS_DEFAULT_SHADOW }, 0, >> INT_MAX, ASS_DS }, \ >> +{ "alignment", "default text alignment", offsetof(cls, >> obj.style.alignment), AV_OPT_TYPE_INT, { .i64 = ASS_DEFAULT_ALIGNMENT }, 1, >> 9, ASS_DS }, \ >> +{ "margin_l", "default left margin", offsetof(cls, obj.style.margin_l), >> AV_OPT_TYPE_INT, { .i64 = ASS_DEFAULT_MARGINL }, 0, INT_MAX, ASS_DS }, \ >> +{ "margin_r", "default right margin", offsetof(cls, >> obj.style.margin_r), AV_OPT_TYPE_INT, { .i64 = ASS_DEFAULT_MARGINR }, 0, >> INT_MAX, ASS_DS }, \ >> +{ "margin_v", "default vertical margin", offsetof(cls, >> obj.style.margin_v), AV_OPT_TYPE_INT, { .i64 = ASS_DEFAULT_MARGINV }, 0, >> INT_MAX, ASS_DS }, \ > > To make this more readable, you should also MACROify the "offsetof(cls, > obj.X)", as many other options sections do it, and perhaps align the > entries' columns. I shied away from this to avoid polluting the global macro space (since this is in a header); I can do it anyway if you prefer (it's not like it's a public header, at least). > > Moritz > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] lavc/ac3dec: disable DRC by default
This issue has been argued before, with the status quo being preserved under the logic that the spec says this parameter is supposed to default to 1, and that we should follow the spec. The spec was misguided, and thus so was blindly following it. The (E-)AC3 DRC architecture is a clever optimization: the (relatively) heavy lifting of analyzing the audio data and calculating the per-block gain needed is offloaded to the encoder, so that the player only needs to apply the gain coefficients (at the desired scale) to get the DRC effect. In theory, this seems like an efficient way to reduce the computational complexity of playback. In practice, this isn't actually the case. Actual (E-)AC3 is not guaranteed to have useful DRC metadata at all. For instance, ffmpeg's encoder has never supported generating it. This means that a user who wants DRC can't merely use the internal filter for (E-)AC3 and an external one for other codecs; they have to use an external filter at al times! They could also apply the internal filter, but it's hard to see what benefit this would give. I've also seen it argued that (E-)AC3 DRC does a better job of reproducing the intent of the audio mastering engineer than playback-time DRC can. I don't believe this argument is credible either. The official encoder does support passing in custom gain values, but it doesn't appear that this capability is frequently used. I'm not aware of any tooling that actually passes custom data into the encoder's loudness parameters, and Dolby's first-party GUI tools don't appear to support doing so. Dolby's own tools expose the parameters available in the encoder itself, which comprise a set of 5 presets with no customizability: "Film Standard", "Film Light", "Music Standard", "Music Light", and "Speech", along with the null profile. These profiles are documented (minus their time constants) in this PDF on the Dolby website: https://www.dolby.com/us/en/technologies/a-guide-to-dolby-metadata.pdf These are not advanced filters; they don't provide any complex control to the content producer, who can't even tune the details or _know_ the time constants. Even if the mastering engineer did want to customize the DRC with some custom tool, in most cases I don't think they'd have the ability to do so because they don't have access to the point in the pipeline where audio encoding occurs. In TV, audio is often encoded live rather than streaming a pre-compressed bitstream. In web streaming, masters are usually delivered with uncompressed PCM audio and no loudness metadata, and encoded using stock configurations. Film for DVD or Blu-Ray is the only plausible case, but again, I'm not aware of any widely-used tooling for this with any more configurability than Dolby's. Additional context: the AudioToolbox (E-)AC3 decoder (which is Dolby's) seems not to apply DRC; you can see this by comparing the output of ffmpeg's decoder with drc_scale set to 0 and 1 with the output of the (e)ac3_at decoder. So to summarize: - (E-)AC3 DRC is designed as an optimization for the decoder - There's no inherent reason (E-)AC3 _requires_ DRC for playback more than any other codec - Due to inconsistent encoding, it can't be relied upon - There's no reason to believe it's better than decode-side DRC when it works - It's not universally applied by other software I think this makes a compelling case to stop applying (E-)AC3 DRC by default. The user can enable it on their own if they prefer, but I believe having it off by default will improve the apparent quality of (E-)AC3 playback for the vast majority of ffmpeg users, and improve the consistency between (E-)AC3 playback and playback of any other codec. Thus, this patch. --- libavcodec/ac3dec_fixed.c | 2 +- libavcodec/ac3dec_float.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/ac3dec_fixed.c b/libavcodec/ac3dec_fixed.c index bd66175d50..312616edfd 100644 --- a/libavcodec/ac3dec_fixed.c +++ b/libavcodec/ac3dec_fixed.c @@ -169,7 +169,7 @@ static void ac3_downmix_c_fixed16(int16_t **samples, int16_t **matrix, static const AVOption options[] = { { "cons_noisegen", "enable consistent noise generation", OFFSET(consistent_noise_generation), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, PAR }, -{ "drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), AV_OPT_TYPE_FLOAT, {.dbl = 1.0}, 0.0, 6.0, PAR }, +{ "drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), AV_OPT_TYPE_FLOAT, {.dbl = 0.0}, 0.0, 6.0, PAR }, { "heavy_compr", "enable heavy dynamic range compression", OFFSET(heavy_compression), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, PAR }, { NULL}, }; diff --git a/libavcodec/ac3dec_float.c b/libavcodec/ac3dec_float.c index b85a4ce336..69bd47aa6a 100644 --- a/libavcodec/ac3dec_float.c +++ b/libavcodec/ac3dec_float.c @@ -33,7 +33,7 @@ static const AVOption options[] = { { "cons_noisegen", "enable consistent noise generation",
[FFmpeg-devel] [PATCH] lavc/ac3dec: disable DRC by default
This issue has been argued before, with the status quo being preserved under the logic that the spec says this parameter is supposed to default to 1, and that we should follow the spec. The spec was misguided, and thus so was blindly following it. The (E-)AC3 DRC architecture is a clever optimization: the (relatively) heavy lifting of analyzing the audio data and calculating the per-block gain needed is offloaded to the encoder, so that the player only needs to apply the gain coefficients (at the desired scale) to get the DRC effect. In theory, this seems like an efficient way to reduce the computational complexity of playback. In practice, this isn't actually the case. Actual (E-)AC3 is not guaranteed to have useful DRC metadata at all. For instance, ffmpeg's encoder has never supported generating it. This means that a user who wants DRC can't merely use the internal filter for (E-)AC3 and an external one for other codecs; they have to use an external filter at al times! They could also apply the internal filter, but it's hard to see what benefit this would give. I've also seen it argued that (E-)AC3 DRC does a better job of reproducing the intent of the audio mastering engineer than playback-time DRC can. I don't believe this argument is credible either. The official encoder does support passing in custom gain values, but it doesn't appear that this capability is frequently used. I'm not aware of any tooling that actually passes custom data into the encoder's loudness parameters, and Dolby's first-party GUI tools don't appear to support doing so. Dolby's own tools expose the parameters available in the encoder itself, which comprise a set of 5 presets with no customizability: "Film Standard", "Film Light", "Music Standard", "Music Light", and "Speech", along with the null profile. These profiles are documented (minus their time constants) in this PDF on the Dolby website: https://www.dolby.com/us/en/technologies/a-guide-to-dolby-metadata.pdf These are not advanced filters; they don't provide any complex control to the content producer, who can't even tune the details or _know_ the time constants. Even if the mastering engineer did want to customize the DRC with some custom tool, in most cases I don't think they'd have the ability to do so because they don't have access to the point in the pipeline where audio encoding occurs. In TV, audio is often encoded live rather than streaming a pre-compressed bitstream. In web streaming, masters are usually delivered with uncompressed PCM audio and no loudness metadata, and encoded using stock configurations. Film for DVD or Blu-Ray is the only plausible case, but again, I'm not aware of any widely-used tooling for this with any more configurability than Dolby's. Additional context: the AudioToolbox (E-)AC3 decoder (which is Dolby's) seems not to apply DRC; you can see this by comparing the output of ffmpeg's decoder with drc_scale set to 0 and 1 with the output of the (e)ac3_at decoder. So to summarize: - (E-)AC3 DRC is designed as an optimization for the decoder - There's no inherent reason (E-)AC3 _requires_ DRC for playback more than any other codec - Due to inconsistent encoding, it can't be relied upon - There's no reason to believe it's better than decode-side DRC when it works - It's not universally applied by other software I think this makes a compelling case to stop applying (E-)AC3 DRC by default. The user can enable it on their own if they prefer, but I believe having it off by default will improve the apparent quality of (E-)AC3 playback for the vast majority of ffmpeg users, and improve the consistency between (E-)AC3 playback and playback of any other codec. Thus, this patch. --- libavcodec/ac3dec_fixed.c | 2 +- libavcodec/ac3dec_float.c | 2 +- tests/fate/ac3.mak| 32 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/libavcodec/ac3dec_fixed.c b/libavcodec/ac3dec_fixed.c index bd66175d50..312616edfd 100644 --- a/libavcodec/ac3dec_fixed.c +++ b/libavcodec/ac3dec_fixed.c @@ -169,7 +169,7 @@ static void ac3_downmix_c_fixed16(int16_t **samples, int16_t **matrix, static const AVOption options[] = { { "cons_noisegen", "enable consistent noise generation", OFFSET(consistent_noise_generation), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, PAR }, -{ "drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), AV_OPT_TYPE_FLOAT, {.dbl = 1.0}, 0.0, 6.0, PAR }, +{ "drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), AV_OPT_TYPE_FLOAT, {.dbl = 0.0}, 0.0, 6.0, PAR }, { "heavy_compr", "enable heavy dynamic range compression", OFFSET(heavy_compression), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, PAR }, { NULL}, }; diff --git a/libavcodec/ac3dec_float.c b/libavcodec/ac3dec_float.c index b85a4ce336..69bd47aa6a 100644 --- a/libavcodec/ac3dec_float.c +++ b/libavcodec/ac3dec_float.c @@ -33,7 +33,7 @@ static const AVOption options[
Re: [FFmpeg-devel] [PATCH] lavc/ac3dec: disable DRC by default
> On Feb 1, 2020, at 13:43, Derek Buitenhuis wrote: > > On 01/02/2020 19:34, rcombs wrote: >> This issue has been argued before, with the status quo being preserved under >> the logic that the spec says this parameter is supposed to default to 1, >> and that we should follow the spec. The spec was misguided, and thus so was >> blindly following it. > > If "I don't agree with the spec" or "this spec does something stupid" were > valid > arguments, we may as well not have specs at all, and FFmpeg would have a lot > more > garbage in it. You can write at length why you think it's bad, but that does > not > negeate the fact that it's the spec, I'm not sure why the spec should have any bearing on the defaults of configurable options, particularly when those defaults result in unexpected behavior that's unlike that used for any other codec. > and the defacto way to handle decoding AC-3. Is it, though? My understanding is that AV receivers usually only enable AC3 DRC in "night mode" or the like, and few even provide a fully-tunable setting for it. Apple's decoder in AudioToolbox (implemented on top of Dolby's) doesn't provide the feature at all (I haven't checked what Win32 Media Foundation does yet). So where does this "de facto" situation come from, other than lavc itself? Meanwhile, Dolby's own decoder applies digital dialog normalization by default (contrary to how the spec says it should be applied downstream), and I haven't seen anyone arguing that lavc should do that. Additionally, TrueHD has a very similar DRC feature that lavc doesn't support whatsoever, and nobody seems to mind. One other thing I neglected to mention in the commit message: the actual audio encoded in an (E)AC3 track often has levels similar to those of a track in another codec (PCM, AAC, etc) from the same or other sources, but sounds very different when both are decoded with lavc. For instance, Netflix's EAC3 sounds about the same as BD audio of the same content when decoded without DRC, but in lavc-based players by default, it sounds, well... compressed. This had led to an impression in the anime community that Netflix applies excessive DRC to their EAC3 streams at encode-time, and thus that those streams were low-quality and should be avoided. > > And I'd rather not give Dolby more ammunition for their anti-FOSS FUD > campaign. > > For whatever my opinion is worth nowadays on this list, it's a very, very hard > NAK from me. > > - Derek > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH] lavc/ac3dec: disable DRC by default
> On Feb 1, 2020, at 15:55, Derek Buitenhuis wrote: > >>> and the defacto way to handle decoding AC-3. >> >> Is it, though? My understanding is that AV receivers usually only enable AC3 >> DRC in "night mode" or the like, and few even provide a fully-tunable >> setting for it. Apple's decoder in AudioToolbox (implemented on top of >> Dolby's) doesn't provide the feature at all (I haven't checked what Win32 >> Media Foundation does yet). So where does this "de facto" situation come >> from, other than lavc itself? > > Because the spec defines what is de facto - it is what defines what AC-3 *is*. > You are choosing to ignore it here because you don't like what's in it. This is "de jure"; "de facto" means how it's actually implemented in practice. >> Meanwhile, Dolby's own decoder applies digital dialog normalization by >> default (contrary to how the spec says it should be applied downstream), and >> I haven't seen anyone arguing that lavc should do that. > > Own decoder from where? Is it officially Dolby branded, or is this Apple > again? Their own decoder IP and reference tool; it's non-public, and it's what Apple's is built on top of. > > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel > > To unsubscribe, visit link above, or email > ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe". ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/3] lavf: add read_flush function to AVInputFormat vtable
--- libavformat/avformat.h | 6 ++ libavformat/utils.c| 4 libavformat/version.h | 4 ++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 9b9b634ec3..1412119342 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -780,6 +780,12 @@ typedef struct AVInputFormat { * @see avdevice_capabilities_free() for more details. */ int (*free_device_capabilities)(struct AVFormatContext *s, struct AVDeviceCapabilitiesQuery *caps); + +/** + * Flush demuxer-internal buffers ahead of a discontinuity in the input byte stream. + * @see avformat_flush() for more details. + */ +void (*read_flush)(struct AVFormatContext *s); } AVInputFormat; /** * @} diff --git a/libavformat/utils.c b/libavformat/utils.c index 123d67800b..c5fbe74c54 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2611,6 +2611,10 @@ int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int avformat_flush(AVFormatContext *s) { ff_read_frame_flush(s); + +if (s->iformat->read_flush) +s->iformat->read_flush(s); + return 0; } diff --git a/libavformat/version.h b/libavformat/version.h index 94fa57614d..741f2e30c5 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -32,8 +32,8 @@ // Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium) // Also please add any ticket numbers that you believe might be affected here #define LIBAVFORMAT_VERSION_MAJOR 58 -#define LIBAVFORMAT_VERSION_MINOR 38 -#define LIBAVFORMAT_VERSION_MICRO 101 +#define LIBAVFORMAT_VERSION_MINOR 39 +#define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ -- 2.24.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/3] lavf/hlsdec: use public avformat_flush function
--- libavformat/hls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/hls.c b/libavformat/hls.c index 1f58e745a7..8181a631b6 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -2295,7 +2295,7 @@ static int hls_read_seek(AVFormatContext *s, int stream_index, /* Reset the pos, to let the mpegts demuxer know we've seeked. */ pls->pb.pos = 0; /* Flush the packet queue of the subdemuxer. */ -ff_read_frame_flush(pls->ctx); +avformat_flush(pls->ctx); pls->seek_timestamp = seek_timestamp; pls->seek_flags = flags; -- 2.24.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 3/3] lavf/matroskadec: add read_flush function
--- libavformat/matroskadec.c | 23 +-- 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 4d7fdab99f..68e424992a 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -3703,6 +3703,21 @@ static int matroska_read_packet(AVFormatContext *s, AVPacket *pkt) return 0; } +static void matroska_read_flush(AVFormatContext *s) +{ +MatroskaDemuxContext *matroska = s->priv_data; +int i; + +matroska_reset_status(matroska, 0, -1); +matroska->resync_pos = -1; +matroska_clear_queue(matroska); +matroska->skip_to_keyframe = 0; +matroska->done = 0; + +for (i = 0; i < s->nb_streams; i++) +s->streams[i]->skip_to_keyframe = 0; +} + static int matroska_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { @@ -3758,12 +3773,7 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index, err: // slightly hackish but allows proper fallback to // the generic seeking code. -matroska_reset_status(matroska, 0, -1); -matroska->resync_pos = -1; -matroska_clear_queue(matroska); -st->skip_to_keyframe = -matroska->skip_to_keyframe = 0; -matroska->done = 0; +matroska_read_flush(s); return -1; } @@ -4200,6 +4210,7 @@ AVInputFormat ff_matroska_demuxer = { .read_packet= matroska_read_packet, .read_close = matroska_read_close, .read_seek = matroska_read_seek, +.read_flush = matroska_read_flush, .mime_type = "audio/webm,audio/x-matroska,video/webm,video/x-matroska" }; -- 2.24.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] configure: unmark FDKAAC as nonfree
Red Hat legal believes the FDK license to be free when using their stripped version (https://github.com/UnitedRPMs/fdk-aac-free/releases), as the patent clause is a no-op now that the relevant patents on that version are expired: https://bugzilla.redhat.com/show_bug.cgi?id=1501522 Plex legal believes that the license is GPL-compatible in general: > I see no issue under GPL here. The reference to patent licenses is advisory > and not a limitation on use. In essence, it says, "you can get a license here > if you want one [implicitly, if you don't, you are at your peril], but you > may not need one because most Android hardware makers already have one that > covers you." There remains some disagreement over which (if any) versions of the FDK SDK are GPL-compatible, but I see no reason for ffmpeg to assert the position that builds linking to it and to GPL code are nonredistributable. The source is available under a license widely understood to fulfill some definition of "free", and the contention around it largely comes down to a technicality. If a user or packager wants to redistribute builds with it at their own risk, I don't believe doing so would cause harm to ffmpeg's developers or community (in contrast with closed-source libraries like NDI and Decklink). --- configure | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure b/configure index ab761c7183..f590f30093 100755 --- a/configure +++ b/configure @@ -1727,7 +1727,6 @@ EXTERNAL_LIBRARY_GPL_LIST=" EXTERNAL_LIBRARY_NONFREE_LIST=" decklink -libfdk_aac openssl libtls " @@ -1768,6 +1767,7 @@ EXTERNAL_LIBRARY_LIST=" libdav1d libdc1394 libdrm +libfdk_aac libflite libfontconfig libfreetype -- 2.24.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 04/15] lavc: add new font pseudo-codecs
--- libavcodec/codec_desc.c | 28 libavcodec/codec_id.h | 4 2 files changed, 32 insertions(+) diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 72ecc1012b..ad044318c7 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -3410,6 +3410,34 @@ static const AVCodecDescriptor codec_descriptors[] = { .long_name = NULL_IF_CONFIG_SMALL("binary data"), .mime_types= MT("application/octet-stream"), }, +{ +.id= AV_CODEC_ID_TTC, +.type = AVMEDIA_TYPE_DATA, +.name = "ttc", +.long_name = NULL_IF_CONFIG_SMALL("OpenType font collection"), +.mime_types= MT("font/collection"), +}, +{ +.id= AV_CODEC_ID_SFNT, +.type = AVMEDIA_TYPE_DATA, +.name = "sfnt", +.long_name = NULL_IF_CONFIG_SMALL("SFNT font"), +.mime_types= MT("font/sfnt", "application/font-sfnt"), +}, +{ +.id= AV_CODEC_ID_WOFF, +.type = AVMEDIA_TYPE_DATA, +.name = "woff", +.long_name = NULL_IF_CONFIG_SMALL("WOFF font"), +.mime_types= MT("font/woff", "application/font-woff"), +}, +{ +.id= AV_CODEC_ID_WOFF2, +.type = AVMEDIA_TYPE_DATA, +.name = "woff2", +.long_name = NULL_IF_CONFIG_SMALL("WOFF version 2 font"), +.mime_types= MT("font/woff2"), +}, { .id= AV_CODEC_ID_WRAPPED_AVFRAME, .type = AVMEDIA_TYPE_VIDEO, diff --git a/libavcodec/codec_id.h b/libavcodec/codec_id.h index e4eca5d580..06e5cdb4cd 100644 --- a/libavcodec/codec_id.h +++ b/libavcodec/codec_id.h @@ -552,6 +552,10 @@ enum AVCodecID { AV_CODEC_ID_DVD_NAV, AV_CODEC_ID_TIMED_ID3, AV_CODEC_ID_BIN_DATA, +AV_CODEC_ID_TTC, +AV_CODEC_ID_SFNT, +AV_CODEC_ID_WOFF, +AV_CODEC_ID_WOFF2, AV_CODEC_ID_PROBE = 0x19000, ///< codec_id is not known (like AV_CODEC_ID_NONE) but lavf should attempt to identify it -- 2.27.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 02/15] lavc/codec_desc: add additional JPEG and BMP MIME types
--- libavcodec/codec_desc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 3dee640360..49a00ad264 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -82,7 +82,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .name = "mjpeg", .long_name = NULL_IF_CONFIG_SMALL("Motion JPEG"), .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSY, -.mime_types= MT("image/jpeg"), +.mime_types= MT("image/jpeg", "image/jpg"), .profiles = NULL_IF_CONFIG_SMALL(ff_mjpeg_profiles), }, { @@ -588,7 +588,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .name = "bmp", .long_name = NULL_IF_CONFIG_SMALL("BMP (Windows and OS/2 bitmap)"), .props = AV_CODEC_PROP_INTRA_ONLY | AV_CODEC_PROP_LOSSLESS, -.mime_types= MT("image/x-ms-bmp"), +.mime_types= MT("image/x-ms-bmp", "image/bmp"), }, { .id= AV_CODEC_ID_CSCD, -- 2.27.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 05/15] lavf/matroskaenc: remove text/plain special-case
--- libavformat/matroskaenc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 233c472b8f..d9caa3e728 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -1706,10 +1706,8 @@ static const char *get_mimetype(const AVStream *st) return t->value; if (st->codecpar->codec_id != AV_CODEC_ID_NONE) { const AVCodecDescriptor *desc = avcodec_descriptor_get(st->codecpar->codec_id); -if (desc && desc->mime_types) { +if (desc && desc->mime_types) return desc->mime_types[0]; -} else if (st->codecpar->codec_id == AV_CODEC_ID_TEXT) -return "text/plain"; } return NULL; -- 2.27.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 13/15] lavf/asfdec: use avcodec_descriptor_get_by_mime_type
--- libavformat/asfdec_f.c | 11 +++ libavformat/asfdec_o.c | 11 +++ 2 files changed, 6 insertions(+), 16 deletions(-) diff --git a/libavformat/asfdec_f.c b/libavformat/asfdec_f.c index e9ddca7151..c35b81550b 100644 --- a/libavformat/asfdec_f.c +++ b/libavformat/asfdec_f.c @@ -218,7 +218,7 @@ static int get_value(AVIOContext *pb, int type, int type2_size) static int asf_read_picture(AVFormatContext *s, int len) { AVPacket pkt = { 0 }; -const CodecMime *mime = ff_id3v2_mime_tags; +const AVCodecDescriptor *cdesc; enum AVCodecID id= AV_CODEC_ID_NONE; char mimetype[64]; uint8_t *desc = NULL; @@ -245,13 +245,8 @@ static int asf_read_picture(AVFormatContext *s, int len) /* picture MIME type */ len -= avio_get_str16le(s->pb, len, mimetype, sizeof(mimetype)); -while (mime->id != AV_CODEC_ID_NONE) { -if (!strncmp(mime->str, mimetype, sizeof(mimetype))) { -id = mime->id; -break; -} -mime++; -} +if ((cdesc = avcodec_descriptor_get_by_mime_type(mimetype, "image"))) +id = cdesc->id; if (id == AV_CODEC_ID_NONE) { av_log(s, AV_LOG_ERROR, "Unknown attached picture mimetype: %s.\n", mimetype); diff --git a/libavformat/asfdec_o.c b/libavformat/asfdec_o.c index 1b10e47907..970748c6cf 100644 --- a/libavformat/asfdec_o.c +++ b/libavformat/asfdec_o.c @@ -359,7 +359,7 @@ static int asf_read_picture(AVFormatContext *s, int len) { ASFContext *asf = s->priv_data; AVPacket pkt = { 0 }; -const CodecMime *mime = ff_id3v2_mime_tags; +const AVCodecDescriptor *cdesc; enum AVCodecID id= AV_CODEC_ID_NONE; char mimetype[64]; uint8_t *desc = NULL; @@ -387,13 +387,8 @@ static int asf_read_picture(AVFormatContext *s, int len) /* picture MIME type */ len -= avio_get_str16le(s->pb, len, mimetype, sizeof(mimetype)); -while (mime->id != AV_CODEC_ID_NONE) { -if (!strncmp(mime->str, mimetype, sizeof(mimetype))) { -id = mime->id; -break; -} -mime++; -} +if ((cdesc = avcodec_descriptor_get_by_mime_type(mimetype, "image"))) +id = cdesc->id; if (id == AV_CODEC_ID_NONE) { av_log(s, AV_LOG_ERROR, "Unknown attached picture mimetype: %s.\n", mimetype); -- 2.27.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 06/15] lavc/codec_desc: add avcodec_descriptor_get_by_mime_type
--- libavcodec/codec_desc.c | 41 + libavcodec/codec_desc.h | 12 libavcodec/version.h| 2 +- 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index ad044318c7..61b7f8d74f 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -21,6 +21,7 @@ #include +#include "libavutil/avstring.h" #include "libavutil/common.h" #include "libavutil/internal.h" @@ -3480,6 +3481,46 @@ const AVCodecDescriptor *avcodec_descriptor_get_by_name(const char *name) return NULL; } +const AVCodecDescriptor *avcodec_descriptor_get_by_mime_type(const char *search, const char *prefix) +{ +const AVCodecDescriptor *desc = NULL; +int len, prefix_len; +if (!search) +return NULL; + +len = strlen(search); +if (!len) +return NULL; + +if (strchr(search, '/')) +prefix = NULL; + +if (prefix) +prefix_len = strlen(prefix); + +while ((desc = avcodec_descriptor_next(desc))) { +if (desc->mime_types) { +int i; +for (i = 0; desc->mime_types[i]; i++) { +const char *check = desc->mime_types[i]; +if (prefix) { +if (!av_strncasecmp(check, prefix, prefix_len) && +check[prefix_len] == '/') +check += prefix_len + 1; +else +continue; +} + +if (!av_strncasecmp(check, search, len) && +(check[len] == 0 || check[len] == '+' || check[len] == ';')) +return desc; +} +} +} + +return NULL; +} + enum AVMediaType avcodec_get_type(enum AVCodecID codec_id) { const AVCodecDescriptor *desc = avcodec_descriptor_get(codec_id); diff --git a/libavcodec/codec_desc.h b/libavcodec/codec_desc.h index 126b52df47..da38784a49 100644 --- a/libavcodec/codec_desc.h +++ b/libavcodec/codec_desc.h @@ -121,6 +121,18 @@ const AVCodecDescriptor *avcodec_descriptor_next(const AVCodecDescriptor *prev); */ const AVCodecDescriptor *avcodec_descriptor_get_by_name(const char *name); +/** + * Locate a codec descriptor with a particular MIME type + * + * @param search the MIME type to search for. + * @param prefix a prefix to use if the search type does not contain a media type. + * NULL if no default prefix should be used. + * + * @return codec descriptor with the given MIME type or NULL if no such + * descriptor exists. + */ +const AVCodecDescriptor *avcodec_descriptor_get_by_mime_type(const char *search, const char *prefix); + /** * @} */ diff --git a/libavcodec/version.h b/libavcodec/version.h index 4b221f96ad..5ce4ba55d9 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -28,7 +28,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 58 -#define LIBAVCODEC_VERSION_MINOR 105 +#define LIBAVCODEC_VERSION_MINOR 106 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ -- 2.27.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 09/15] lavf/id3v2: use avcodec_descriptor_get_by_mime_type
--- libavformat/id3v2.c | 12 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index cecd9b9f6d..72a10bd1e1 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -585,7 +585,7 @@ static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, { int enc, pic_type; char mimetype[64] = {0}; -const CodecMime *mime = ff_id3v2_mime_tags; +const AVCodecDescriptor *desc; enum AVCodecID id = AV_CODEC_ID_NONE; ID3v2ExtraMetaAPIC *apic = NULL; ID3v2ExtraMeta *new_extra = NULL; @@ -614,13 +614,9 @@ static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, taglen-= 3; } -while (mime->id != AV_CODEC_ID_NONE) { -if (!av_strncasecmp(mime->str, mimetype, sizeof(mimetype))) { -id = mime->id; -break; -} -mime++; -} +if ((desc = avcodec_descriptor_get_by_mime_type(mimetype, "image"))) +id = desc->id; + if (id == AV_CODEC_ID_NONE) { av_log(s, AV_LOG_WARNING, "Unknown attached picture mimetype: %s, skipping.\n", mimetype); -- 2.27.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 14/15] lavf: remove ff_id3v2_mime_tags
The ID3 spec doesn't list any particular set of allowed types, it only suggests using PNG or JPEG for compatibility. --- libavformat/id3v2.c | 12 libavformat/id3v2.h | 2 -- 2 files changed, 14 deletions(-) diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index 72a10bd1e1..340b2fc60c 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -128,18 +128,6 @@ const char * const ff_id3v2_picture_types[21] = { "Publisher/Studio logotype", }; -const CodecMime ff_id3v2_mime_tags[] = { -{ "image/gif", AV_CODEC_ID_GIF }, -{ "image/jpeg", AV_CODEC_ID_MJPEG }, -{ "image/jpg", AV_CODEC_ID_MJPEG }, -{ "image/png", AV_CODEC_ID_PNG }, -{ "image/tiff", AV_CODEC_ID_TIFF }, -{ "image/bmp", AV_CODEC_ID_BMP }, -{ "JPG",AV_CODEC_ID_MJPEG }, /* ID3v2.2 */ -{ "PNG",AV_CODEC_ID_PNG }, /* ID3v2.2 */ -{ "", AV_CODEC_ID_NONE }, -}; - int ff_id3v2_match(const uint8_t *buf, const char *magic) { return buf[0] == magic[0] && diff --git a/libavformat/id3v2.h b/libavformat/id3v2.h index a41fb271a4..8e9b7d95d2 100644 --- a/libavformat/id3v2.h +++ b/libavformat/id3v2.h @@ -207,8 +207,6 @@ extern const char ff_id3v2_4_tags[][4]; */ extern const char ff_id3v2_3_tags[][4]; -extern const CodecMime ff_id3v2_mime_tags[]; - extern const char * const ff_id3v2_picture_types[21]; #endif /* AVFORMAT_ID3V2_H */ -- 2.27.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 15/15] lavf: remove internal CodecMime type
These use the global codec descriptor registry now. --- libavformat/internal.h | 5 - 1 file changed, 5 deletions(-) diff --git a/libavformat/internal.h b/libavformat/internal.h index 17a6ab07d3..7ae8142e5b 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -44,11 +44,6 @@ typedef struct AVCodecTag { unsigned int tag; } AVCodecTag; -typedef struct CodecMime{ -char str[32]; -enum AVCodecID id; -} CodecMime; - /*/ /* fractional numbers for exact pts handling */ -- 2.27.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 08/15] lavf/id3v2enc: use codec-desc-provided MIME types
--- libavformat/id3v2enc.c | 11 +++ 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/libavformat/id3v2enc.c b/libavformat/id3v2enc.c index 5d821ea4db..a7f251652f 100644 --- a/libavformat/id3v2enc.c +++ b/libavformat/id3v2enc.c @@ -352,23 +352,18 @@ int ff_id3v2_write_apic(AVFormatContext *s, ID3v2EncContext *id3, AVPacket *pkt) { AVStream *st = s->streams[pkt->stream_index]; AVDictionaryEntry *e; +const AVCodecDescriptor *cdesc = avcodec_descriptor_get(st->codecpar->codec_id); AVIOContext *dyn_buf; uint8_t *buf; -const CodecMime *mime = ff_id3v2_mime_tags; const char *mimetype = NULL, *desc = ""; int enc = id3->version == 3 ? ID3v2_ENCODING_UTF16BOM : ID3v2_ENCODING_UTF8; int i, len, type = 0, ret; /* get the mimetype*/ -while (mime->id != AV_CODEC_ID_NONE) { -if (mime->id == st->codecpar->codec_id) { -mimetype = mime->str; -break; -} -mime++; -} +if (cdesc && cdesc->mime_types) +mimetype = cdesc->mime_types[0]; if (!mimetype) { av_log(s, AV_LOG_ERROR, "No mimetype is known for stream %d, cannot " "write an attached picture.\n", st->index); -- 2.27.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 01/15] lavc/codec_desc: add MIME type to AV_CODEC_ID_TEXT
--- libavcodec/codec_desc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 9e73dcba27..3dee640360 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -3173,6 +3173,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .name = "text", .long_name = NULL_IF_CONFIG_SMALL("raw UTF-8 text"), .props = AV_CODEC_PROP_TEXT_SUB, +.mime_types= MT("text/plain"), }, { .id= AV_CODEC_ID_XSUB, -- 2.27.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 10/15] lavf/flac_picture: use avcodec_descriptor_get_by_mime_type
--- libavformat/flac_picture.c | 11 +++ 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/libavformat/flac_picture.c b/libavformat/flac_picture.c index 53e24b28b7..3e684b58a3 100644 --- a/libavformat/flac_picture.c +++ b/libavformat/flac_picture.c @@ -31,7 +31,7 @@ int ff_flac_parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size, int truncate_workaround) { -const CodecMime *mime = ff_id3v2_mime_tags; +const AVCodecDescriptor *cdesc; enum AVCodecID id = AV_CODEC_ID_NONE; AVBufferRef *data = NULL; uint8_t mimetype[64], *desc = NULL; @@ -78,13 +78,8 @@ int ff_flac_parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size, int tr bytestream2_get_bufferu(&g, mimetype, len); mimetype[len] = 0; -while (mime->id != AV_CODEC_ID_NONE) { -if (!strncmp(mime->str, mimetype, sizeof(mimetype))) { -id = mime->id; -break; -} -mime++; -} +if ((cdesc = avcodec_descriptor_get_by_mime_type(mimetype, "image"))) +id = cdesc->id; if (id == AV_CODEC_ID_NONE) { av_log(s, AV_LOG_ERROR, "Unknown attached picture mimetype: %s.\n", mimetype); -- 2.27.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 07/15] lavf/matroskadec: use avcodec_descriptor_get_by_mime_type
--- libavformat/matroskadec.c | 40 ++- 1 file changed, 6 insertions(+), 34 deletions(-) diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index b1ef344aa7..71debe692a 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -749,25 +749,6 @@ static EbmlSyntax matroska_cluster_enter[] = { }; #undef CHILD_OF -static const CodecMime mkv_image_mime_tags[] = { -{"image/gif" , AV_CODEC_ID_GIF}, -{"image/jpeg" , AV_CODEC_ID_MJPEG}, -{"image/png" , AV_CODEC_ID_PNG}, -{"image/tiff" , AV_CODEC_ID_TIFF}, - -{"" , AV_CODEC_ID_NONE} -}; - -static const CodecMime mkv_mime_tags[] = { -{"text/plain" , AV_CODEC_ID_TEXT}, -{"application/x-truetype-font", AV_CODEC_ID_TTF}, -{"application/x-font" , AV_CODEC_ID_TTF}, -{"application/vnd.ms-opentype", AV_CODEC_ID_OTF}, -{"binary" , AV_CODEC_ID_BIN_DATA}, - -{"" , AV_CODEC_ID_NONE} -}; - static const char *const matroska_doctypes[] = { "matroska", "webm" }; static int matroska_read_close(AVFormatContext *s); @@ -2908,6 +2889,7 @@ static int matroska_read_header(AVFormatContext *s) attachments[j].bin.data && attachments[j].bin.size > 0)) { av_log(matroska->ctx, AV_LOG_ERROR, "incomplete attachment\n"); } else { +const AVCodecDescriptor *desc = avcodec_descriptor_get_by_mime_type(attachments[j].mime, NULL); AVStream *st = avformat_new_stream(s, NULL); if (!st) break; @@ -2917,17 +2899,12 @@ static int matroska_read_header(AVFormatContext *s) av_dict_set(&st->metadata, "title", attachments[j].description, 0); st->codecpar->codec_id = AV_CODEC_ID_NONE; -for (i = 0; mkv_image_mime_tags[i].id != AV_CODEC_ID_NONE; i++) { -if (!strncmp(mkv_image_mime_tags[i].str, attachments[j].mime, - strlen(mkv_image_mime_tags[i].str))) { -st->codecpar->codec_id = mkv_image_mime_tags[i].id; -break; -} -} +if (desc) +st->codecpar->codec_id = desc->id; attachments[j].stream = st; -if (st->codecpar->codec_id != AV_CODEC_ID_NONE) { +if (desc && desc->type == AVMEDIA_TYPE_VIDEO) { AVPacket *pkt = &st->attached_pic; st->disposition |= AV_DISPOSITION_ATTACHED_PIC; @@ -2947,13 +2924,8 @@ static int matroska_read_header(AVFormatContext *s) memcpy(st->codecpar->extradata, attachments[j].bin.data, attachments[j].bin.size); -for (i = 0; mkv_mime_tags[i].id != AV_CODEC_ID_NONE; i++) { -if (!strncmp(mkv_mime_tags[i].str, attachments[j].mime, -strlen(mkv_mime_tags[i].str))) { -st->codecpar->codec_id = mkv_mime_tags[i].id; -break; -} -} +if (!strcmp(attachments[j].mime, "binary")) +st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA; } } } -- 2.27.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 03/15] lavc/codec_desc: add new TTF and OTF MIME types
--- libavcodec/codec_desc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c index 49a00ad264..72ecc1012b 100644 --- a/libavcodec/codec_desc.c +++ b/libavcodec/codec_desc.c @@ -3343,7 +3343,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_DATA, .name = "ttf", .long_name = NULL_IF_CONFIG_SMALL("TrueType font"), -.mime_types= MT("application/x-truetype-font", "application/x-font"), +.mime_types= MT("application/x-truetype-font", "application/x-font", "font/ttf"), }, { .id= AV_CODEC_ID_SCTE_35, @@ -3383,7 +3383,7 @@ static const AVCodecDescriptor codec_descriptors[] = { .type = AVMEDIA_TYPE_DATA, .name = "otf", .long_name = NULL_IF_CONFIG_SMALL("OpenType font"), -.mime_types= MT("application/vnd.ms-opentype"), +.mime_types= MT("application/vnd.ms-opentype", "font/otf"), }, { .id= AV_CODEC_ID_SMPTE_KLV, -- 2.27.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 11/15] lavf/flacenc: use codec-desc-provided MIME types
--- libavformat/flacenc.c | 11 +++ 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/libavformat/flacenc.c b/libavformat/flacenc.c index b947a3b067..ebb0ffb967 100644 --- a/libavformat/flacenc.c +++ b/libavformat/flacenc.c @@ -80,22 +80,17 @@ static int flac_write_picture(struct AVFormatContext *s, AVPacket *pkt) FlacMuxerContext *c = s->priv_data; AVIOContext *pb = s->pb; const AVPixFmtDescriptor *pixdesc; -const CodecMime *mime = ff_id3v2_mime_tags; AVDictionaryEntry *e; const char *mimetype = NULL, *desc = ""; const AVStream *st = s->streams[pkt->stream_index]; +const AVCodecDescriptor *cdesc = avcodec_descriptor_get(st->codecpar->codec_id); int i, mimelen, desclen, type = 0, blocklen; if (!pkt->data) return 0; -while (mime->id != AV_CODEC_ID_NONE) { -if (mime->id == st->codecpar->codec_id) { -mimetype = mime->str; -break; -} -mime++; -} +if (cdesc && cdesc->mime_types) +mimetype = cdesc->mime_types[0]; if (!mimetype) { av_log(s, AV_LOG_ERROR, "No mimetype is known for stream %d, cannot " "write an attached picture.\n", st->index); -- 2.27.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 12/15] lavf/mp3enc: use codec descs for query_codec
--- libavformat/mp3enc.c | 9 +++-- 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c index a3586e1f86..eb8cc2e22f 100644 --- a/libavformat/mp3enc.c +++ b/libavformat/mp3enc.c @@ -489,12 +489,9 @@ static int mp3_write_trailer(struct AVFormatContext *s) static int query_codec(enum AVCodecID id, int std_compliance) { -const CodecMime *cm= ff_id3v2_mime_tags; -while(cm->id != AV_CODEC_ID_NONE) { -if(id == cm->id) -return MKTAG('A', 'P', 'I', 'C'); -cm++; -} +const AVCodecDescriptor *desc = avcodec_descriptor_get(id); +if (desc && desc->type == AVMEDIA_TYPE_VIDEO && desc->mime_types) +return MKTAG('A', 'P', 'I', 'C'); return -1; } -- 2.27.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] lavfi: make job count configurable separately from thread count
Slicing frames into a larger number of jobs can improve performance significantly on asymmetric-multiprocessing systems. On my M1 Max, performance on the two filters transitioned to the new model in this patchset (vf_scale and vf_unsharp, chosen somewhat arbitrarily as reasonable test cases) improved by roughly 15%. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/7] lavu/cpu: add av_cpu_job_count()
This estimates an appropriate number of jobs for a task to be broken up into. This may be higher than the core count in a heterogeneous system. Currently implemented only on Apple platforms; otherwise, we assume homogeneity. --- doc/APIchanges | 3 +++ libavutil/cpu.c | 37 + libavutil/cpu.h | 11 +++ libavutil/version.h | 4 ++-- 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 729f56be7b..6059b495dd 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -14,6 +14,9 @@ libavutil: 2021-04-27 API changes, most recent first: +2022-09-20 - xx - lavu 57.37.100 - cpu.h + Add av_cpu_job_count() and av_cpu_force_job_count(). + 2022-09-03 - xx - lavu 57.36.100 - pixfmt.h Add AV_PIX_FMT_P012, AV_PIX_FMT_Y212, AV_PIX_FMT_XV30, AV_PIX_FMT_XV36 diff --git a/libavutil/cpu.c b/libavutil/cpu.c index 0035e927a5..b846a4a2d5 100644 --- a/libavutil/cpu.c +++ b/libavutil/cpu.c @@ -51,6 +51,7 @@ static atomic_int cpu_flags = ATOMIC_VAR_INIT(-1); static atomic_int cpu_count = ATOMIC_VAR_INIT(-1); +static atomic_int job_count = ATOMIC_VAR_INIT(-1); static int get_cpu_flags(void) { @@ -251,6 +252,42 @@ void av_cpu_force_count(int count) atomic_store_explicit(&cpu_count, count, memory_order_relaxed); } +int av_cpu_job_count(void) +{ +static atomic_int printed = ATOMIC_VAR_INIT(0); +int loaded = 0; + +int jobs = av_cpu_count(); + +#if __APPLE__ +int nperflevels = 1; +size_t len = sizeof(nperflevels); + +if (sysctlbyname("hw.nperflevels", &nperflevels, &len, NULL, 0) == -1) +nperflevels = 1; + +if (nperflevels > 1) +jobs *= 3; +#endif + +if (!atomic_exchange_explicit(&printed, 1, memory_order_relaxed)) +av_log(NULL, AV_LOG_DEBUG, "computed default job factor of %d\n", jobs); + +loaded = atomic_load_explicit(&job_count, memory_order_relaxed); + +if (loaded > 0) { +jobs = loaded; +av_log(NULL, AV_LOG_DEBUG, "overriding to job factor of %d\n", jobs); +} + +return jobs; +} + +void av_cpu_force_job_count(int factor) +{ +atomic_store_explicit(&job_count, factor, memory_order_relaxed); +} + size_t av_cpu_max_align(void) { #if ARCH_MIPS diff --git a/libavutil/cpu.h b/libavutil/cpu.h index 9711e574c5..20f037afe1 100644 --- a/libavutil/cpu.h +++ b/libavutil/cpu.h @@ -110,6 +110,17 @@ int av_cpu_count(void); */ void av_cpu_force_count(int count); +/** + * @return an estimated optimal maximum number of jobs for tasks to be sliced into. + */ +int av_cpu_job_count(void); + +/** + * Overrides job count computation and forces the specified count. + * Count < 1 disables forcing of specific count. + */ +void av_cpu_force_job_count(int count); + /** * Get the maximum data alignment that may be required by FFmpeg. * diff --git a/libavutil/version.h b/libavutil/version.h index 0585fa7b80..9c44cef6aa 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -79,8 +79,8 @@ */ #define LIBAVUTIL_VERSION_MAJOR 57 -#define LIBAVUTIL_VERSION_MINOR 36 -#define LIBAVUTIL_VERSION_MICRO 102 +#define LIBAVUTIL_VERSION_MINOR 37 +#define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ LIBAVUTIL_VERSION_MINOR, \ -- 2.37.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/7] sws: add jobs option, distinct from threads
This allows for more efficient use of asymmetric-multiprocessing systems. --- libswscale/options.c | 2 ++ libswscale/swscale_internal.h | 1 + libswscale/utils.c| 9 ++--- libswscale/version.h | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/libswscale/options.c b/libswscale/options.c index 4d41b835b1..5765daa100 100644 --- a/libswscale/options.c +++ b/libswscale/options.c @@ -81,6 +81,8 @@ static const AVOption swscale_options[] = { { "threads", "number of threads", OFFSET(nb_threads), AV_OPT_TYPE_INT, {.i64 = 1 }, 0, INT_MAX, VE, "threads" }, { "auto",NULL,0, AV_OPT_TYPE_CONST, {.i64 = 0 },.flags = VE, "threads" }, +{ "jobs","number of jobs",OFFSET(nb_jobs), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, VE, "jobs" }, +{ "auto",NULL,0, AV_OPT_TYPE_CONST, {.i64 = 0 },.flags = VE, "jobs" }, { NULL } }; diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index abeebbb002..602082e12c 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -339,6 +339,7 @@ typedef struct SwsContext { int vChrDrop; ///< Binary logarithm of extra vertical subsampling factor in source image chroma planes specified by user. int sliceDir; ///< Direction that slices are fed to the scaler (1 = top-to-bottom, -1 = bottom-to-top). int nb_threads; ///< Number of threads used for scaling +int nb_jobs; ///< Number of slice jobs used for scaling double param[2]; ///< Input parameters for scaling algorithms that need them. AVFrame *frame_src; diff --git a/libswscale/utils.c b/libswscale/utils.c index 45baa22b23..c9ff9db957 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -1277,18 +1277,21 @@ static int context_init_threaded(SwsContext *c, ff_sws_slice_worker, NULL, c->nb_threads); if (ret == AVERROR(ENOSYS)) { c->nb_threads = 1; +c->nb_jobs = 1; return 0; } else if (ret < 0) return ret; c->nb_threads = ret; +if (c->nb_jobs < 1) +c->nb_jobs = av_cpu_job_count(); -c->slice_ctx = av_calloc(c->nb_threads, sizeof(*c->slice_ctx)); -c->slice_err = av_calloc(c->nb_threads, sizeof(*c->slice_err)); +c->slice_ctx = av_calloc(c->nb_jobs, sizeof(*c->slice_ctx)); +c->slice_err = av_calloc(c->nb_jobs, sizeof(*c->slice_err)); if (!c->slice_ctx || !c->slice_err) return AVERROR(ENOMEM); -for (int i = 0; i < c->nb_threads; i++) { +for (int i = 0; i < c->nb_jobs; i++) { c->slice_ctx[i] = sws_alloc_context(); if (!c->slice_ctx[i]) return AVERROR(ENOMEM); diff --git a/libswscale/version.h b/libswscale/version.h index 9bb3b171a7..4529a2d7d4 100644 --- a/libswscale/version.h +++ b/libswscale/version.h @@ -29,7 +29,7 @@ #include "version_major.h" #define LIBSWSCALE_VERSION_MINOR 8 -#define LIBSWSCALE_VERSION_MICRO 112 +#define LIBSWSCALE_VERSION_MICRO 113 #define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \ LIBSWSCALE_VERSION_MINOR, \ -- 2.37.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 3/7] lavfi: add jobs args
This allows tuning the number of tasks that frames are sliced into independently from the number of execution pool threads, which can improve performance significantly on asymmetric-multiprocessing systems. --- doc/APIchanges | 3 +++ libavfilter/avfilter.c | 9 + libavfilter/avfilter.h | 14 ++ libavfilter/avfiltergraph.c | 4 libavfilter/internal.h | 6 ++ libavfilter/pthread.c | 5 + libavfilter/version.h | 2 +- 7 files changed, 42 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index 6059b495dd..ae8b0bf0b4 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -14,6 +14,9 @@ libavutil: 2021-04-27 API changes, most recent first: +2022-09-20 - xx - lavfi 8.50.100 - avfilter.h + Add AVFilterContext.nb_jobs and AVFilterGraph.nb_jobs. + 2022-09-20 - xx - lavu 57.37.100 - cpu.h Add av_cpu_job_count() and av_cpu_force_job_count(). diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index f34204e650..4e16e312c6 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -621,6 +621,8 @@ static const AVOption avfilter_options[] = { { "enable", "set enable expression", OFFSET(enable_str), AV_OPT_TYPE_STRING, {.str=NULL}, .flags = TFLAGS }, { "threads", "Allowed number of threads", OFFSET(nb_threads), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, FLAGS }, +{ "jobs", "Allowed number of jobs", OFFSET(nb_jobs), AV_OPT_TYPE_INT, +{ .i64 = 0 }, 0, INT_MAX, FLAGS }, { "extra_hw_frames", "Number of extra hardware frames to allocate for the user", OFFSET(extra_hw_frames), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, FLAGS }, { NULL }, @@ -797,6 +799,13 @@ int ff_filter_get_nb_threads(AVFilterContext *ctx) return ctx->graph->nb_threads; } +int ff_filter_get_nb_jobs(AVFilterContext *ctx) +{ +if (ctx->nb_jobs > 0) +return FFMIN(ctx->nb_jobs, ctx->graph->nb_jobs); +return ctx->graph->nb_jobs; +} + static int process_options(AVFilterContext *ctx, AVDictionary **options, const char *args) { diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index 2e8197c9a6..aadeadd41c 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -492,6 +492,13 @@ struct AVFilterContext { * configured. */ int extra_hw_frames; + +/** + * Max number of jobs allowed in this filter instance. + * If <= 0, its value is ignored. + * Overrides global number of jobs set per filter graph. + */ +int nb_jobs; }; /** @@ -935,6 +942,13 @@ typedef struct AVFilterGraph { int sink_links_count; unsigned disable_auto_convert; + +/** + * Maximum number of jobs used by filters in this graph. May be set by + * the caller before adding any filters to the filtergraph. Zero (the + * default) means that the number of jobs is determined automatically. + */ +int nb_jobs; } AVFilterGraph; /** diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index 53f468494d..4aac62c6c3 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -51,6 +51,9 @@ static const AVOption filtergraph_options[] = { { "threads", "Maximum number of threads", OFFSET(nb_threads), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, F|V|A, "threads"}, {"auto", "autodetect a suitable number of threads to use", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, .flags = F|V|A, .unit = "threads"}, +{ "jobs","Maximum number of jobs", OFFSET(nb_jobs), AV_OPT_TYPE_INT, +{ .i64 = 0 }, 0, INT_MAX, F|V|A, "jobs"}, +{"auto", "autodetect a suitable number of jobs to use", 0, AV_OPT_TYPE_CONST, {.i64 = 0 }, .flags = F|V|A, .unit = "jobs"}, {"scale_sws_opts" , "default scale filter options", OFFSET(scale_sws_opts), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, F|V }, {"aresample_swr_opts" , "default aresample filter options", OFFSET(aresample_swr_opts), @@ -75,6 +78,7 @@ int ff_graph_thread_init(AVFilterGraph *graph) { graph->thread_type = 0; graph->nb_threads = 1; +graph->nb_jobs = 1; return 0; } #endif diff --git a/libavfilter/internal.h b/libavfilter/internal.h index 0128820be0..be05e8550b 100644 --- a/libavfilter/internal.h +++ b/libavfilter/internal.h @@ -384,6 +384,12 @@ int ff_filter_graph_run_once(AVFilterGraph *graph); */ int ff_filter_get_nb_threads(AVFilterContext *ctx) av_pure; +/** + * Get number of jobs for current filter instance. + * This number is always same or less than graph->nb_jobs. + */ +int ff_filter_get_nb_jobs(AVFilterContext *ctx) av_pure; + /** * Generic processing of user supplied commands that are set * in the same way as the filter options. diff --git a/libavfilter/pthread.c b/libavfilter/pthread.c index 1a063d3cc0..589e32e263 100644 --- a/libavfilter/pthread.c +++ b/libavfilt
[FFmpeg-devel] [PATCH 4/7] ffmpeg: add filter_jobs and filter_complex_jobs args
These are similar to filter_threads and filter_complex_threads, but control job count. --- doc/ffmpeg.texi | 12 fftools/ffmpeg.c| 1 + fftools/ffmpeg.h| 2 ++ fftools/ffmpeg_filter.c | 7 +++ fftools/ffmpeg_opt.c| 13 + 5 files changed, 35 insertions(+) diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index 42440d93b4..6b8248df3b 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -789,6 +789,13 @@ Defines how many threads are used to process a filter pipeline. Each pipeline will produce a thread pool with this many threads available for parallel processing. The default is the number of available CPUs. +@item -filter_jobs @var{nb_jobs} (@emph{global}) +Defines how many jobs are used to process a filter pipeline. Each filter's work +may be split into up to this many tasks for parallel processing, which are then +dispatched to the thread pool of size @var{nb_threads}. +The default is the number of available CPUs, times a multiplier determined based on +the detected CPU topology. For homogenous systems, this multiplier is 1. + @item -pre[:@var{stream_specifier}] @var{preset_name} (@emph{output,per-stream}) Specify the preset for matching stream(s). @@ -1916,6 +1923,11 @@ Defines how many threads are used to process a filter_complex graph. Similar to filter_threads but used for @code{-filter_complex} graphs only. The default is the number of available CPUs. +@item -filter_complex_jobs @var{nb_jobs} (@emph{global}) +Defines how many jobs are used to process a filter_complex graph. +Similar to filter_jobs but used for @code{-filter_complex} graphs only. +The default is the number of available CPUs times a topology multiplier. + @item -lavfi @var{filtergraph} (@emph{global}) Define a complex filtergraph, i.e. one with arbitrary number of inputs and/or outputs. Equivalent to @option{-filter_complex}. diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 0e1477299d..9ff48141cd 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -621,6 +621,7 @@ static void ffmpeg_cleanup(int ret) } av_freep(&vstats_filename); av_freep(&filter_nbthreads); +av_freep(&filter_nbjobs); av_freep(&input_streams); av_freep(&input_files); diff --git a/fftools/ffmpeg.h b/fftools/ffmpeg.h index ede0b2bd96..89ee9caca7 100644 --- a/fftools/ffmpeg.h +++ b/fftools/ffmpeg.h @@ -679,7 +679,9 @@ extern AVIOContext *progress_avio; extern float max_error_rate; extern char *filter_nbthreads; +extern char *filter_nbjobs; extern int filter_complex_nbthreads; +extern int filter_complex_nbjobs; extern int vstats_version; extern int auto_conversion_filters; diff --git a/fftools/ffmpeg_filter.c b/fftools/ffmpeg_filter.c index 7a5308425d..34e0fce7ab 100644 --- a/fftools/ffmpeg_filter.c +++ b/fftools/ffmpeg_filter.c @@ -998,6 +998,12 @@ int configure_filtergraph(FilterGraph *fg) av_opt_set(fg->graph, "threads", e->value, 0); } +if (filter_nbjobs) { +ret = av_opt_set(fg->graph, "jobs", filter_nbjobs, 0); +if (ret < 0) +goto fail; +} + args[0] = 0; e = NULL; while ((e = av_dict_get(ost->sws_dict, "", e, @@ -1020,6 +1026,7 @@ int configure_filtergraph(FilterGraph *fg) av_opt_set(fg->graph, "aresample_swr_opts", args, 0); } else { fg->graph->nb_threads = filter_complex_nbthreads; +fg->graph->nb_jobs= filter_complex_nbjobs; } if ((ret = avfilter_graph_parse2(fg->graph, graph_desc, &inputs, &outputs)) < 0) diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c index 5febe319e4..196064d1b9 100644 --- a/fftools/ffmpeg_opt.c +++ b/fftools/ffmpeg_opt.c @@ -175,7 +175,9 @@ int qp_hist = 0; int stdin_interaction = 1; float max_error_rate = 2.0/3; char *filter_nbthreads; +char *filter_nbjobs; int filter_complex_nbthreads = 0; +int filter_complex_nbjobs = 0; int vstats_version = 2; int auto_conversion_filters = 1; int64_t stats_period = 50; @@ -352,6 +354,13 @@ static int opt_filter_threads(void *optctx, const char *opt, const char *arg) return 0; } +static int opt_filter_jobs(void *optctx, const char *opt, const char *arg) +{ +av_free(filter_nbjobs); +filter_nbjobs = av_strdup(arg); +return 0; +} + static int opt_abort_on(void *optctx, const char *opt, const char *arg) { static const AVOption opts[] = { @@ -3961,6 +3970,8 @@ const OptionDef options[] = { "set stream filtergraph", "filter_graph" }, { "filter_threads", HAS_ARG, { .func_arg = opt_filter_threads }, "number of non-complex filter threads" }, +{ "filter_jobs", HAS_ARG,{ .func_arg = opt_filter_jobs }, +"number of non-complex filter jobs" }, { "filter_script", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(filter_scripts) }, "read stre
[FFmpeg-devel] [PATCH 5/7] ffplay: add filter_jobs arg
This is similar to filter_threads, but controls job count. --- doc/ffplay.texi | 5 + fftools/ffplay.c | 4 2 files changed, 9 insertions(+) diff --git a/doc/ffplay.texi b/doc/ffplay.texi index 5dd860b846..abc857013f 100644 --- a/doc/ffplay.texi +++ b/doc/ffplay.texi @@ -196,6 +196,11 @@ will produce a thread pool with this many threads available for parallel processing. The default is 0 which means that the thread count will be determined by the number of available CPUs. +@item -filter_jobs @var{nb_jobs} +Defines how many distinct jobs a filter pipeline will break frames into. +The default is 0 which means that the thread count will be determined +by the CPU topology. + @end table @section While playing diff --git a/fftools/ffplay.c b/fftools/ffplay.c index bcc00afe31..bce1d20c49 100644 --- a/fftools/ffplay.c +++ b/fftools/ffplay.c @@ -355,6 +355,7 @@ static char *afilters = NULL; static int autorotate = 1; static int find_stream_info = 1; static int filter_nbthreads = 0; +static int filter_nbjobs = 0; /* current context */ static int is_full_screen; @@ -1963,6 +1964,7 @@ static int configure_audio_filters(VideoState *is, const char *afilters, int for if (!(is->agraph = avfilter_graph_alloc())) return AVERROR(ENOMEM); is->agraph->nb_threads = filter_nbthreads; +is->agraph->nb_jobs = filter_nbjobs; av_bprint_init(&bp, 0, AV_BPRINT_SIZE_AUTOMATIC); @@ -2168,6 +2170,7 @@ static int video_thread(void *arg) goto the_end; } graph->nb_threads = filter_nbthreads; +graph->nb_jobs = filter_nbjobs; if ((ret = configure_video_filters(graph, is, vfilters_list ? vfilters_list[is->vfilter_idx] : NULL, frame)) < 0) { SDL_Event event; event.type = FF_QUIT_EVENT; @@ -3615,6 +3618,7 @@ static const OptionDef options[] = { { "find_stream_info", OPT_BOOL | OPT_INPUT | OPT_EXPERT, { &find_stream_info }, "read and decode the streams to fill missing information with heuristics" }, { "filter_threads", HAS_ARG | OPT_INT | OPT_EXPERT, { &filter_nbthreads }, "number of filter threads per graph" }, +{ "filter_jobs", HAS_ARG | OPT_INT | OPT_EXPERT, { &filter_nbjobs }, "number of filter jobs per graph" }, { NULL, }, }; -- 2.37.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 6/7] lavfi/vf_unsharp: use ff_filter_get_nb_jobs
Improves performance by roughly 15% on M1 Max --- libavfilter/unsharp.h| 2 +- libavfilter/vf_unsharp.c | 20 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/libavfilter/unsharp.h b/libavfilter/unsharp.h index 0da6f05036..7af32b0467 100644 --- a/libavfilter/unsharp.h +++ b/libavfilter/unsharp.h @@ -54,7 +54,7 @@ typedef struct UnsharpContext { int nb_planes; int bitdepth; int bps; -int nb_threads; +int nb_jobs; int (* apply_unsharp)(AVFilterContext *ctx, AVFrame *in, AVFrame *out); int (* unsharp_slice)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs); } UnsharpContext; diff --git a/libavfilter/vf_unsharp.c b/libavfilter/vf_unsharp.c index e88e732c9e..9632058daf 100644 --- a/libavfilter/vf_unsharp.c +++ b/libavfilter/vf_unsharp.c @@ -166,7 +166,7 @@ static int apply_unsharp_c(AVFilterContext *ctx, AVFrame *in, AVFrame *out) td.dst_stride = out->linesize[i]; td.src_stride = in->linesize[i]; ff_filter_execute(ctx, s->unsharp_slice, &td, NULL, - FFMIN(plane_h[i], s->nb_threads)); + FFMIN(plane_h[i], s->nb_jobs)); } return 0; } @@ -229,12 +229,12 @@ static int init_filter_param(AVFilterContext *ctx, UnsharpFilterParam *fp, const av_log(ctx, AV_LOG_VERBOSE, "effect:%s type:%s msize_x:%d msize_y:%d amount:%0.2f\n", effect, effect_type, fp->msize_x, fp->msize_y, fp->amount / 65535.0); -fp->sr = av_malloc_array((MAX_MATRIX_SIZE - 1) * s->nb_threads, sizeof(uint32_t)); -fp->sc = av_calloc(fp->steps_y * s->nb_threads, 2 * sizeof(*fp->sc)); +fp->sr = av_malloc_array((MAX_MATRIX_SIZE - 1) * s->nb_jobs, sizeof(uint32_t)); +fp->sc = av_calloc(fp->steps_y * s->nb_jobs, 2 * sizeof(*fp->sc)); if (!fp->sr || !fp->sc) return AVERROR(ENOMEM); -for (z = 0; z < 2 * fp->steps_y * s->nb_threads; z++) +for (z = 0; z < 2 * fp->steps_y * s->nb_jobs; z++) if (!(fp->sc[z] = av_malloc_array(width + 2 * fp->steps_x, sizeof(*(fp->sc[z]) return AVERROR(ENOMEM); @@ -255,9 +255,9 @@ static int config_input(AVFilterLink *inlink) s->bps = s->bitdepth > 8 ? 2 : 1; s->unsharp_slice = s->bitdepth > 8 ? unsharp_slice_16 : unsharp_slice_8; -// ensure (height / nb_threads) > 4 * steps_y, +// ensure (height / nb_jobs) > 4 * steps_y, // so that we don't have too much overlap between two threads -s->nb_threads = FFMIN(ff_filter_get_nb_threads(inlink->dst), +s->nb_jobs = FFMIN(ff_filter_get_nb_jobs(inlink->dst), inlink->h / (4 * s->luma.steps_y)); ret = init_filter_param(inlink->dst, &s->luma, "luma", inlink->w); @@ -270,12 +270,12 @@ static int config_input(AVFilterLink *inlink) return 0; } -static void free_filter_param(UnsharpFilterParam *fp, int nb_threads) +static void free_filter_param(UnsharpFilterParam *fp, int nb_jobs) { int z; if (fp->sc) { -for (z = 0; z < 2 * fp->steps_y * nb_threads; z++) +for (z = 0; z < 2 * fp->steps_y * nb_jobs; z++) av_freep(&fp->sc[z]); av_freep(&fp->sc); } @@ -286,8 +286,8 @@ static av_cold void uninit(AVFilterContext *ctx) { UnsharpContext *s = ctx->priv; -free_filter_param(&s->luma, s->nb_threads); -free_filter_param(&s->chroma, s->nb_threads); +free_filter_param(&s->luma, s->nb_jobs); +free_filter_param(&s->chroma, s->nb_jobs); } static int filter_frame(AVFilterLink *link, AVFrame *in) -- 2.37.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 7/7] lavfi/vf_scale: set sws job count using ff_filter_get_nb_jobs
This mirrors the existing handling for thread count. --- libavfilter/vf_scale.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c index 2b12cf283c..db984725bd 100644 --- a/libavfilter/vf_scale.c +++ b/libavfilter/vf_scale.c @@ -544,6 +544,7 @@ static int config_props(AVFilterLink *outlink) av_opt_set_int(s, "param0", scale->param[0], 0); av_opt_set_int(s, "param1", scale->param[1], 0); av_opt_set_int(s, "threads", ff_filter_get_nb_threads(ctx), 0); +av_opt_set_int(s, "jobs",ff_filter_get_nb_jobs(ctx), 0); if (scale->in_range != AVCOL_RANGE_UNSPECIFIED) av_opt_set_int(s, "src_range", scale->in_range == AVCOL_RANGE_JPEG, 0); -- 2.37.2 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] lavc/libaribb24: add default_profile option
This allows decoding of streams that don't have a profile tagged (e.g. ones that were remuxed improperly). --- libavcodec/libaribb24.c | 33 +++-- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/libavcodec/libaribb24.c b/libavcodec/libaribb24.c index f40517e22e..8ccf3c4b5d 100644 --- a/libavcodec/libaribb24.c +++ b/libavcodec/libaribb24.c @@ -40,10 +40,18 @@ typedef struct Libaribb24Context { char*aribb24_base_path; unsigned int aribb24_skip_ruby; + +int default_profile; } Libaribb24Context; -static unsigned int get_profile_font_size(int profile) +static unsigned int get_profile_font_size(AVCodecContext *avctx) { +Libaribb24Context *b24 = avctx->priv_data; +int profile = avctx->profile; + +if (profile == FF_PROFILE_UNKNOWN) +profile = b24->default_profile; + switch (profile) { case FF_PROFILE_ARIB_PROFILE_A: return 36; @@ -61,26 +69,31 @@ static void libaribb24_log(void *p, const char *msg) static int libaribb24_generate_ass_header(AVCodecContext *avctx) { +Libaribb24Context *b24 = avctx->priv_data; unsigned int plane_width = 0; unsigned int plane_height = 0; unsigned int font_size = 0; +int profile = avctx->profile; -switch (avctx->profile) { +if (profile == FF_PROFILE_UNKNOWN) +profile = b24->default_profile; + +switch (profile) { case FF_PROFILE_ARIB_PROFILE_A: plane_width = 960; plane_height = 540; -font_size = get_profile_font_size(avctx->profile); break; case FF_PROFILE_ARIB_PROFILE_C: plane_width = 320; plane_height = 180; -font_size = get_profile_font_size(avctx->profile); break; default: av_log(avctx, AV_LOG_ERROR, "Unknown or unsupported profile set!\n"); return AVERROR(EINVAL); } +font_size = get_profile_font_size(avctx); + avctx->subtitle_header = av_asprintf( "[Script Info]\r\n" "; Script generated by FFmpeg/Lavc%s\r\n" @@ -135,6 +148,7 @@ static int libaribb24_init(AVCodecContext *avctx) Libaribb24Context *b24 = avctx->priv_data; void(* arib_dec_init)(arib_decoder_t* decoder) = NULL; int ret_code = AVERROR_EXTERNAL; +int profile = avctx->profile; if (!(b24->lib_instance = arib_instance_new(avctx))) { av_log(avctx, AV_LOG_ERROR, "Failed to initialize libaribb24!\n"); @@ -158,7 +172,10 @@ static int libaribb24_init(AVCodecContext *avctx) goto init_fail; } -switch (avctx->profile) { +if (profile == FF_PROFILE_UNKNOWN) +profile = b24->default_profile; + +switch (profile) { case FF_PROFILE_ARIB_PROFILE_A: arib_dec_init = arib_initialize_decoder_a_profile; break; @@ -209,7 +226,7 @@ static int libaribb24_handle_regions(AVCodecContext *avctx, AVSubtitle *sub) { Libaribb24Context *b24 = avctx->priv_data; const arib_buf_region_t *region = arib_decoder_get_regions(b24->decoder); -unsigned int profile_font_size = get_profile_font_size(avctx->profile); +unsigned int profile_font_size = get_profile_font_size(avctx); AVBPrint buf = { 0 }; int ret = 0; @@ -371,6 +388,10 @@ static const AVOption options[] = { OFFSET(aribb24_base_path), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, SD }, { "aribb24-skip-ruby-text", "skip ruby text blocks during decoding", OFFSET(aribb24_skip_ruby), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, SD }, +{ "default_profile", "default profile to use if not specified in the stream parameters", + OFFSET(default_profile), AV_OPT_TYPE_INT, { .i64 = FF_PROFILE_UNKNOWN }, FF_PROFILE_UNKNOWN, FF_PROFILE_ARIB_PROFILE_C, SD, "profile" }, +{"a", "Profile A", 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_ARIB_PROFILE_A}, INT_MIN, INT_MAX, SD, "profile"}, +{"c", "Profile C", 0, AV_OPT_TYPE_CONST, {.i64 = FF_PROFILE_ARIB_PROFILE_C}, INT_MIN, INT_MAX, SD, "profile"}, { NULL } }; -- 2.38.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] lavf/mux: ignore nonmonotonic timestamps for timestampless muxers
--- libavformat/mux.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libavformat/mux.c b/libavformat/mux.c index 37fe19358d..7b13dd8012 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -538,7 +538,7 @@ static int compute_muxer_pkt_fields(AVFormatContext *s, AVStream *st, AVPacket * } if (sti->cur_dts && sti->cur_dts != AV_NOPTS_VALUE && -((!(s->oformat->flags & AVFMT_TS_NONSTRICT) && +((!(s->oformat->flags & (AVFMT_TS_NONSTRICT | AVFMT_NOTIMESTAMPS)) && st->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE && st->codecpar->codec_type != AVMEDIA_TYPE_DATA && sti->cur_dts >= pkt->dts) || sti->cur_dts > pkt->dts)) { @@ -783,7 +783,8 @@ static int prepare_input_packet(AVFormatContext *s, AVStream *st, AVPacket *pkt) /* check that the dts are increasing (or at least non-decreasing, * if the format allows it */ if (sti->cur_dts != AV_NOPTS_VALUE && -((!(s->oformat->flags & AVFMT_TS_NONSTRICT) && sti->cur_dts >= pkt->dts) || +((!(s->oformat->flags & (AVFMT_TS_NONSTRICT | AVFMT_NOTIMESTAMPS)) && + sti->cur_dts >= pkt->dts) || sti->cur_dts > pkt->dts)) { av_log(s, AV_LOG_ERROR, "Application provided invalid, non monotonically increasing " -- 2.38.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH] lavf/spdifdec: support EAC3
Parsing should probably be enabled for all codecs, at least for headers, but e.g. the AAC parser produces 1-byte packets of zero padding with it, so I'm just enabling it for EAC3 for the moment. --- libavformat/spdifdec.c | 19 +- tests/fate/spdif.mak| 3 + tests/ref/fate/spdif-eac3-remux | 659 3 files changed, 680 insertions(+), 1 deletion(-) create mode 100644 tests/ref/fate/spdif-eac3-remux diff --git a/libavformat/spdifdec.c b/libavformat/spdifdec.c index 672133581a..7a6b77aae8 100644 --- a/libavformat/spdifdec.c +++ b/libavformat/spdifdec.c @@ -31,6 +31,7 @@ #include "libavcodec/adts_parser.h" #include "avformat.h" +#include "internal.h" #include "spdif.h" static int spdif_get_offset_and_codec(AVFormatContext *s, @@ -93,6 +94,10 @@ static int spdif_get_offset_and_codec(AVFormatContext *s, *offset = 8192; *codec = AV_CODEC_ID_DTS; break; +case IEC61937_EAC3: +*offset = 24576; +*codec = AV_CODEC_ID_EAC3; +break; default: if (s) { /* be silent during a probe */ avpriv_request_sample(s, "Data type 0x%04x in IEC 61937", @@ -170,6 +175,16 @@ static int spdif_read_header(AVFormatContext *s) return 0; } +static int spdif_get_pkt_size_bits(int type, int code) +{ +switch (type & 0xff) { +case IEC61937_EAC3: +return code << 3; +default: +return code; +} +} + int ff_spdif_read_packet(AVFormatContext *s, AVPacket *pkt) { AVIOContext *pb = s->pb; @@ -185,7 +200,7 @@ int ff_spdif_read_packet(AVFormatContext *s, AVPacket *pkt) } data_type = avio_rl16(pb); -pkt_size_bits = avio_rl16(pb); +pkt_size_bits = spdif_get_pkt_size_bits(data_type, avio_rl16(pb)); if (pkt_size_bits % 16) avpriv_request_sample(s, "Packet not ending at a 16-bit boundary"); @@ -218,6 +233,8 @@ int ff_spdif_read_packet(AVFormatContext *s, AVPacket *pkt) } st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; st->codecpar->codec_id = codec_id; +if (codec_id == AV_CODEC_ID_EAC3) +ffstream(st)->need_parsing = AVSTREAM_PARSE_FULL; } else if (codec_id != s->streams[0]->codecpar->codec_id) { avpriv_report_missing_feature(s, "Codec change in IEC 61937"); return AVERROR_PATCHWELCOME; diff --git a/tests/fate/spdif.mak b/tests/fate/spdif.mak index 093b8138e8..85627b2241 100644 --- a/tests/fate/spdif.mak +++ b/tests/fate/spdif.mak @@ -24,6 +24,9 @@ fate-spdif-dca-master-core: CMD = md5 -i $(TARGET_SAMPLES)/dts/master_audio_7.1_ FATE_SPDIF-$(call DEMMUX, EAC3, SPDIF) += fate-spdif-eac3 fate-spdif-eac3: CMD = md5 -i $(TARGET_SAMPLES)/eac3/csi_miami_stereo_128_spx.eac3 -c copy -f spdif +FATE_SPDIF_REMUX-$(call ALLYES, EAC3_DEMUXER EAC3_DECODER SPDIF_MUXER SPDIF_DEMUXER) += fate-spdif-eac3-remux +fate-spdif-eac3-remux: CMD = transcode eac3 $(TARGET_SAMPLES)/eac3/csi_miami_stereo_128_spx.eac3 spdif "-c copy" "-c copy" + FATE_SPDIF-$(call DEMMUX, MLP, SPDIF) += fate-spdif-mlp fate-spdif-mlp: CMD = md5 -i $(TARGET_SAMPLES)/lossless-audio/luckynight-partial.mlp -c copy -f spdif diff --git a/tests/ref/fate/spdif-eac3-remux b/tests/ref/fate/spdif-eac3-remux new file mode 100644 index 00..43399fefba --- /dev/null +++ b/tests/ref/fate/spdif-eac3-remux @@ -0,0 +1,659 @@ +b881db03eb6370e057645396d1880260 *tests/data/fate/spdif-eac3-remux.spdif +16023552 tests/data/fate/spdif-eac3-remux.spdif +#tb 0: 1/9 +#media_type 0: audio +#codec_id 0: eac3 +#sample_rate 0: 48000 +#channel_layout_name 0: stereo +0, 0, 0, 2880, 352, 0x0ae5a595 +0, 2880, 2880, 2880, 512, 0x2beaf79f +0, 5760, 5760, 2880, 512, 0x29ddf9d6 +0, 8640, 8640, 2880, 512, 0xba0afa79 +0, 11520, 11520, 2880, 512, 0xe019f394 +0, 14400, 14400, 2880, 512, 0xf501f5ab +0, 17280, 17280, 2880, 512, 0x5ed3f35c +0, 20160, 20160, 2880, 512, 0xb2a5f67b +0, 23040, 23040, 2880, 512, 0xdab3f328 +0, 25920, 25920, 2880, 512, 0x490dfa2e +0, 28800, 28800, 2880, 512, 0x26dffa1d +0, 31680, 31680, 2880, 512, 0xa8daf5cd +0, 34560, 34560, 2880, 512, 0x823a01e1 +0, 37440, 37440, 2880, 512, 0xf2feee89 +0, 40320, 40320, 2880, 512, 0x58f5ebe2 +0, 43200, 43200, 2880, 512, 0x8618f679 +0, 46080, 46080, 2880, 512, 0xfbe3f0e9 +0, 48960, 48960, 2880, 512, 0xadc3f479 +0, 51840, 51840, 2880, 512, 0xe85ef861 +0, 54720, 54720, 2880, 512, 0x788cf985 +0, 57600, 57600, 2880, 512, 0x44cf00c1 +0, 60480, 60480, 2880, 512, 0x3398fbf8 +0, 63360, 63360, 2880, 512, 0xfbfafc32 +0, 66240, 66240,
[FFmpeg-devel] [PATCH] lavf/matroska: add support for ARIB captions
Not yet ready for merge, pending finalization of the standard proposal for this mapping: https://github.com/ietf-wg-cellar/matroska-specification/pull/724 --- libavformat/matroska.c| 1 + libavformat/matroskadec.c | 30 ++ libavformat/matroskaenc.c | 23 +++ 3 files changed, 54 insertions(+) diff --git a/libavformat/matroska.c b/libavformat/matroska.c index 90d94b65bf..79b2d09984 100644 --- a/libavformat/matroska.c +++ b/libavformat/matroska.c @@ -76,6 +76,7 @@ const CodecTags ff_mkv_codec_tags[]={ {"S_DVBSUB" , AV_CODEC_ID_DVB_SUBTITLE}, {"S_HDMV/PGS" , AV_CODEC_ID_HDMV_PGS_SUBTITLE}, {"S_HDMV/TEXTST", AV_CODEC_ID_HDMV_TEXT_SUBTITLE}, +{"S_ARIBSUB", AV_CODEC_ID_ARIB_CAPTION}, {"V_AV1", AV_CODEC_ID_AV1}, {"V_AVS2" , AV_CODEC_ID_AVS2}, diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index d582f566a2..3a888e3ada 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -50,6 +50,7 @@ #include "libavutil/time_internal.h" #include "libavutil/spherical.h" +#include "libavcodec/avcodec.h" #include "libavcodec/bytestream.h" #include "libavcodec/flac.h" #include "libavcodec/mpeg4audio.h" @@ -2813,6 +2814,35 @@ static int matroska_parse_tracks(AVFormatContext *s) /* we don't need any value stored in CodecPrivate. make sure that it's not exported as extradata. */ track->codec_priv.size = 0; +} else if (codec_id == AV_CODEC_ID_ARIB_CAPTION && track->codec_priv.size == 3) { +int component_tag = track->codec_priv.data[0]; +int data_component_id = AV_RB16(track->codec_priv.data + 1); + +switch (data_component_id) { +case 0x0008: +// [0x30..0x37] are component tags utilized for +// non-mobile captioning service ("profile A"). +if (component_tag >= 0x30 && component_tag <= 0x37) { +st->codecpar->profile = FF_PROFILE_ARIB_PROFILE_A; +} +break; +case 0x0012: +// component tag 0x87 signifies a mobile/partial reception +// (1seg) captioning service ("profile C"). +if (component_tag == 0x87) { +st->codecpar->profile = FF_PROFILE_ARIB_PROFILE_C; +} +break; +default: +break; +} + +if (st->codecpar->profile == FF_PROFILE_UNKNOWN) +av_log(matroska->ctx, AV_LOG_WARNING, + "Unknown ARIB caption profile utilized: %02x / %04x\n", + component_tag, data_component_id); + +track->codec_priv.size = 0; } track->codec_priv.size -= extradata_offset; diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 2deb4284e8..67cfec761a 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -58,6 +58,7 @@ #include "libavutil/stereo3d.h" #include "libavcodec/av1.h" +#include "libavcodec/avcodec.h" #include "libavcodec/codec_desc.h" #include "libavcodec/xiph.h" #include "libavcodec/mpeg4audio.h" @@ -1142,6 +1143,27 @@ static int mkv_assemble_native_codecprivate(AVFormatContext *s, AVIOContext *dyn else *size_to_reserve = MAX_PCE_SIZE; break; +case AV_CODEC_ID_ARIB_CAPTION: { +unsigned stream_identifier, data_component_id; +switch (par->profile) { +case FF_PROFILE_ARIB_PROFILE_A: +stream_identifier = 0x30; +data_component_id = 0x0008; +break; +case FF_PROFILE_ARIB_PROFILE_C: +stream_identifier = 0x87; +data_component_id = 0x0012; +break; +default: +av_log(s, AV_LOG_ERROR, + "Unset/unknown ARIB caption profile %d utilized!\n", + par->profile); +return AVERROR_INVALIDDATA; +} +avio_w8(dyn_cp, stream_identifier); +avio_wb16(dyn_cp, data_component_id); +break; +} #endif default: if (CONFIG_MATROSKA_MUXER && par->codec_id == AV_CODEC_ID_PRORES && @@ -3274,6 +3296,7 @@ static const AVCodecTag additional_subtitle_tags[] = { { AV_CODEC_ID_DVB_SUBTITLE, 0x }, { AV_CODEC_ID_DVD_SUBTITLE, 0x }, { AV_CODEC_ID_HDMV_PGS_SUBTITLE, 0x }, +{ AV_CODEC_ID_ARIB_CAPTION, 0x }, { AV_CODEC_ID_NONE, 0x } }; -- 2.38.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/6] lavc/videotoolboxdec: warn on nonzero status in the callback
From: rcombs Signed-off-by: rcombs --- libavcodec/videotoolbox.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/videotoolbox.c b/libavcodec/videotoolbox.c index 9083f6ff29..7c4c4c6e1b 100644 --- a/libavcodec/videotoolbox.c +++ b/libavcodec/videotoolbox.c @@ -691,7 +691,7 @@ static void videotoolbox_decoder_callback(void *opaque, } if (!image_buffer) { -av_log(avctx, AV_LOG_DEBUG, "vt decoder cb: output image buffer is null\n"); +av_log(avctx, status ? AV_LOG_WARNING : AV_LOG_DEBUG, "vt decoder cb: output image buffer is null: %i\n", status); return; } -- ffmpeg-codebot ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/6] lavc/videotoolboxdec: fix escaping sequential zero sequences
From: rcombs This ensure that e.g. 00 becomes 0300 000300, rather than 0300 . Signed-off-by: rcombs --- libavcodec/videotoolbox.c | 7 +++ 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/libavcodec/videotoolbox.c b/libavcodec/videotoolbox.c index 7c4c4c6e1b..a1933f03f2 100644 --- a/libavcodec/videotoolbox.c +++ b/libavcodec/videotoolbox.c @@ -166,14 +166,13 @@ static int escape_ps(uint8_t* dst, const uint8_t* src, int src_size) src[i + 2] <= 0x03) { if (dst) { *p++ = src[i++]; -*p++ = src[i++]; +*p++ = src[i]; *p++ = 0x03; } else { -i += 2; +i++; } size++; -} -if (dst) +} else if (dst) *p++ = src[i]; } -- ffmpeg-codebot ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 3/6] lavc/videotoolboxdec: fix generating HEVC general_profile_compatibility_flags
From: rcombs We store this as an array of bools, not a bitfield. Signed-off-by: rcombs --- libavcodec/videotoolbox.c | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libavcodec/videotoolbox.c b/libavcodec/videotoolbox.c index a1933f03f2..c95c53fcf0 100644 --- a/libavcodec/videotoolbox.c +++ b/libavcodec/videotoolbox.c @@ -273,7 +273,16 @@ CFDataRef ff_videotoolbox_hvcc_extradata_create(AVCodecContext *avctx) ptlc.profile_idc); /* unsigned int(32) general_profile_compatibility_flags; */ -memcpy(p + 2, ptlc.profile_compatibility_flag, 4); +for (i = 0; i < 4; i++) { +AV_W8(p + 2 + i, ptlc.profile_compatibility_flag[i * 8] << 7 | + ptlc.profile_compatibility_flag[i * 8 + 1] << 6 | + ptlc.profile_compatibility_flag[i * 8 + 2] << 5 | + ptlc.profile_compatibility_flag[i * 8 + 3] << 4 | + ptlc.profile_compatibility_flag[i * 8 + 4] << 3 | + ptlc.profile_compatibility_flag[i * 8 + 5] << 2 | + ptlc.profile_compatibility_flag[i * 8 + 6] << 1 | + ptlc.profile_compatibility_flag[i * 8 + 7]); +} /* unsigned int(48) general_constraint_indicator_flags; */ AV_W8(p + 6, ptlc.progressive_source_flag<< 7 | -- ffmpeg-codebot ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 4/6] lavc/videotoolboxdec: fix writing too many 1 bits for the reserved fields
From: rcombs Signed-off-by: rcombs --- libavcodec/videotoolbox.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/videotoolbox.c b/libavcodec/videotoolbox.c index c95c53fcf0..921fed9619 100644 --- a/libavcodec/videotoolbox.c +++ b/libavcodec/videotoolbox.c @@ -328,13 +328,13 @@ CFDataRef ff_videotoolbox_hvcc_extradata_create(AVCodecContext *avctx) * bit(5) reserved = ‘1’b; * unsigned int(3) bitDepthLumaMinus8; */ -AV_W8(p + 17, (sps->bit_depth - 8) | 0xfc); +AV_W8(p + 17, (sps->bit_depth - 8) | 0xf8); /* * bit(5) reserved = ‘1’b; * unsigned int(3) bitDepthChromaMinus8; */ -AV_W8(p + 18, (sps->bit_depth_chroma - 8) | 0xfc); +AV_W8(p + 18, (sps->bit_depth_chroma - 8) | 0xf8); /* bit(16) avgFrameRate; */ AV_WB16(p + 19, 0); -- ffmpeg-codebot ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 5/6] lavc/videotoolboxdec: insert emu-prevention bytes for HEVC as well
From: rcombs Fixes decoding of files with sync-fooling sequences in their PSs. Signed-off-by: rcombs --- libavcodec/videotoolbox.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/videotoolbox.c b/libavcodec/videotoolbox.c index 921fed9619..ce83c2594a 100644 --- a/libavcodec/videotoolbox.c +++ b/libavcodec/videotoolbox.c @@ -246,7 +246,7 @@ CFDataRef ff_videotoolbox_hvcc_extradata_create(AVCodecContext *avctx) for (i = 0; i < HEVC_MAX_##T##PS_COUNT; i++) { \ if (h->ps.t##ps_list[i]) { \ const HEVC##T##PS *lps = (const HEVC##T##PS *)h->ps.t##ps_list[i]->data; \ -vt_extradata_size += 2 + lps->data_size; \ +vt_extradata_size += 2 + escape_ps(NULL, lps->data, lps->data_size); \ num_##t##ps++; \ } \ } @@ -369,11 +369,11 @@ CFDataRef ff_videotoolbox_hvcc_extradata_create(AVCodecContext *avctx) for (i = 0; i < HEVC_MAX_##T##PS_COUNT; i++) { \ if (h->ps.t##ps_list[i]) { \ const HEVC##T##PS *lps = (const HEVC##T##PS *)h->ps.t##ps_list[i]->data; \ +int size = escape_ps(p + 2, lps->data, lps->data_size); \ /* unsigned int(16) nalUnitLength; */ \ -AV_WB16(p, lps->data_size); \ +AV_WB16(p, size); \ /* bit(8*nalUnitLength) nalUnit; */ \ -memcpy(p + 2, lps->data, lps->data_size); \ -p += 2 + lps->data_size; \ +p += 2 + size; \ } \ } -- ffmpeg-codebot ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 6/6] lavc/h264_ps: always include the stop bit in [s|p]ps->data
From: rcombs The VideoToolbox hwaccel needs the entire NAL (including the stop bit), but ff_h2645_packet_split may remove it. Detect this case by looking for bit counts divisible by 8 and insert a stop-bit-only 0x80 byte. Signed-off-by: rcombs --- libavcodec/h264_ps.c | 8 1 file changed, 8 insertions(+) diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c index 051f06692c..e16da68dec 100644 --- a/libavcodec/h264_ps.c +++ b/libavcodec/h264_ps.c @@ -351,6 +351,10 @@ int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx, } memcpy(sps->data, gb->buffer, sps->data_size); +// Re-add the removed stop bit (may be used by hwaccels). +if (!(gb->size_in_bits & 7) && sps->data_size < sizeof(sps->data)) +sps->data[sps->data_size++] = 0x80; + profile_idc = get_bits(gb, 8); constraint_set_flags |= get_bits1(gb) << 0; // constraint_set0_flag constraint_set_flags |= get_bits1(gb) << 1; // constraint_set1_flag @@ -775,6 +779,10 @@ int ff_h264_decode_picture_parameter_set(GetBitContext *gb, AVCodecContext *avct } memcpy(pps->data, gb->buffer, pps->data_size); +// Re-add the removed stop bit (may be used by hwaccels). +if (!(bit_length & 7) && pps->data_size < sizeof(pps->data)) +pps->data[pps->data_size++] = 0x80; + pps->sps_id = get_ue_golomb_31(gb); if ((unsigned)pps->sps_id >= MAX_SPS_COUNT || !ps->sps_list[pps->sps_id]) { -- ffmpeg-codebot ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/2] lavfi/colorspace: add ff_matrix_mul_3x3_vec
From: rcombs Signed-off-by: rcombs --- libavfilter/colorspace.c | 11 +++ libavfilter/colorspace.h | 1 + 2 files changed, 12 insertions(+) diff --git a/libavfilter/colorspace.c b/libavfilter/colorspace.c index 7f74fe5113..f0bd14be18 100644 --- a/libavfilter/colorspace.c +++ b/libavfilter/colorspace.c @@ -62,6 +62,17 @@ void ff_matrix_mul_3x3(double dst[3][3], src2[m][1] * src1[1][n] + src2[m][2] * src1[2][n]; } + +void ff_matrix_mul_3x3_vec(double dst[3], const double vec[3], const double mat[3][3]) +{ +int m; + +for (m = 0; m < 3; m++) +dst[m] = vec[0] * mat[m][0] + + vec[1] * mat[m][1] + + vec[2] * mat[m][2]; +} + /* * see e.g. http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html */ diff --git a/libavfilter/colorspace.h b/libavfilter/colorspace.h index 879518d242..4d98b1da2e 100644 --- a/libavfilter/colorspace.h +++ b/libavfilter/colorspace.h @@ -29,6 +29,7 @@ void ff_matrix_invert_3x3(const double in[3][3], double out[3][3]); void ff_matrix_mul_3x3(double dst[3][3], const double src1[3][3], const double src2[3][3]); +void ff_matrix_mul_3x3_vec(double dst[3], const double vec[3], const double mat[3][3]); void ff_fill_rgb2xyz_table(const AVPrimaryCoefficients *coeffs, const AVWhitepointCoefficients *wp, double rgb2xyz[3][3]); -- ffmpeg-codebot ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/2] lavfi/drawutils: improve colorspace support
From: rcombs - Introduce ff_draw_init2, which takes explicit colorspace and range args - Use lavu/csp and lavfi/colorspace for conversion, rather than the lavu/colorspace.h macros - Use the passed-in colorspace when performing RGB->YUV conversions The upshot of this is: - Support for YUV spaces other than BT601 - Better rounding for all conversions - Particular rounding improvements in >8-bit formats, which previously used simple left-shifts - Support for limited-range RGB - Support for full-range YUV in non-J pixfmts Due to the rounding improvements, this results in a large number of minor changes to FATE tests. Signed-off-by: rcombs --- libavfilter/drawutils.c | 84 +-- libavfilter/drawutils.h | 26 +- tests/ref/fate/filter-chromashift-smear | 10 +- tests/ref/fate/filter-chromashift-wrap| 10 +- tests/ref/fate/filter-decimate| 480 +- tests/ref/fate/filter-fps-down| 22 +- tests/ref/fate/filter-fps-down-eof-pass | 22 +- tests/ref/fate/filter-fps-down-round-down | 20 +- tests/ref/fate/filter-fps-down-round-up | 22 +- tests/ref/fate/filter-fps-start-drop | 12 +- tests/ref/fate/filter-fps-start-fill | 12 +- tests/ref/fate/filter-fps-up | 28 +- tests/ref/fate/filter-fps-up-round-down | 28 +- tests/ref/fate/filter-fps-up-round-up | 28 +- tests/ref/fate/filter-framerate-12bit-down| 100 ++-- tests/ref/fate/filter-framerate-12bit-up | 120 ++--- tests/ref/fate/filter-framerate-down | 2 +- tests/ref/fate/filter-framerate-up| 20 +- .../filter-metadata-signalstats-yuv420p10 | 2 +- tests/ref/fate/filter-minterpolate-down | 2 +- tests/ref/fate/filter-minterpolate-up | 20 +- tests/ref/fate/filter-mpdecimate | 40 +- tests/ref/fate/filter-overlay_yuv420p10 | 6 +- tests/ref/fate/filter-overlay_yuv422p10 | 6 +- tests/ref/fate/filter-pixfmts-pad | 84 +-- tests/ref/fate/filter-pixfmts-tinterlace_pad | 22 +- tests/ref/fate/filter-testsrc2-yuv420p| 140 ++--- tests/ref/fate/filter-testsrc2-yuv444p| 140 ++--- tests/ref/fate/filter-tpad-add| 4 +- tests/ref/fate/filter-tpad-clone | 8 +- tests/ref/fate/filter-unsharp-yuv420p10 | 40 +- tests/ref/fate/filter-untile | 16 +- 32 files changed, 807 insertions(+), 769 deletions(-) diff --git a/libavfilter/drawutils.c b/libavfilter/drawutils.c index 65ed61aa92..b4083b9a95 100644 --- a/libavfilter/drawutils.c +++ b/libavfilter/drawutils.c @@ -23,9 +23,10 @@ #include "libavutil/avassert.h" #include "libavutil/avutil.h" -#include "libavutil/colorspace.h" +#include "libavutil/csp.h" #include "libavutil/intreadwrite.h" #include "libavutil/pixdesc.h" +#include "colorspace.h" #include "drawutils.h" #include "formats.h" @@ -76,13 +77,14 @@ int ff_fill_rgba_map(uint8_t *rgba_map, enum AVPixelFormat pix_fmt) return 0; } -int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags) +int ff_draw_init2(FFDrawContext *draw, enum AVPixelFormat format, enum AVColorSpace csp, + enum AVColorRange range, unsigned flags) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format); +const AVLumaCoefficients *luma = NULL; const AVComponentDescriptor *c; unsigned i, nb_planes = 0; int pixelstep[MAX_PLANES] = { 0 }; -int full_range = 0; int depthb = 0; if (!desc || !desc->name) @@ -91,9 +93,17 @@ int ff_draw_init(FFDrawContext *draw, enum AVPixelFormat format, unsigned flags) return AVERROR(ENOSYS); if (desc->flags & ~(AV_PIX_FMT_FLAG_PLANAR | AV_PIX_FMT_FLAG_RGB | AV_PIX_FMT_FLAG_ALPHA)) return AVERROR(ENOSYS); -if (format == AV_PIX_FMT_YUVJ420P || format == AV_PIX_FMT_YUVJ422P || format == AV_PIX_FMT_YUVJ444P || -format == AV_PIX_FMT_YUVJ411P || format == AV_PIX_FMT_YUVJ440P) -full_range = 1; +if (csp == AVCOL_SPC_UNSPECIFIED) +csp = (desc->flags & AV_PIX_FMT_FLAG_RGB) ? AVCOL_SPC_RGB : AVCOL_SPC_SMPTE170M; +if (!(desc->flags & AV_PIX_FMT_FLAG_RGB) && !(luma = av_csp_luma_coeffs_from_avcsp(csp))) +return AVERROR(EINVAL); +if (range == AVCOL_RANGE_UNSPECIFIED) +range = (format == AV_PIX_FMT_YUVJ420P || format == AV_PIX_FMT_YUVJ422P || + format == AV_PIX_FMT_YUVJ444P || format == AV_PIX_FMT_YUVJ411P || + format == AV_PIX_FMT_YUVJ440P || csp == AVCOL_SPC_RGB) +? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; +if (range != AVCOL_RANGE_JPEG && range != AVCOL_RANGE_MPEG) +return AVERROR(EINVAL); for (i = 0; i < desc->nb_components; i++) {
[FFmpeg-devel] [PATCH 1/3] lavu/hwcontext_vulkan: check for encode/decode queue extensions
These are currently beta features, and aren't always present. --- libavutil/hwcontext_vulkan.c | 16 1 file changed, 16 insertions(+) diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c index 2a9b5f4aac..589a7a7d9a 100644 --- a/libavutil/hwcontext_vulkan.c +++ b/libavutil/hwcontext_vulkan.c @@ -954,8 +954,16 @@ static int setup_queue_families(AVHWDeviceContext *ctx, VkDeviceCreateInfo *cd) ((qf[i].queueFlags) & VK_QUEUE_GRAPHICS_BIT) ? " graphics" : "", ((qf[i].queueFlags) & VK_QUEUE_COMPUTE_BIT) ? " compute" : "", ((qf[i].queueFlags) & VK_QUEUE_TRANSFER_BIT) ? " transfer" : "", +#ifdef VK_KHR_video_encode_queue ((qf[i].queueFlags) & VK_QUEUE_VIDEO_ENCODE_BIT_KHR) ? " encode" : "", +#else + "", +#endif +#ifdef VK_KHR_video_decode_queue ((qf[i].queueFlags) & VK_QUEUE_VIDEO_DECODE_BIT_KHR) ? " decode" : "", +#else + "", +#endif ((qf[i].queueFlags) & VK_QUEUE_SPARSE_BINDING_BIT) ? " sparse" : "", ((qf[i].queueFlags) & VK_QUEUE_PROTECTED_BIT) ? " protected" : "", qf[i].queueCount); @@ -969,8 +977,16 @@ static int setup_queue_families(AVHWDeviceContext *ctx, VkDeviceCreateInfo *cd) graph_index = pick_queue_family(qf, num, VK_QUEUE_GRAPHICS_BIT); comp_index = pick_queue_family(qf, num, VK_QUEUE_COMPUTE_BIT); tx_index= pick_queue_family(qf, num, VK_QUEUE_TRANSFER_BIT); +#ifdef VK_KHR_video_encode_queue enc_index = pick_queue_family(qf, num, VK_QUEUE_VIDEO_ENCODE_BIT_KHR); +#else +enc_index = -1; +#endif +#ifdef VK_KHR_video_decode_queue dec_index = pick_queue_family(qf, num, VK_QUEUE_VIDEO_DECODE_BIT_KHR); +#else +dec_index = -1; +#endif /* Signalling the transfer capabilities on a queue family is optional */ if (tx_index < 0) { -- 2.39.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/3] configure: check for vulkan beta extension support
Some systems (e.g. android) provide vulkan.h, but not vulkan_beta.h. In that case, compiling vulkan.h with VK_ENABLE_BETA_EXTENSIONS enabled will result in a preprocessor error. We can check for this up-front. --- configure | 3 +++ 1 file changed, 3 insertions(+) diff --git a/configure b/configure index d67855c729..8c7311ce74 100755 --- a/configure +++ b/configure @@ -2408,6 +2408,7 @@ HAVE_LIST=" perl pod2man texi2html +vulkan_beta xmllint zlib_gzip " @@ -7008,6 +7009,8 @@ enabled crystalhd && check_lib crystalhd "stdint.h libcrystalhd/libcrystalhd_if. if enabled vulkan; then check_pkg_config_header_only vulkan "vulkan >= 1.2.189" "vulkan/vulkan.h" "defined VK_VERSION_1_2" || check_cpp_condition vulkan "vulkan/vulkan.h" "defined(VK_VERSION_1_3) || (defined(VK_VERSION_1_2) && VK_HEADER_VERSION >= 189)" +test_cflags_cc "-DVK_ENABLE_BETA_EXTENSIONS" "vulkan/vulkan.h" "1" && +enable vulkan_beta fi if enabled x86; then -- 2.39.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 3/3] lavu/vulkan: only request beta extensions if we detected they're present
Fixes build on systems where vulkan_beta.h is absent (e.g. Android) --- libavutil/hwcontext_vulkan.c | 5 - libavutil/vulkan_functions.h | 4 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/libavutil/hwcontext_vulkan.c b/libavutil/hwcontext_vulkan.c index 589a7a7d9a..67802a850d 100644 --- a/libavutil/hwcontext_vulkan.c +++ b/libavutil/hwcontext_vulkan.c @@ -16,8 +16,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "config.h" + #define VK_NO_PROTOTYPES +#if HAVE_VULKAN_BETA #define VK_ENABLE_BETA_EXTENSIONS +#endif #ifdef _WIN32 #include /* Included to prevent conflicts with CreateSemaphore */ @@ -29,7 +33,6 @@ #include -#include "config.h" #include "pixdesc.h" #include "avstring.h" #include "imgutils.h" diff --git a/libavutil/vulkan_functions.h b/libavutil/vulkan_functions.h index d15a5d9a42..4d80322540 100644 --- a/libavutil/vulkan_functions.h +++ b/libavutil/vulkan_functions.h @@ -19,8 +19,12 @@ #ifndef AVUTIL_VULKAN_FUNCTIONS_H #define AVUTIL_VULKAN_FUNCTIONS_H +#include "config.h" + #define VK_NO_PROTOTYPES +#if HAVE_VULKAN_BETA #define VK_ENABLE_BETA_EXTENSIONS +#endif #include "hwcontext.h" #include "hwcontext_vulkan.h" -- 2.39.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/3] lavc/codec.h: add AV_CODEC_CAP_SINGLE_SUB_RECT
--- doc/APIchanges | 3 +++ libavcodec/codec.h | 5 + libavcodec/version.h | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index bc52a07964..56f33aa25b 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -14,6 +14,9 @@ libavutil: 2021-04-27 API changes, most recent first: +2023-02-20 - xx - lavc 59.60.100 - codec.h + Add AV_CODEC_CAP_SINGLE_SUB_RECT. + 2023-01-29 - xx - lavc 59.59.100 - avcodec.h Add AV_CODEC_FLAG_COPY_OPAQUE and AV_CODEC_FLAG_FRAME_DURATION. diff --git a/libavcodec/codec.h b/libavcodec/codec.h index 77a1a3f5a2..c0df33ef3c 100644 --- a/libavcodec/codec.h +++ b/libavcodec/codec.h @@ -190,6 +190,11 @@ */ #define AV_CODEC_CAP_ENCODER_RECON_FRAME (1 << 22) +/** + * This encoder requires a single rectangle per AVSubtitle. + */ +#define AV_CODEC_CAP_SINGLE_SUB_RECT (1 << 23) + /** * AVProfile. */ diff --git a/libavcodec/version.h b/libavcodec/version.h index 752adc81f8..2ed4ef5547 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #include "version_major.h" -#define LIBAVCODEC_VERSION_MINOR 59 +#define LIBAVCODEC_VERSION_MINOR 60 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ -- 2.39.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/3] lavc/assenc: set AV_CODEC_CAP_SINGLE_SUB_RECT
This already gave garbled output when multiple rects were present, so this is simply documenting an existing requirement. --- libavcodec/assenc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/assenc.c b/libavcodec/assenc.c index db6fd25dd7..1c49a6685b 100644 --- a/libavcodec/assenc.c +++ b/libavcodec/assenc.c @@ -74,6 +74,7 @@ const FFCodec ff_ssa_encoder = { CODEC_LONG_NAME("ASS (Advanced SubStation Alpha) subtitle"), .p.type = AVMEDIA_TYPE_SUBTITLE, .p.id = AV_CODEC_ID_ASS, +.p.capabilities = AV_CODEC_CAP_SINGLE_SUB_RECT, .init = ass_encode_init, FF_CODEC_ENCODE_SUB_CB(ass_encode_frame), }; @@ -85,6 +86,7 @@ const FFCodec ff_ass_encoder = { CODEC_LONG_NAME("ASS (Advanced SubStation Alpha) subtitle"), .p.type = AVMEDIA_TYPE_SUBTITLE, .p.id = AV_CODEC_ID_ASS, +.p.capabilities = AV_CODEC_CAP_SINGLE_SUB_RECT, .init = ass_encode_init, FF_CODEC_ENCODE_SUB_CB(ass_encode_frame), }; -- 2.39.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 3/3] ffmpeg: respect AV_CODEC_CAP_SINGLE_SUB_RECT
Fixes ASS output when multiple rects are present. --- fftools/ffmpeg.c | 28 ++-- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 9884e0c6c6..23eac52438 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -1021,6 +1021,7 @@ static void do_subtitle_out(OutputFile *of, AVCodecContext *enc; AVPacket *pkt = ost->pkt; int64_t pts; +int single_rect; if (sub->pts == AV_NOPTS_VALUE) { av_log(ost, AV_LOG_ERROR, "Subtitle packets must have a pts\n"); @@ -1031,11 +1032,15 @@ static void do_subtitle_out(OutputFile *of, enc = ost->enc_ctx; +single_rect = !!(enc->codec->capabilities & AV_CODEC_CAP_SINGLE_SUB_RECT); + /* Note: DVB subtitle need one packet to draw them and one other packet to clear them */ /* XXX: signal it in the codec context ? */ if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE) nb = 2; +else if (single_rect) +nb = FFMAX(sub->num_rects, 1); else nb = 1; @@ -1044,7 +1049,7 @@ static void do_subtitle_out(OutputFile *of, if (output_files[ost->file_index]->start_time != AV_NOPTS_VALUE) pts -= output_files[ost->file_index]->start_time; for (i = 0; i < nb; i++) { -unsigned save_num_rects = sub->num_rects; +AVSubtitle local_sub = *sub; if (!check_recording_time(ost, pts, AV_TIME_BASE_Q)) return; @@ -1053,19 +1058,22 @@ static void do_subtitle_out(OutputFile *of, if (ret < 0) report_and_exit(AVERROR(ENOMEM)); -sub->pts = pts; +local_sub.pts = pts; // start_display_time is required to be 0 -sub->pts += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, AV_TIME_BASE_Q); -sub->end_display_time -= sub->start_display_time; -sub->start_display_time = 0; -if (i == 1) -sub->num_rects = 0; +local_sub.pts += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, AV_TIME_BASE_Q); +local_sub.end_display_time -= sub->start_display_time; +local_sub.start_display_time = 0; + +if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE && i == 1) +local_sub.num_rects = 0; +else if (single_rect && sub->num_rects > 0) { +local_sub.num_rects = 1; +local_sub.rects += i; +} ost->frames_encoded++; -subtitle_out_size = avcodec_encode_subtitle(enc, pkt->data, pkt->size, sub); -if (i == 1) -sub->num_rects = save_num_rects; +subtitle_out_size = avcodec_encode_subtitle(enc, pkt->data, pkt->size, &local_sub); if (subtitle_out_size < 0) { av_log(ost, AV_LOG_FATAL, "Subtitle encoding failed\n"); exit_program(1); -- 2.39.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/2] fftools: set process code page to UTF-8 on Windows
This causes char-based filesystem and other API calls to accept and produce UTF-8 strings instead of locale-dependent legacy code page strings, when running on Win10 or newer. By and large, ffmpeg uses the wide-character equivalents of these APIs, so this shouldn't have any effect on most usage. --- fftools/fftools.manifest | 1 + 1 file changed, 1 insertion(+) diff --git a/fftools/fftools.manifest b/fftools/fftools.manifest index f2708ecb13..eaef6cacf1 100644 --- a/fftools/fftools.manifest +++ b/fftools/fftools.manifest @@ -4,6 +4,7 @@ http://schemas.microsoft.com/SMI/2005/WindowsSettings";>true http://schemas.microsoft.com/SMI/2016/WindowsSettings";>PerMonitorV2 + http://schemas.microsoft.com/SMI/2019/WindowsSettings";>UTF-8 -- 2.39.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 2/2] fftools: enable long path support on Windows
This allows use of filesystem paths longer than MAX_PATH (260 characters) on Windows 10 version 1607 and later. This _may_ be a no-op if a "LongPathsEnabled" isn't set in the registry. --- fftools/fftools.manifest | 1 + 1 file changed, 1 insertion(+) diff --git a/fftools/fftools.manifest b/fftools/fftools.manifest index eaef6cacf1..34124c8298 100644 --- a/fftools/fftools.manifest +++ b/fftools/fftools.manifest @@ -5,6 +5,7 @@ http://schemas.microsoft.com/SMI/2005/WindowsSettings";>true http://schemas.microsoft.com/SMI/2016/WindowsSettings";>PerMonitorV2 http://schemas.microsoft.com/SMI/2019/WindowsSettings";>UTF-8 + http://schemas.microsoft.com/SMI/2019/WindowsSettings";>true -- 2.39.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-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 1/2] ffmpeg: send only one rect per packet when encoding ASS
The packet and rect formats are identical, so there's no support for multiple rects per packet. --- fftools/ffmpeg.c | 25 +++-- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index d721a5e721..438bee8fef 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -1072,6 +1072,8 @@ static void do_subtitle_out(OutputFile *of, /* XXX: signal it in the codec context ? */ if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE) nb = 2; +else if (enc->codec_id == AV_CODEC_ID_ASS) +nb = FFMAX(sub->num_rects, 1); else nb = 1; @@ -1080,7 +1082,7 @@ static void do_subtitle_out(OutputFile *of, if (output_files[ost->file_index]->start_time != AV_NOPTS_VALUE) pts -= output_files[ost->file_index]->start_time; for (i = 0; i < nb; i++) { -unsigned save_num_rects = sub->num_rects; +AVSubtitle local_sub = *sub; if (!check_recording_time(ost, pts, AV_TIME_BASE_Q)) return; @@ -1089,19 +1091,22 @@ static void do_subtitle_out(OutputFile *of, if (ret < 0) report_and_exit(AVERROR(ENOMEM)); -sub->pts = pts; +local_sub.pts = pts; // start_display_time is required to be 0 -sub->pts += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, AV_TIME_BASE_Q); -sub->end_display_time -= sub->start_display_time; -sub->start_display_time = 0; -if (i == 1) -sub->num_rects = 0; +local_sub.pts += av_rescale_q(sub->start_display_time, (AVRational){ 1, 1000 }, AV_TIME_BASE_Q); +local_sub.end_display_time -= sub->start_display_time; +local_sub.start_display_time = 0; + +if (enc->codec_id == AV_CODEC_ID_DVB_SUBTITLE && i == 1) +local_sub.num_rects = 0; +else if (enc->codec_id == AV_CODEC_ID_ASS && sub->num_rects > 0) { +local_sub.num_rects = 1; +local_sub.rects += i; +} ost->frames_encoded++; -subtitle_out_size = avcodec_encode_subtitle(enc, pkt->data, pkt->size, sub); -if (i == 1) -sub->num_rects = save_num_rects; +subtitle_out_size = avcodec_encode_subtitle(enc, pkt->data, pkt->size, &local_sub); if (subtitle_out_size < 0) { av_log(ost, AV_LOG_FATAL, "Subtitle encoding failed\n"); exit_program(1); -- 2.39.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-requ...@ffmpeg.org with subject "unsubscribe".