Re: [FFmpeg-devel] [PATCH] libavcodec/qsvenc: Enable fixed QP configure in qsv CQP runtime
> On Wed, 2022-06-15 at 15:25 +0800, Wenbin Chen wrote: > > From: Yue Heng > > > > Enable dynamic QP configuration in runtime on qsv encoder. Through > > AVFrame->metadata, we can set key "qsv_config_qp" to change QP > > configuration when we encode video in CQP mode. > > > > Signed-off-by: Yue Heng > > Signed-off-by: Wenbin Chen > > --- > > doc/encoders.texi | 9 +++ > > libavcodec/qsvenc.c | 59 > + > > 2 files changed, 68 insertions(+) > > > > diff --git a/doc/encoders.texi b/doc/encoders.texi > > index 9796a606fa..1eb75e199a 100644 > > --- a/doc/encoders.texi > > +++ b/doc/encoders.texi > > @@ -,6 +,15 @@ Forcing I frames as IDR frames. > > For encoders set this flag to ON to reduce power consumption and GPU > usage. > > @end table > > > > +@subsection Runtime Options > > +Following options can be used durning qsv encoding. > > + > > +@table @option > > +@item @var{qsv_config_qp} > > +This option can be set in per-frame metadata. QP parameter can be > dynamically > > +changed when encode in CQP mode. > > +@end table > > + > > @subsection H264 options > > These options are used by h264_qsv > > > > diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c > > index 2b3b06767d..52462950be 100644 > > --- a/libavcodec/qsvenc.c > > +++ b/libavcodec/qsvenc.c > > @@ -146,6 +146,14 @@ static const struct { > > { MFX_RATECONTROL_QVBR,"QVBR" }, > > }; > > > > +#define UPDATE_PARAM(a, b) \ > > +do {\ > > +if ((a) != (b)) { \ > > +a = b; \ > > +updated = 1;\ > > +} \ > > +} while (0) \ > > + > > static const char *print_ratecontrol(mfxU16 rc_mode) > > { > > int i; > > @@ -1520,6 +1528,53 @@ static void > print_interlace_msg(AVCodecContext *avctx, > > QSVEncContext *q) > > } > > } > > > > +static int update_qp(AVCodecContext *avctx, QSVEncContext *q, > > + const AVFrame *frame) > > +{ > > +int updated = 0, qp = 0, new_qp; > > +AVDictionaryEntry *entry = av_dict_get(frame->metadata, > "qsv_config_qp", > > + NULL, 0); > > +if (entry && q->param.mfx.RateControlMethod == > MFX_RATECONTROL_CQP) { > > +qp = atoi(entry->value); > > I think it is better to use strtol() because atoi() doesn't detect errors. See > `man atoi` Will change to strtol(). > > > > +av_log(avctx, AV_LOG_DEBUG, "Configure qp: %d\n",qp); > > +if (qp < 0 || qp > 51) > > +av_log(avctx, AV_LOG_WARNING, "Invalid qp, clip to 0 ~ 51\n"); > > Is this feature for H264 and H265 only ? I will add a codec check here. > > > + > > +qp = av_clip(qp, 0, 51); > > +UPDATE_PARAM(q->param.mfx.QPP, qp); > > +new_qp = av_clip(qp * fabs(avctx->i_quant_factor) + > > +avctx->i_quant_offset, 0, 51); > > +UPDATE_PARAM(q->param.mfx.QPI, new_qp); > > +new_qp = av_clip(qp * fabs(avctx->b_quant_factor) + > > +avctx->b_quant_offset, 0, 51); > > +UPDATE_PARAM(q->param.mfx.QPB, new_qp); > > +av_log(avctx, AV_LOG_DEBUG, > > +"using fixed qp = %d/%d/%d for idr/p/b frames\n", > > +q->param.mfx.QPI, q->param.mfx.QPP, q->param.mfx.QPB); > > +} > > +return updated; > > +} > > + > > +static int update_parameters(AVCodecContext *avctx, QSVEncContext *q, > > + const AVFrame *frame) > > +{ > > +int needReset = 0, ret = 0; > > + > > +if (!frame) > > +return 0; > > + > > +needReset = update_qp(avctx, q, frame); > > +if (needReset) { > > +q->param.ExtParam= q->extparam_internal; > > +q->param.NumExtParam = q->nb_extparam_internal; > > User might provide external parameters in avctx->hwaccel_context. Are > these > parameters not required in MFXVideoENCODE_Reset() ? Miss the user provided parameters. I will add them as well. > > Thanks > Haihao Thanks for your review. I will fix these in new patch. Thanks Wenbin > > > +av_log(avctx, AV_LOG_DEBUG, "Parameter change, call msdk > reset.\n"); > > +ret = MFXVideoENCODE_Reset(q->session, &q->param); > > +if (ret < 0) > > +return ff_qsv_print_error(avctx, ret, "Error during > > resetting"); > > +} > > +return 0; > > +} > > + > > static int encode_frame(AVCodecContext *avctx, QSVEncContext *q, > > const AVFrame *frame) > > { > > @@ -1630,6 +1685,10 @@ int ff_qsv_encode(AVCodecContext *avctx, > QSVEncContext > > *q, > > { > > int ret; > > > > +ret = update_parameters(avctx, q, frame); > > +if (ret < 0) > > +return ret; > > + > > ret = encode_frame(avctx, q, frame); > > if (ret < 0) > > return ret; > ___ > ffmpeg-devel mailing list > ffmpeg-devel@ffmpeg.org > http
[FFmpeg-devel] [PATCH v3 6/6] avformat/movenc: handle OOM situations when parsing AC-3 headers
From: Jan Ekström Signed-off-by: Jan Ekström --- libavformat/movenc.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index a071f1cdd5..58ba0bc545 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -420,7 +420,10 @@ static int handle_eac3(MOVMuxContext *mov, AVPacket *pkt, MOVTrack *track) if (!info->pkt && !(info->pkt = av_packet_alloc())) return AVERROR(ENOMEM); -if (avpriv_ac3_parse_header(&hdr, pkt->data, pkt->size) < 0) { +if ((ret = avpriv_ac3_parse_header(&hdr, pkt->data, pkt->size) < 0)) { +if (ret == AVERROR(ENOMEM)) +goto end; + /* drop the packets until we see a good one */ if (!track->entry) { av_log(mov->fc, AV_LOG_WARNING, "Dropping invalid packet from start of the stream\n"); -- 2.36.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 v3 5/6] avformat/movenc: utilize existing AC-3 parsing workflow for AC-3
From: Jan Ekström Signed-off-by: Jan Ekström --- libavcodec/Makefile | 1 + libavformat/Makefile | 1 + libavformat/ac3_bitrate_tab.c | 22 ++ libavformat/movenc.c | 55 +-- 4 files changed, 51 insertions(+), 28 deletions(-) create mode 100644 libavformat/ac3_bitrate_tab.c diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 10697d31f7..7e0d278e3d 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -1018,6 +1018,7 @@ STLIBOBJS-$(CONFIG_FLV_MUXER) += mpeg4audio_sample_rates.o STLIBOBJS-$(CONFIG_HLS_DEMUXER)+= ac3_channel_layout_tab.o STLIBOBJS-$(CONFIG_MATROSKA_DEMUXER) += mpeg4audio_sample_rates.o STLIBOBJS-$(CONFIG_MOV_DEMUXER)+= ac3_channel_layout_tab.o +STLIBOBJS-$(CONFIG_MOV_MUXER) += ac3_bitrate_tab.o STLIBOBJS-$(CONFIG_MXF_MUXER) += golomb.o STLIBOBJS-$(CONFIG_MP3_MUXER) += mpegaudiotabs.o STLIBOBJS-$(CONFIG_NUT_MUXER) += mpegaudiotabs.o diff --git a/libavformat/Makefile b/libavformat/Makefile index 1416bf31bd..c71de95b2f 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -699,6 +699,7 @@ SHLIBOBJS-$(CONFIG_FLV_MUXER)+= mpeg4audio_sample_rates.o SHLIBOBJS-$(CONFIG_HLS_DEMUXER) += ac3_channel_layout_tab.o SHLIBOBJS-$(CONFIG_MATROSKA_DEMUXER) += mpeg4audio_sample_rates.o SHLIBOBJS-$(CONFIG_MOV_DEMUXER) += ac3_channel_layout_tab.o +SHLIBOBJS-$(CONFIG_MOV_MUXER)+= ac3_bitrate_tab.o SHLIBOBJS-$(CONFIG_MP3_MUXER)+= mpegaudiotabs.o SHLIBOBJS-$(CONFIG_MXF_MUXER)+= golomb_tab.o SHLIBOBJS-$(CONFIG_NUT_MUXER)+= mpegaudiotabs.o diff --git a/libavformat/ac3_bitrate_tab.c b/libavformat/ac3_bitrate_tab.c new file mode 100644 index 00..57b6181511 --- /dev/null +++ b/libavformat/ac3_bitrate_tab.c @@ -0,0 +1,22 @@ +/* + * AC-3 bit rate table + * copyright (c) 2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavcodec/ac3_bitrate_tab.h" diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 103f958d75..a071f1cdd5 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -36,6 +36,7 @@ #include "av1.h" #include "avc.h" #include "libavcodec/ac3_parser_internal.h" +#include "libavcodec/ac3tab.h" #include "libavcodec/dnxhddata.h" #include "libavcodec/flac.h" #include "libavcodec/get_bits.h" @@ -362,44 +363,42 @@ struct eac3_info { static int mov_write_ac3_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track) { -GetBitContext gbc; +struct eac3_info *info = track->eac3_priv; +int8_t ac3_bit_rate_code = -1; PutBitContext pbc; uint8_t buf[3]; -int fscod, bsid, bsmod, acmod, lfeon, frmsizecod; -if (track->vos_len < 7) { +if (!info || !info->ec3_done) { av_log(s, AV_LOG_ERROR, "Cannot write moov atom before AC3 packets." " Set the delay_moov flag to fix this.\n"); return AVERROR(EINVAL); } -avio_wb32(pb, 11); -ffio_wfourcc(pb, "dac3"); +for (unsigned int i = 0; i < FF_ARRAY_ELEMS(ff_ac3_bitrate_tab); i++) { +if (info->data_rate == ff_ac3_bitrate_tab[i]) { +ac3_bit_rate_code = i; +break; +} +} -init_get_bits(&gbc, track->vos_data + 4, (track->vos_len - 4) * 8); -fscod = get_bits(&gbc, 2); -frmsizecod = get_bits(&gbc, 6); -bsid = get_bits(&gbc, 5); -bsmod = get_bits(&gbc, 3); -acmod = get_bits(&gbc, 3); -if (acmod == 2) { -skip_bits(&gbc, 2); // dsurmod -} else { -if ((acmod & 1) && acmod != 1) -skip_bits(&gbc, 2); // cmixlev -if (acmod & 4) -skip_bits(&gbc, 2); // surmixlev +if (ac3_bit_rate_code < 0) { +av_log(s, AV_LOG_ERROR, + "No valid AC3 bit rate code for data rate of %d!\n", + info->data_rate); +return AVERROR(EINVAL); } -lfeon = get_bits1(&gbc); + +avio_wb32(pb, 11); +ffio_wfourcc(pb, "dac3"); init_put_bits(&pbc, buf, sizeof(buf)); -put_bits(&pbc, 2, fscod); -put_bits(&pbc, 5, bsid); -put_bits(&pbc, 3, bsmod); -put_bits(&pbc, 3, acmod);
[FFmpeg-devel] [PATCH v3 4/6] avformat/movenc: move eac3_info definition so that it can be used for AC-3
From: Jan Ekström Signed-off-by: Jan Ekström --- libavformat/movenc.c | 64 ++-- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index c24b11cf5f..103f958d75 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -328,6 +328,38 @@ static int mov_write_amr_tag(AVIOContext *pb, MOVTrack *track) return 0x11; } +struct eac3_info { +AVPacket *pkt; +uint8_t ec3_done; +uint8_t num_blocks; + +/* Layout of the EC3SpecificBox */ +/* maximum bitrate */ +uint16_t data_rate; +/* number of independent substreams */ +uint8_t num_ind_sub; +struct { +/* sample rate code (see ff_ac3_sample_rate_tab) 2 bits */ +uint8_t fscod; +/* bit stream identification 5 bits */ +uint8_t bsid; +/* one bit reserved */ +/* audio service mixing (not supported yet) 1 bit */ +/* bit stream mode 3 bits */ +uint8_t bsmod; +/* audio coding mode 3 bits */ +uint8_t acmod; +/* sub woofer on 1 bit */ +uint8_t lfeon; +/* 3 bits reserved */ +/* number of dependent substreams associated with this substream 4 bits */ +uint8_t num_dep_sub; +/* channel locations of the dependent substream(s), if any, 9 bits */ +uint16_t chan_loc; +/* if there is no dependent substream, then one bit reserved instead */ +} substream[1]; /* TODO: support 8 independent substreams */ +}; + static int mov_write_ac3_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track) { GetBitContext gbc; @@ -376,38 +408,6 @@ static int mov_write_ac3_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *trac return 11; } -struct eac3_info { -AVPacket *pkt; -uint8_t ec3_done; -uint8_t num_blocks; - -/* Layout of the EC3SpecificBox */ -/* maximum bitrate */ -uint16_t data_rate; -/* number of independent substreams */ -uint8_t num_ind_sub; -struct { -/* sample rate code (see ff_ac3_sample_rate_tab) 2 bits */ -uint8_t fscod; -/* bit stream identification 5 bits */ -uint8_t bsid; -/* one bit reserved */ -/* audio service mixing (not supported yet) 1 bit */ -/* bit stream mode 3 bits */ -uint8_t bsmod; -/* audio coding mode 3 bits */ -uint8_t acmod; -/* sub woofer on 1 bit */ -uint8_t lfeon; -/* 3 bits reserved */ -/* number of dependent substreams associated with this substream 4 bits */ -uint8_t num_dep_sub; -/* channel locations of the dependent substream(s), if any, 9 bits */ -uint16_t chan_loc; -/* if there is no dependent substream, then one bit reserved instead */ -} substream[1]; /* TODO: support 8 independent substreams */ -}; - static int handle_eac3(MOVMuxContext *mov, AVPacket *pkt, MOVTrack *track) { AC3HeaderInfo *hdr = NULL; -- 2.36.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 v3 3/6] avformat/movenc: enable handle_eac3 to handle AC-3 tracks
From: Jan Ekström Add the AC-3 frame type, as well as early exit from additional packet parsing in case of AC-3, as only a single packet is required to get the required information. Signed-off-by: Jan Ekström --- libavformat/movenc.c | 11 ++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 87cd066c95..c24b11cf5f 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -443,7 +443,8 @@ static int handle_eac3(MOVMuxContext *mov, AVPacket *pkt, MOVTrack *track) /* this should always be the case, given that our AC-3 parser * concatenates dependent frames to their independent parent */ -if (hdr->frame_type == EAC3_FRAME_TYPE_INDEPENDENT) { +if (hdr->frame_type == EAC3_FRAME_TYPE_INDEPENDENT || +hdr->frame_type == EAC3_FRAME_TYPE_AC3_CONVERT) { /* substream ids must be incremental */ if (hdr->substreamid > info->num_ind_sub + 1) { ret = AVERROR(EINVAL); @@ -475,6 +476,14 @@ static int handle_eac3(MOVMuxContext *mov, AVPacket *pkt, MOVTrack *track) info->substream[hdr->substreamid].acmod = hdr->channel_mode; info->substream[hdr->substreamid].lfeon = hdr->lfe_on; +if (track->par->codec_id == AV_CODEC_ID_AC3) { +// with AC-3 we only require the information of a single packet, +// so we can finish as soon as the basic values of the bit stream +// have been set to the track's informational structure. +info->ec3_done = 1; +goto concatenate; +} + /* Parse dependent substream(s), if any */ if (pkt->size != hdr->frame_size) { int cumul_size = hdr->frame_size; -- 2.36.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 v3 2/6] {configure, avformat/movenc}: enable AC-3 parser for movenc
From: Jan Ekström This simplifies the code to no longer have #ifs in a manner which does not require handling avpriv_ac3_parse_header returning ENOSYS. As an existing example, the MPEG-TS muxer already requires the AC-3 parser, and in order to fix existing issues with the current AC-3 movenc code, switching to use the AC-3 parser is required, so this is an enabling change for that. Signed-off-by: Jan Ekström --- configure| 2 +- libavformat/movenc.c | 4 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/configure b/configure index 7ffbb85e21..0c5a1ae8c0 100755 --- a/configure +++ b/configure @@ -3440,7 +3440,7 @@ mlp_demuxer_select="mlp_parser" mmf_muxer_select="riffenc" mov_demuxer_select="iso_media riffdec" mov_demuxer_suggest="zlib" -mov_muxer_select="iso_media riffenc rtpenc_chain vp9_superframe_bsf aac_adtstoasc_bsf" +mov_muxer_select="iso_media riffenc rtpenc_chain vp9_superframe_bsf aac_adtstoasc_bsf ac3_parser" mp3_demuxer_select="mpegaudio_parser" mp3_muxer_select="mpegaudioheader" mp4_muxer_select="mov_muxer" diff --git a/libavformat/movenc.c b/libavformat/movenc.c index b7b2f46a17..87cd066c95 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -408,7 +408,6 @@ struct eac3_info { } substream[1]; /* TODO: support 8 independent substreams */ }; -#if CONFIG_AC3_PARSER static int handle_eac3(MOVMuxContext *mov, AVPacket *pkt, MOVTrack *track) { AC3HeaderInfo *hdr = NULL; @@ -549,7 +548,6 @@ end: return ret; } -#endif static int mov_write_eac3_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track) { @@ -6046,7 +6044,6 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) } } -#if CONFIG_AC3_PARSER } else if (par->codec_id == AV_CODEC_ID_EAC3) { size = handle_eac3(mov, pkt, trk); if (size < 0) @@ -6054,7 +6051,6 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) else if (!size) goto end; avio_write(pb, pkt->data, size); -#endif } else if (par->codec_id == AV_CODEC_ID_EIA_608) { size = 8; -- 2.36.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 v3 1/6] avcodec: make AC-3 bit rate table available in a separate header
From: Jan Ekström This makes it possible to include it from libavformat Signed-off-by: Jan Ekström --- libavcodec/Makefile | 8 +--- libavcodec/ac3_bitrate_tab.c | 22 ++ libavcodec/ac3_bitrate_tab.h | 33 + libavcodec/ac3tab.c | 6 -- 4 files changed, 60 insertions(+), 9 deletions(-) create mode 100644 libavcodec/ac3_bitrate_tab.c create mode 100644 libavcodec/ac3_bitrate_tab.h diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 3b8f7b5e01..10697d31f7 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -190,8 +190,9 @@ OBJS-$(CONFIG_AC3_DECODER) += ac3dec_float.o ac3dec_data.o ac3.o \ OBJS-$(CONFIG_AC3_FIXED_DECODER) += ac3dec_fixed.o ac3dec_data.o ac3.o \ kbdwin.o ac3tab.o ac3_channel_layout_tab.o OBJS-$(CONFIG_AC3_ENCODER) += ac3enc_float.o ac3enc.o ac3tab.o \ - ac3.o kbdwin.o -OBJS-$(CONFIG_AC3_FIXED_ENCODER) += ac3enc_fixed.o ac3enc.o ac3tab.o ac3.o kbdwin.o + ac3.o kbdwin.o ac3_bitrate_tab.o +OBJS-$(CONFIG_AC3_FIXED_ENCODER) += ac3enc_fixed.o ac3enc.o ac3tab.o \ + ac3.o kbdwin.o ac3_bitrate_tab.o OBJS-$(CONFIG_AC3_MF_ENCODER) += mfenc.o mf_utils.o OBJS-$(CONFIG_ACELP_KELVIN_DECODER)+= g729dec.o lsp.o celp_math.o celp_filters.o acelp_filters.o acelp_pitch_delay.o acelp_vectors.o g729postfilter.o OBJS-$(CONFIG_AGM_DECODER) += agm.o @@ -1110,7 +,8 @@ OBJS-$(CONFIG_LIBZVBI_TELETEXT_DECODER) += libzvbi-teletextdec.o ass.o OBJS-$(CONFIG_AAC_LATM_PARSER) += latm_parser.o OBJS-$(CONFIG_AAC_PARSER) += aac_parser.o aac_ac3_parser.o OBJS-$(CONFIG_AC3_PARSER) += aac_ac3_parser.o ac3tab.o \ - ac3_channel_layout_tab.o + ac3_channel_layout_tab.o \ + ac3_bitrate_tab.o OBJS-$(CONFIG_ADX_PARSER) += adx_parser.o adx.o OBJS-$(CONFIG_AMR_PARSER) += amr_parser.o OBJS-$(CONFIG_AV1_PARSER) += av1_parser.o diff --git a/libavcodec/ac3_bitrate_tab.c b/libavcodec/ac3_bitrate_tab.c new file mode 100644 index 00..9ae8794a4c --- /dev/null +++ b/libavcodec/ac3_bitrate_tab.c @@ -0,0 +1,22 @@ +/* + * AC-3 bit rate table + * copyright (c) 2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "ac3_bitrate_tab.h" diff --git a/libavcodec/ac3_bitrate_tab.h b/libavcodec/ac3_bitrate_tab.h new file mode 100644 index 00..44fc5f59ec --- /dev/null +++ b/libavcodec/ac3_bitrate_tab.h @@ -0,0 +1,33 @@ +/* + * AC-3 bit rate table + * copyright (c) 2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AC3_BITRATE_TAB_H +#define AVCODEC_AC3_BITRATE_TAB_H + +#include + +/* possible bitrates */ +const uint16_t ff_ac3_bitrate_tab[19] = { +32, 40, 48, 56, 64, 80, 96, 112, 128, +160, 192, 224, 256, 320, 384, 448, 512, 576, 640 +}; + +#endif diff --git a/libavcodec/ac3tab.c b/libavcodec/ac3tab.c index 48c89a8ba0..75865fd7d2 100644 --- a/libavcodec/ac3tab.c +++ b/libavcodec/ac3tab.c @@ -94,12 +94,6 @@ const uint8_t ff_ac3_dec_channel_map[8][2][6] = { /* possible frequencies */ const int ff_ac3_sample_rate_tab[] = { 48000, 44100, 32000, 0 }; -/* possible bitrates */ -const uint16_t ff_a
[FFmpeg-devel] [PATCH v3 0/6] avformat/movenc: normalize on AC-3 parser usage
The simplified parsing currently in `mov_write_ac3_tag` trusts the content of the packets a bit too much (the AC-3 parser returns all data fed to it, including any possible data before the start code), while the existing E-AC-3 logic does proper header validation by utilizing the (E-)AC-3 parser. Thus, normalize on AC-3 parser usage for both AC-3 and E-AC-3. Difference to v2: * libavcodec/Makefile received `STLIBOBJS-$(CONFIG_MOV_MUXER) += ac3_bitrate_tab.o` Jan Jan Ekström (6): avcodec: make AC-3 bit rate table available in a separate header {configure,avformat/movenc}: enable AC-3 parser for movenc avformat/movenc: enable handle_eac3 to handle AC-3 tracks avformat/movenc: move eac3_info definition so that it can be used for AC-3 avformat/movenc: utilize existing AC-3 parsing workflow for AC-3 avformat/movenc: handle OOM situations when parsing AC-3 headers configure | 2 +- libavcodec/Makefile | 9 ++- libavcodec/ac3_bitrate_tab.c | 22 +++ libavcodec/ac3_bitrate_tab.h | 33 ++ libavcodec/ac3tab.c | 6 -- libavformat/Makefile | 1 + libavformat/ac3_bitrate_tab.c | 22 +++ libavformat/movenc.c | 121 ++ 8 files changed, 149 insertions(+), 67 deletions(-) create mode 100644 libavcodec/ac3_bitrate_tab.c create mode 100644 libavcodec/ac3_bitrate_tab.h create mode 100644 libavformat/ac3_bitrate_tab.c -- 2.36.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] libavcodec/qsvenc: Enable fixed QP configure in qsv CQP runtime
On Wed, 2022-06-15 at 15:25 +0800, Wenbin Chen wrote: > From: Yue Heng > > Enable dynamic QP configuration in runtime on qsv encoder. Through > AVFrame->metadata, we can set key "qsv_config_qp" to change QP > configuration when we encode video in CQP mode. > > Signed-off-by: Yue Heng > Signed-off-by: Wenbin Chen > --- > doc/encoders.texi | 9 +++ > libavcodec/qsvenc.c | 59 + > 2 files changed, 68 insertions(+) > > diff --git a/doc/encoders.texi b/doc/encoders.texi > index 9796a606fa..1eb75e199a 100644 > --- a/doc/encoders.texi > +++ b/doc/encoders.texi > @@ -,6 +,15 @@ Forcing I frames as IDR frames. > For encoders set this flag to ON to reduce power consumption and GPU usage. > @end table > > +@subsection Runtime Options > +Following options can be used durning qsv encoding. > + > +@table @option > +@item @var{qsv_config_qp} > +This option can be set in per-frame metadata. QP parameter can be dynamically > +changed when encode in CQP mode. > +@end table > + > @subsection H264 options > These options are used by h264_qsv > > diff --git a/libavcodec/qsvenc.c b/libavcodec/qsvenc.c > index 2b3b06767d..52462950be 100644 > --- a/libavcodec/qsvenc.c > +++ b/libavcodec/qsvenc.c > @@ -146,6 +146,14 @@ static const struct { > { MFX_RATECONTROL_QVBR,"QVBR" }, > }; > > +#define UPDATE_PARAM(a, b) \ > +do {\ > +if ((a) != (b)) { \ > +a = b; \ > +updated = 1;\ > +} \ > +} while (0) \ > + > static const char *print_ratecontrol(mfxU16 rc_mode) > { > int i; > @@ -1520,6 +1528,53 @@ static void print_interlace_msg(AVCodecContext *avctx, > QSVEncContext *q) > } > } > > +static int update_qp(AVCodecContext *avctx, QSVEncContext *q, > + const AVFrame *frame) > +{ > +int updated = 0, qp = 0, new_qp; > +AVDictionaryEntry *entry = av_dict_get(frame->metadata, "qsv_config_qp", > + NULL, 0); > +if (entry && q->param.mfx.RateControlMethod == MFX_RATECONTROL_CQP) { > +qp = atoi(entry->value); I think it is better to use strtol() because atoi() doesn't detect errors. See `man atoi` > +av_log(avctx, AV_LOG_DEBUG, "Configure qp: %d\n",qp); > +if (qp < 0 || qp > 51) > +av_log(avctx, AV_LOG_WARNING, "Invalid qp, clip to 0 ~ 51\n"); Is this feature for H264 and H265 only ? > + > +qp = av_clip(qp, 0, 51); > +UPDATE_PARAM(q->param.mfx.QPP, qp); > +new_qp = av_clip(qp * fabs(avctx->i_quant_factor) + > +avctx->i_quant_offset, 0, 51); > +UPDATE_PARAM(q->param.mfx.QPI, new_qp); > +new_qp = av_clip(qp * fabs(avctx->b_quant_factor) + > +avctx->b_quant_offset, 0, 51); > +UPDATE_PARAM(q->param.mfx.QPB, new_qp); > +av_log(avctx, AV_LOG_DEBUG, > +"using fixed qp = %d/%d/%d for idr/p/b frames\n", > +q->param.mfx.QPI, q->param.mfx.QPP, q->param.mfx.QPB); > +} > +return updated; > +} > + > +static int update_parameters(AVCodecContext *avctx, QSVEncContext *q, > + const AVFrame *frame) > +{ > +int needReset = 0, ret = 0; > + > +if (!frame) > +return 0; > + > +needReset = update_qp(avctx, q, frame); > +if (needReset) { > +q->param.ExtParam= q->extparam_internal; > +q->param.NumExtParam = q->nb_extparam_internal; User might provide external parameters in avctx->hwaccel_context. Are these parameters not required in MFXVideoENCODE_Reset() ? Thanks Haihao > +av_log(avctx, AV_LOG_DEBUG, "Parameter change, call msdk reset.\n"); > +ret = MFXVideoENCODE_Reset(q->session, &q->param); > +if (ret < 0) > +return ff_qsv_print_error(avctx, ret, "Error during resetting"); > +} > +return 0; > +} > + > static int encode_frame(AVCodecContext *avctx, QSVEncContext *q, > const AVFrame *frame) > { > @@ -1630,6 +1685,10 @@ int ff_qsv_encode(AVCodecContext *avctx, QSVEncContext > *q, > { > int ret; > > +ret = update_parameters(avctx, q, frame); > +if (ret < 0) > +return ret; > + > ret = encode_frame(avctx, q, frame); > if (ret < 0) > return ret; ___ 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] avformat/matroskaenc: Reuse dynamic buffer
Avoids some allocations. Signed-off-by: Andreas Rheinhardt --- libavformat/matroskaenc.c | 21 +++-- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index acb50017b6..bfc397dbe6 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -222,7 +222,8 @@ typedef struct MatroskaMuxContext { * to write the length field of EBML Masters. * Every user has to reset the buffer after using it and * different uses may not overlap. It is currently used in - * mkv_write_tag(). */ + * mkv_write_tag(), in mkv_assemble_cues() as well as in + * mkv_update_codecprivate() and mkv_write_track(). */ AVIOContext*tmp_bc; AVPacket *cur_audio_pkt; @@ -941,17 +942,10 @@ static int mkv_add_cuepoint(MatroskaMuxContext *mkv, int stream, int64_t ts, return 0; } -static int mkv_assemble_cues(AVStream **streams, AVIOContext *dyn_cp, +static int mkv_assemble_cues(AVStream **streams, AVIOContext *dyn_cp, AVIOContext *cuepoint, const mkv_cues *cues, mkv_track *tracks, int num_tracks, uint64_t offset) { -AVIOContext *cuepoint; -int ret; - -ret = avio_open_dyn_buf(&cuepoint); -if (ret < 0) -return ret; - for (mkv_cuepoint *entry = cues->entries, *end = entry + cues->num_entries; entry < end;) { uint64_t pts = entry->pts; @@ -981,14 +975,13 @@ static int mkv_assemble_cues(AVStream **streams, AVIOContext *dyn_cp, end_ebml_master(cuepoint, track_positions); } while (++entry < end && entry->pts == pts); size = avio_get_dyn_buf(cuepoint, &buf); -if ((ret = cuepoint->error) < 0) -break; +if (cuepoint->error < 0) +return cuepoint->error; put_ebml_binary(dyn_cp, MATROSKA_ID_POINTENTRY, buf, size); ffio_reset_dyn_buf(cuepoint); } -ffio_free_dyn_buf(&cuepoint); -return ret; +return 0; } static int put_xiph_codecpriv(AVFormatContext *s, AVIOContext *pb, @@ -2964,7 +2957,7 @@ redo_cues: if (ret < 0) return ret; -ret = mkv_assemble_cues(s->streams, cues, &mkv->cues, +ret = mkv_assemble_cues(s->streams, cues, mkv->tmp_bc, &mkv->cues, mkv->tracks, s->nb_streams, offset); if (ret < 0) { ffio_free_dyn_buf(&cues); -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
Re: [FFmpeg-devel] [PATCH v3 3/5] avcodec/avs2_parser: parse more info
At 2022-06-13 11:36:34, "Zhao Zhili" wrote: >Including video resolution, framerate and picture type, etc. > >Signed-off-by: Zhao Zhili >--- > libavcodec/Makefile | 2 +- > libavcodec/avs2.c| 42 > libavcodec/avs2.h| 10 > libavcodec/avs2_parser.c | 105 +++ > 4 files changed, 158 insertions(+), 1 deletion(-) > create mode 100644 libavcodec/avs2.c > >diff --git a/libavcodec/Makefile b/libavcodec/Makefile >index 3b8f7b5e01..6cc6f8437c 100644 >--- a/libavcodec/Makefile >+++ b/libavcodec/Makefile >@@ -1114,7 +1114,7 @@ OBJS-$(CONFIG_AC3_PARSER) += >aac_ac3_parser.o ac3tab.o \ > OBJS-$(CONFIG_ADX_PARSER) += adx_parser.o adx.o > OBJS-$(CONFIG_AMR_PARSER) += amr_parser.o > OBJS-$(CONFIG_AV1_PARSER) += av1_parser.o >-OBJS-$(CONFIG_AVS2_PARSER) += avs2_parser.o >+OBJS-$(CONFIG_AVS2_PARSER) += avs2.o avs2_parser.o > OBJS-$(CONFIG_AVS3_PARSER) += avs3_parser.o > OBJS-$(CONFIG_BMP_PARSER) += bmp_parser.o > OBJS-$(CONFIG_CAVSVIDEO_PARSER)+= cavs_parser.o >diff --git a/libavcodec/avs2.c b/libavcodec/avs2.c >new file mode 100644 >index 00..ead8687d0a >--- /dev/null >+++ b/libavcodec/avs2.c >@@ -0,0 +1,42 @@ >+/* >+ * AVS2 related definitions >+ * >+ * Copyright (C) 2022 Zhao Zhili, >+ * >+ * This file is part of FFmpeg. >+ * >+ * FFmpeg is free software; you can redistribute it and/or >+ * modify it under the terms of the GNU Lesser General Public >+ * License as published by the Free Software Foundation; either >+ * version 2.1 of the License, or (at your option) any later version. >+ * >+ * FFmpeg is distributed in the hope that it will be useful, >+ * but WITHOUT ANY WARRANTY; without even the implied warranty of >+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU >+ * Lesser General Public License for more details. >+ * >+ * You should have received a copy of the GNU Lesser General Public >+ * License along with FFmpeg; if not, write to the Free Software >+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 >USA >+ */ >+ >+#include "avs2.h" >+ >+const AVRational ff_avs2_frame_rate_tab[16] = { >+{ 0, 0 }, // forbid >+{ 24000, 1001}, >+{ 24 , 1 }, >+{ 25 , 1 }, >+{ 3, 1001}, >+{ 30 , 1 }, >+{ 50 , 1 }, >+{ 6, 1001}, >+{ 60 , 1 }, >+{ 100 , 1 }, >+{ 120 , 1 }, >+{ 200 , 1 }, >+{ 240 , 1 }, >+{ 300 , 1 }, >+{ 0, 0 }, // reserved >+{ 0, 0 } // reserved >+}; That table seems to appear only in avs2 decoder. If so, they are supposed to be declared in libdavs2.c. If not, please point out the usage of this separate source file. Persionally, the frame_rate table can be used in both encoder and decoder. So it is what should be defined in the avs2.h (with related enc/dec changes). >diff --git a/libavcodec/avs2.h b/libavcodec/avs2.h >index f342ba52a0..544cf502d7 100644 >--- a/libavcodec/avs2.h >+++ b/libavcodec/avs2.h >@@ -23,6 +23,8 @@ > #ifndef AVCODEC_AVS2_H > #define AVCODEC_AVS2_H > >+#include "libavutil/rational.h" >+ > #define AVS2_SLICE_MAX_START_CODE0x01AF > > enum { >@@ -38,4 +40,12 @@ enum { > #define AVS2_ISPIC(x) ((x) == AVS2_INTRA_PIC_START_CODE || (x) == > AVS2_INTER_PIC_START_CODE) > #define AVS2_ISUNIT(x) ((x) == AVS2_SEQ_START_CODE || AVS2_ISPIC(x)) > Same as above. Mentioned definitions now are only used in avs2_parser.c. If so, they are supposed to be kept in avs2_parser.c. >+enum AVS2Profile { >+AVS2_PROFILE_MAIN_PIC = 0x12, >+AVS2_PROFILE_MAIN = 0x20, >+AVS2_PROFILE_MAIN10 = 0x22, >+}; Not mentioned elsewhere. If they are to work in the encoder/decoder, please package them with related changes. >+ >+extern const AVRational ff_avs2_frame_rate_tab[16]; >+ > #endif >diff --git a/libavcodec/avs2_parser.c b/libavcodec/avs2_parser.c >index 71cf442903..0350517493 100644 >--- a/libavcodec/avs2_parser.c >+++ b/libavcodec/avs2_parser.c >@@ -19,7 +19,9 @@ > * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 > USA > */ > >+#include "libavutil/avutil.h" > #include "avs2.h" >+#include "get_bits.h" > #include "parser.h" > > static int avs2_find_frame_end(ParseContext *pc, const uint8_t *buf, int > buf_size) >@@ -58,6 +60,107 @@ static int avs2_find_frame_end(ParseContext *pc, const >uint8_t *buf, int buf_siz > return END_NOT_FOUND; > } > >+static void parse_avs2_seq_header(AVCodecParserContext *s, const uint8_t *buf, >+ int buf_size, AVCodecContext *avctx) >+{ >+GetBitContext gb; >+int profile, level; >+int width, height; >+int chroma, sample_precision, encoding_precision = 1; >+// sample_precision and encoding_precision is 3 bits >+static const uint8_t precision[8] = { 0, 8, 10 }; >+unsigned aspect
Re: [FFmpeg-devel] [PATCH] AV1 VDPAU hwaccel Decode support
Hi Philip, The issue seems to be from MPV side rather than from ffmpeg patch. I was able to decode the clip Halo_AV1 properly bitmatching with nvcuvid output with ffmpeg + VDPAU. Please find the cmds I used to verify the same. ./ffmpeg -hwaccel vdpau -i /home/bondamanoj/VideoClips/AV1Clips/Halo_AV1.mp4 -y decoded_vdpau.yuv ./ffmpeg -hwaccel nvdec -i /home/bondamanoj/VideoClips/AV1Clips/Halo_AV1.mp4 decoded_nvcuvid.yuv cmp decoded_vdpau.yuv ~/Downloads/ffmpeg-git2/FFmpeg/decoded_nvcuvid.yuv The same clip is dumped using mpv via cmd ./mpv --hwdec=vdpau-copy --o=Halo_dump_av1.yuv --of=rawvideo /home/bondamanoj/VideoClips/AV1Clips/Halo_AV1.mp4 Is differing and is having corruption while playing. Thanks, ManojGupta. > -Original Message- > From: Philip Langdale > Sent: Thursday, May 19, 2022 10:25 PM > To: Manoj Bonda > Cc: Andy Ritger ; Aaron Plattner > ; Mandar Godse ; Ashish Roy > ; Hardy Doelfel > Subject: Re: [FFmpeg-devel] [PATCH] AV1 VDPAU hwaccel Decode support > > External email: Use caution opening links or attachments > > > On Thu, 19 May 2022 09:01:26 + > Manoj Bonda wrote: > > > Hi Philip, > > > > As mentioned earlier I am getting output matching with nvcuvid for > > VDPAU While using ffmpeg. > > With MPV I am not seeing issue with below cmd ./mpv --vo=vdpau > > --hwdec=vdpau > > /home/bondamanoj/VideoClips/AV1Clips/Chimera-AV1-8bit-1280x720- > 3363kbp > > s.ivf > > > > I am getting mpv failures with --vo=opengl or --vo=gpu and not > > decoding the clip. Can you please share us the cmds and the clip used > > by you where you saw corruption. So I can debug and fix the issue. > > Ok, it seems weird. > > I've been using youtube clips, so here's one from their original AV1 playlist > (The Halo Infinite announce trailer): > > https://nam11.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww. > youtube.com%2Fwatch%3Fv%3DFmdb- > KmlzD8&data=05%7C01%7Cmbonda%40nvidia.com%7Cf69926f451734 > 86cf2f208da39b8430d%7C43083d15727340c1b7db39efd9ccc17a%7C0%7C0 > %7C637885760832069373%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLj > AwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000%7C% > 7C%7C&sdata=Kw2mXnUdaupPhwBq13MCCiciZo6alDqTpM6sh88TMtg% > 3D&reserved=0 > > You then need yt-dlp installed. > > If you tell mpv to play the URL directly, it will use yt-dlp to stream it, > and it > appears to play just fine. > > However, if you use yt-dlp to download the stream to either mp4 or mkv, and > then play that back, the playback is glitched. > > With nvdec, it plays fine either way. > > Minimum Command line: > > mpv --no-config --hwdec=vdpau --gpu-context=x11 > > And switch vdpau for nvdec to compare the two. > > Hope that helps, > > --phil ___ 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] avformat/matroskaenc: Fix outdated comment
Signed-off-by: Andreas Rheinhardt --- libavformat/matroskaenc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index b240ca0a06..acb50017b6 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -2732,8 +2732,8 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt) } break; #endif -// FIXME: Remove the following once libaom starts propagating extradata during init() -//See https://bugs.chromium.org/p/aomedia/issues/detail?id=2012 +// FIXME: Remove the following once libaom starts propagating proper extradata during init() +//See https://bugs.chromium.org/p/aomedia/issues/detail?id=2208 case AV_CODEC_ID_AV1: if (side_data_size && mkv->track.bc && !par->extradata_size) { // If the reserved space doesn't suffice, only write -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 5/6] avformat/matroskaenc: Improve handling of AV1 extradata
Up until now, only the first four bytes (the ones preceding the OBU) were written because not enough space has been reserved for the complete CodecPrivate. This commit changes this by increasing the space reserved for the CodecPrivate (it is big enough for every sane sequence header plus something extra); the code falls back to writing four bytes in case the increased space turns out to be insufficient. Signed-off-by: Andreas Rheinhardt --- libavformat/matroskaenc.c | 37 + 1 file changed, 13 insertions(+), 24 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 250015419f..b240ca0a06 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -56,6 +56,7 @@ #include "libavutil/samplefmt.h" #include "libavutil/stereo3d.h" +#include "libavcodec/av1.h" #include "libavcodec/xiph.h" #include "libavcodec/mpeg4audio.h" @@ -1117,7 +1118,7 @@ static int mkv_assemble_native_codecprivate(AVFormatContext *s, AVIOContext *dyn return ff_isom_write_av1c(dyn_cp, extradata, extradata_size, 1); else -*size_to_reserve = 4; +*size_to_reserve = (AV1_SANE_SEQUENCE_HEADER_MAX_BITS + 7) / 8 + 100; break; #if CONFIG_MATROSKA_MUXER case AV_CODEC_ID_FLAC: @@ -1263,7 +1264,7 @@ static void mkv_put_codecprivate(AVIOContext *pb, unsigned max_payload_size, static int mkv_update_codecprivate(AVFormatContext *s, MatroskaMuxContext *mkv, uint8_t *side_data, int side_data_size, AVCodecParameters *par, AVIOContext *pb, - mkv_track *track) + mkv_track *track, unsigned alternative_size) { AVIOContext *const dyn_bc = mkv->tmp_bc; uint8_t *codecpriv; @@ -1275,9 +1276,12 @@ static int mkv_update_codecprivate(AVFormatContext *s, MatroskaMuxContext *mkv, &codecpriv, &codecpriv_size, &max_payload_size); if (ret < 0) goto fail; -if (codecpriv_size > track->codecpriv_size) { +if (codecpriv_size > track->codecpriv_size && !alternative_size) { ret = AVERROR(ENOSPC); goto fail; +} else if (codecpriv_size > track->codecpriv_size) { +av_assert1(alternative_size < track->codecpriv_size); +codecpriv_size = alternative_size; } avio_seek(pb, track->codecpriv_offset, SEEK_SET); mkv_put_codecprivate(pb, track->codecpriv_size, @@ -2702,7 +2706,7 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt) if (!output_sample_rate) output_sample_rate = track->sample_rate; // Space is already reserved, so it's this or a void element. ret = mkv_update_codecprivate(s, mkv, side_data, side_data_size, - par, mkv->track.bc, track); + par, mkv->track.bc, track, 0); if (ret < 0) return ret; avio_seek(mkv->track.bc, track->sample_rate_offset, SEEK_SET); @@ -2722,7 +2726,7 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt) return AVERROR(EINVAL); } ret = mkv_update_codecprivate(s, mkv, side_data, side_data_size, - par, mkv->track.bc, track); + par, mkv->track.bc, track, 0); if (ret < 0) return ret; } @@ -2732,27 +2736,12 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt) //See https://bugs.chromium.org/p/aomedia/issues/detail?id=2012 case AV_CODEC_ID_AV1: if (side_data_size && mkv->track.bc && !par->extradata_size) { -AVIOContext *dyn_cp; -uint8_t *codecpriv; -int codecpriv_size; -ret = avio_open_dyn_buf(&dyn_cp); -if (ret < 0) -return ret; -ff_isom_write_av1c(dyn_cp, side_data, side_data_size, 1); -codecpriv_size = avio_get_dyn_buf(dyn_cp, &codecpriv); -if ((ret = dyn_cp->error) < 0 || -!codecpriv_size && (ret = AVERROR_INVALIDDATA)) { -ffio_free_dyn_buf(&dyn_cp); -return ret; -} -avio_seek(mkv->track.bc, track->codecpriv_offset, SEEK_SET); -// Do not write the OBUs as we don't have space saved for them -put_ebml_binary(mkv->track.bc, MATROSKA_ID_CODECPRIVATE, codecpriv, 4); -ffio_free_dyn_buf(&dyn_cp); -ret = ff_alloc_extradata(par, side_data_size); +// If the reserved space doesn't suffice, only write +// the first four bytes of the av1C. +ret = mkv_update_codecprivate(s, mkv, side_data, side_data_size, +
[FFmpeg-devel] [PATCH 4/6] avcodec/av1: Add upper bound for the size of a sane sequence header
It will be used by the Matroska muxer to reserve a certain number of bytes for the CodecPrivate in case no extradata is initially available (as it is for the libaom-av1 encoder). Signed-off-by: Andreas Rheinhardt --- libavcodec/av1.h | 6 ++ 1 file changed, 6 insertions(+) diff --git a/libavcodec/av1.h b/libavcodec/av1.h index 951a18ecb2..384f7cddc7 100644 --- a/libavcodec/av1.h +++ b/libavcodec/av1.h @@ -175,4 +175,10 @@ enum { AV1_RESTORE_SWITCHABLE = 3, }; +// Sequence Headers are actually unbounded because one can use +// an arbitrary number of leading zeroes when encoding via uvlc. +// The following estimate is based around using the lowest number +// of bits for uvlc encoding. +#define AV1_SANE_SEQUENCE_HEADER_MAX_BITS 3138 + #endif /* AVCODEC_AV1_H */ -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH 3/6] avformat/matroskaenc: Split updating CodecPrivate from writing it
Up until now, updating extradata was very ad-hoc: The amount of space reserved for extradata was not recorded when writing the header; instead the AAC code simply presumed that it was enough. This commit changes this by recording how much space is available. This brings with it that the code for writing of and reserving space for the CodecPrivate and for updating it diverges. They are therefore split; this allows to put other common tasks like seeking to right offset as well as writing padding (in case the new extradata did not fill the whole reserved space) to this common function. The code for filling up the reserved space is smarter than the code it replaces; therefore it is no longer necessary to reserve more than necessary just to be sure that one can add an EBML Void element (whose minimum size is two) lateron. This is the reason for the change to the aac-autobsf-adtstoasc test. Signed-off-by: Andreas Rheinhardt --- libavformat/matroskaenc.c| 120 ++- tests/ref/fate/aac-autobsf-adtstoasc | 4 +- 2 files changed, 84 insertions(+), 40 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 93d10332a4..250015419f 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -184,7 +184,8 @@ typedef struct mkv_track { int64_t last_timestamp; int64_t duration; int64_t duration_offset; -int64_t codecpriv_offset; +int codecpriv_offset; +unsignedcodecpriv_size; ///< size reserved for CodecPrivate excluding header+length field int64_t ts_offset; /* This callback will be called twice: First with a NULL AVIOContext * to return the size of the (Simple)Block's data via size @@ -1116,7 +1117,7 @@ static int mkv_assemble_native_codecprivate(AVFormatContext *s, AVIOContext *dyn return ff_isom_write_av1c(dyn_cp, extradata, extradata_size, 1); else -*size_to_reserve = 4 + 3; +*size_to_reserve = 4; break; #if CONFIG_MATROSKA_MUXER case AV_CODEC_ID_FLAC: @@ -1143,7 +1144,7 @@ static int mkv_assemble_native_codecprivate(AVFormatContext *s, AVIOContext *dyn if (extradata_size) avio_write(dyn_cp, extradata, extradata_size); else -*size_to_reserve = 4 + MAX_PCE_SIZE + 2; +*size_to_reserve = MAX_PCE_SIZE; break; #endif default: @@ -1162,17 +1163,16 @@ static int mkv_assemble_codecprivate(AVFormatContext *s, AVIOContext *dyn_cp, const uint8_t *extradata, int extradata_size, int native_id, int qt_id, uint8_t **codecpriv, int *codecpriv_size, - unsigned *size_to_reserve) + unsigned *max_payload_size) { MatroskaMuxContext av_unused *const mkv = s->priv_data; +unsigned size_to_reserve = 0; int ret; -*size_to_reserve = 0; - if (native_id) { ret = mkv_assemble_native_codecprivate(s, dyn_cp, par, extradata, extradata_size, - size_to_reserve); + &size_to_reserve); if (ret < 0) return ret; #if CONFIG_MATROSKA_MUXER @@ -1226,31 +1226,72 @@ static int mkv_assemble_codecprivate(AVFormatContext *s, AVIOContext *dyn_cp, *codecpriv_size = avio_get_dyn_buf(dyn_cp, codecpriv); if (dyn_cp->error < 0) return dyn_cp->error; +*max_payload_size = *codecpriv_size + size_to_reserve; + return 0; } -static int mkv_write_codecprivate(AVFormatContext *s, MatroskaMuxContext *mkv, - AVCodecParameters *par, - const uint8_t *extradata, int extradata_size, - int native_id, int qt_id, AVIOContext *pb) +static void mkv_put_codecprivate(AVIOContext *pb, unsigned max_payload_size, + const uint8_t *codecpriv, unsigned codecpriv_size) +{ +unsigned total_codecpriv_size = 0, total_size; + +av_assert1(codecpriv_size < max_payload_size); + +if (!max_payload_size) +return; + +total_size = 2 + ebml_length_size(max_payload_size) + max_payload_size; + +if (codecpriv_size) { +unsigned length_size = ebml_length_size(codecpriv_size); + +total_codecpriv_size = 2U + length_size + codecpriv_size; +if (total_codecpriv_size + 1 == total_size) { +/* It is impossible to add one byte of padding via an EBML Void. */ +length_size++; +total_codecpriv_size++; +} +put_ebml_id(pb, MATROSKA_ID_CODECPRIVATE); +put_ebml_length(pb, codecpriv_size, length_size); +avio_write(pb,
[FFmpeg-devel] [PATCH 2/6] avformat/matroskaenc: Avoid swapping codecpar->extradata temporarily
Instead pass extradata and extradata_size explicitly. (It is not perfect, as ff_put_(wav|bmp)_header() still uses the extradata embedded in codecpar, but this is not an issue as long as their CodecPrivate isn't updated.) Signed-off-by: Andreas Rheinhardt --- libavformat/matroskaenc.c | 82 ++- 1 file changed, 47 insertions(+), 35 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index b4756832eb..93d10332a4 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -990,7 +990,8 @@ static int mkv_assemble_cues(AVStream **streams, AVIOContext *dyn_cp, } static int put_xiph_codecpriv(AVFormatContext *s, AVIOContext *pb, - const AVCodecParameters *par) + const AVCodecParameters *par, + const uint8_t *extradata, int extradata_size) { const uint8_t *header_start[3]; int header_len[3]; @@ -1002,7 +1003,7 @@ static int put_xiph_codecpriv(AVFormatContext *s, AVIOContext *pb, else first_header_size = 42; -err = avpriv_split_xiph_headers(par->extradata, par->extradata_size, +err = avpriv_split_xiph_headers(extradata, extradata_size, first_header_size, header_start, header_len); if (err < 0) { av_log(s, AV_LOG_ERROR, "Extradata corrupt.\n"); @@ -1020,22 +1021,23 @@ static int put_xiph_codecpriv(AVFormatContext *s, AVIOContext *pb, } #if CONFIG_MATROSKA_MUXER -static int put_wv_codecpriv(AVIOContext *pb, const AVCodecParameters *par) +static int put_wv_codecpriv(AVIOContext *pb, const uint8_t *extradata, int extradata_size) { -if (par->extradata && par->extradata_size == 2) -avio_write(pb, par->extradata, 2); +if (extradata && extradata_size == 2) +avio_write(pb, extradata, 2); else avio_wl16(pb, 0x410); // fallback to the most recent version return 0; } static int put_flac_codecpriv(AVFormatContext *s, AVIOContext *pb, - const AVCodecParameters *par) + const AVCodecParameters *par, + const uint8_t *extradata, int extradata_size) { int write_comment = (par->ch_layout.order == AV_CHANNEL_ORDER_NATIVE && !(par->ch_layout.u.mask & ~0x3ULL) && !ff_flac_is_native_layout(par->ch_layout.u.mask)); -int ret = ff_flac_write_header(pb, par->extradata, par->extradata_size, +int ret = ff_flac_write_header(pb, extradata, extradata_size, !write_comment); if (ret < 0) @@ -1101,43 +1103,45 @@ static int get_aac_sample_rates(AVFormatContext *s, MatroskaMuxContext *mkv, static int mkv_assemble_native_codecprivate(AVFormatContext *s, AVIOContext *dyn_cp, const AVCodecParameters *par, +const uint8_t *extradata, +int extradata_size, unsigned *size_to_reserve) { switch (par->codec_id) { case AV_CODEC_ID_VORBIS: case AV_CODEC_ID_THEORA: -return put_xiph_codecpriv(s, dyn_cp, par); +return put_xiph_codecpriv(s, dyn_cp, par, extradata, extradata_size); case AV_CODEC_ID_AV1: -if (par->extradata_size) -return ff_isom_write_av1c(dyn_cp, par->extradata, - par->extradata_size, 1); +if (extradata_size) +return ff_isom_write_av1c(dyn_cp, extradata, + extradata_size, 1); else *size_to_reserve = 4 + 3; break; #if CONFIG_MATROSKA_MUXER case AV_CODEC_ID_FLAC: -return put_flac_codecpriv(s, dyn_cp, par); +return put_flac_codecpriv(s, dyn_cp, par, extradata, extradata_size); case AV_CODEC_ID_WAVPACK: -return put_wv_codecpriv(dyn_cp, par); +return put_wv_codecpriv(dyn_cp, extradata, extradata_size); case AV_CODEC_ID_H264: -return ff_isom_write_avcc(dyn_cp, par->extradata, - par->extradata_size); +return ff_isom_write_avcc(dyn_cp, extradata, + extradata_size); case AV_CODEC_ID_HEVC: -return ff_isom_write_hvcc(dyn_cp, par->extradata, - par->extradata_size, 0); +return ff_isom_write_hvcc(dyn_cp, extradata, + extradata_size, 0); case AV_CODEC_ID_ALAC: -if (par->extradata_size < 36) { +if (extradata_size < 36) { av_log(s, AV_LOG_ERROR, "Invalid extradata found, ALAC expects a 36-byte " "QuickTime atom."); return AVERROR_INVALIDDATA; } else -avio_write(dyn_cp, par->extradata + 1
[FFmpeg-devel] [PATCH 1/6] avformat/matroskaenc: Split assembling CodecPrivate from writing it
This is in preparation for splitting writing and updating extradata more thoroughly later. Signed-off-by: Andreas Rheinhardt --- libavformat/matroskaenc.c | 74 --- 1 file changed, 46 insertions(+), 28 deletions(-) diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 163af8aec8..b4756832eb 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -1099,9 +1099,9 @@ static int get_aac_sample_rates(AVFormatContext *s, MatroskaMuxContext *mkv, } #endif -static int mkv_write_native_codecprivate(AVFormatContext *s, AVIOContext *pb, - const AVCodecParameters *par, - AVIOContext *dyn_cp) +static int mkv_assemble_native_codecprivate(AVFormatContext *s, AVIOContext *dyn_cp, +const AVCodecParameters *par, +unsigned *size_to_reserve) { switch (par->codec_id) { case AV_CODEC_ID_VORBIS: @@ -1112,7 +1112,7 @@ static int mkv_write_native_codecprivate(AVFormatContext *s, AVIOContext *pb, return ff_isom_write_av1c(dyn_cp, par->extradata, par->extradata_size, 1); else -put_ebml_void(pb, 4 + 3); +*size_to_reserve = 4 + 3; break; #if CONFIG_MATROSKA_MUXER case AV_CODEC_ID_FLAC: @@ -1139,7 +1139,7 @@ static int mkv_write_native_codecprivate(AVFormatContext *s, AVIOContext *pb, if (par->extradata_size) avio_write(dyn_cp, par->extradata, par->extradata_size); else -put_ebml_void(pb, MAX_PCE_SIZE + 2 + 4); +*size_to_reserve = 4 + MAX_PCE_SIZE + 2; break; #endif default: @@ -1153,21 +1153,21 @@ static int mkv_write_native_codecprivate(AVFormatContext *s, AVIOContext *pb, return 0; } -static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb, - AVCodecParameters *par, - int native_id, int qt_id) +static int mkv_assemble_codecprivate(AVFormatContext *s, AVIOContext *dyn_cp, + AVCodecParameters *par, + int native_id, int qt_id, + uint8_t **codecpriv, int *codecpriv_size, + unsigned *size_to_reserve) { MatroskaMuxContext av_unused *const mkv = s->priv_data; -AVIOContext *dyn_cp; -uint8_t *codecpriv; -int ret, codecpriv_size; +int ret; -ret = avio_open_dyn_buf(&dyn_cp); -if (ret < 0) -return ret; +*size_to_reserve = 0; if (native_id) { -ret = mkv_write_native_codecprivate(s, pb, par, dyn_cp); +ret = mkv_assemble_native_codecprivate(s, dyn_cp, par, size_to_reserve); +if (ret < 0) +return ret; #if CONFIG_MATROSKA_MUXER } else if (par->codec_type == AVMEDIA_TYPE_VIDEO) { if (qt_id) { @@ -1193,7 +1193,7 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb, if (!par->codec_tag && par->codec_id != AV_CODEC_ID_RAWVIDEO) { av_log(s, AV_LOG_ERROR, "No bmp codec tag found for codec %s\n", avcodec_get_name(par->codec_id)); -ret = AVERROR(EINVAL); +return AVERROR(EINVAL); } ff_put_bmp_header(dyn_cp, par, 0, 0, mkv->flipped_raw_rgb); @@ -1204,7 +1204,7 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb, if (!tag) { av_log(s, AV_LOG_ERROR, "No wav codec tag found for codec %s\n", avcodec_get_name(par->codec_id)); -ret = AVERROR(EINVAL); +return AVERROR(EINVAL); } if (!par->codec_tag) par->codec_tag = tag; @@ -1213,14 +1213,32 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb, #endif } -if (ret >= 0) { -codecpriv_size = avio_get_dyn_buf(dyn_cp, &codecpriv); -if ((ret = dyn_cp->error) >= 0 && codecpriv_size) -put_ebml_binary(pb, MATROSKA_ID_CODECPRIVATE, codecpriv, -codecpriv_size); -} -ffio_free_dyn_buf(&dyn_cp); -return ret; +*codecpriv_size = avio_get_dyn_buf(dyn_cp, codecpriv); +if (dyn_cp->error < 0) +return dyn_cp->error; +return 0; +} + +static int mkv_write_codecprivate(AVFormatContext *s, MatroskaMuxContext *mkv, + AVCodecParameters *par, + int native_id, int qt_id, AVIOContext *pb) +{ +AVIOContext *const dyn_bc = mkv->tmp_bc; +uint8_t *codecpriv; +unsigned size_to_reserve; +int ret, codecpriv_size; + +ret = mkv_assemble_codecprivate(s, dyn_bc, par, native_id, qt_id, +&codecpriv, &codecpriv_size,
Re: [FFmpeg-devel] [PATCH 2/2] lavf/id3v2dec: support multiple values and TIPL frames
On Sun, Jun 19, 2022 at 08:37:11PM -0500, rcombs wrote: > Fixes https://trac.ffmpeg.org/ticket/6949 > > Ordinary text frames in ID3v2 are allowed to have multiple > (null-separated) values. This technically isn't allowed in TXXX, > but it's used in practice by Picard, and supporting it is harmless. > > TIPL/IPL (Involved People List) and TMCL (Musician Credits List) work > similarly to TXXX, but alternate key-value-key-value. > --- > libavformat/id3v2.c | 49 ++--- > 1 file changed, 28 insertions(+), 21 deletions(-) It appears this looses a track # metadata on one file i will send you the file privatly [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB I am the wisest man alive, for I know one thing, and that is that I know nothing. -- Socrates signature.asc Description: PGP signature ___ 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 1/2] avformat/demux: Make read_frame_internal() return AVERREOR(EAGAIN) on stuck empty input parser
On Mon, Jun 20, 2022 at 01:44:52AM +0200, Andreas Rheinhardt wrote: [...] > PS: The fact that the parsing API is based upon buffers and not > AVPackets btw leads to buggy side-data handling: If a parser introduces > delay, then the side-data will not be attached to the correct packet, > but to the preceding one. The parsers pass timestamps around correctly, sidedata can maybe be handled similarly thx [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB The real ebay dictionary, page 2 "100% positive feedback" - "All either got their money back or didnt complain" "Best seller ever, very honest" - "Seller refunded buyer after failed scam" signature.asc Description: PGP signature ___ 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 2/2] lavf/id3v2dec: support multiple values and TIPL frames
> -Original Message- > From: ffmpeg-devel On Behalf Of > Ridley Combs > Sent: Tuesday, June 21, 2022 12:33 AM > To: ffmpeg-devel > Subject: Re: [FFmpeg-devel] [PATCH 2/2] lavf/id3v2dec: support > multiple values and TIPL frames > > > > On Jun 20, 2022, at 17:15, Andreas Rheinhardt > wrote: > > > > rcombs: > >> Fixes https://trac.ffmpeg.org/ticket/6949 > >> > >> Ordinary text frames in ID3v2 are allowed to have multiple > >> (null-separated) values. This technically isn't allowed in TXXX, > >> but it's used in practice by Picard, and supporting it is > harmless. > >> > >> TIPL/IPL (Involved People List) and TMCL (Musician Credits List) > work > >> similarly to TXXX, but alternate key-value-key-value. > >> --- > >> libavformat/id3v2.c | 49 ++--- > > >> 1 file changed, 28 insertions(+), 21 deletions(-) > >> > >> diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c > >> index 191a305ffb..667105e9f9 100644 > >> --- a/libavformat/id3v2.c > >> +++ b/libavformat/id3v2.c > >> @@ -321,8 +321,12 @@ static void read_ttag(AVFormatContext *s, > AVIOContext *pb, int taglen, > >> AVDictionary **metadata, const char *key) > >> { > >> uint8_t *dst; > >> - int encoding, dict_flags = AV_DICT_DONT_OVERWRITE | > AV_DICT_DONT_STRDUP_VAL; > >> + uint8_t *dst_key = NULL; > >> + int encoding, dict_flags = AV_DICT_MULTIKEY | > AV_DICT_DONT_STRDUP_VAL; > >> unsigned genre; > >> + int count = 0; > >> + int is_tipl = !(strcmp(key, "TIPL") && strcmp(key, "TMCL") && > >> + strcmp(key, "IPL")); > >> > >> if (taglen < 1) > >> return; > >> @@ -330,30 +334,33 @@ static void read_ttag(AVFormatContext *s, > AVIOContext *pb, int taglen, > >> encoding = avio_r8(pb); > >> taglen--; /* account for encoding type byte */ > >> > >> - if (decode_str(s, pb, encoding, &dst, &taglen) < 0) { > >> - av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", > key); > >> - return; > >> - } > >> - > >> - if (!(strcmp(key, "TCON") && strcmp(key, "TCO")) && > >> - (sscanf(dst, "(%d)", &genre) == 1 || sscanf(dst, "%d", &genre) > == 1) && > >> - genre <= ID3v1_GENRE_MAX) { > >> - av_freep(&dst); > >> - dst = av_strdup(ff_id3v1_genre_str[genre]); > >> - } else if (!(strcmp(key, "TXXX") && strcmp(key, "TXX"))) { > >> - /* dst now contains the key, need to get value */ > >> - key = dst; > >> + while (taglen > 1) { > >> if (decode_str(s, pb, encoding, &dst, &taglen) < 0) { > >> av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", key); > >> - av_freep(&key); > >> return; > >> } > >> - dict_flags |= AV_DICT_DONT_STRDUP_KEY; > >> - } else if (!*dst) > >> - av_freep(&dst); > >> > >> - if (dst) > >> - av_dict_set(metadata, key, dst, dict_flags); > >> + count++; > >> + > >> + if (!(strcmp(key, "TCON") && strcmp(key, "TCO")) && > >> + (sscanf(dst, "(%d)", &genre) == 1 || sscanf(dst, "%d", &genre) > == 1) && > >> + genre <= ID3v1_GENRE_MAX) { > >> + av_freep(&dst); > >> + dst = av_strdup(ff_id3v1_genre_str[genre]); > >> + } else if (!(strcmp(key, "TXXX") && strcmp(key, "TXX")) || > >> + (is_tipl && (count & 1))) { > >> + /* dst now contains the key, need to get value */ > >> + av_free(dst_key); > >> + key = dst_key = dst; > >> + continue; > >> + } else if (!*dst) > >> + av_freep(&dst); > >> + > >> + if (dst) > >> + av_dict_set(metadata, key, dst, dict_flags); > >> + } > >> + > >> + av_free(dst_key); > >> } > >> > >> static void read_uslt(AVFormatContext *s, AVIOContext *pb, int > taglen, > >> @@ -1039,7 +1046,7 @@ static void id3v2_parse(AVIOContext *pb, > AVDictionary **metadata, > >> pbx = &pb_local.pub; // read from sync buffer > >> } > >> #endif > >> - if (tag[0] == 'T') > >> + if (tag[0] == 'T' || !strcmp(tag, "IPL")) > >> /* parse text tag */ > >> read_ttag(s, pbx, tlen, metadata, tag); > >> else if (!memcmp(tag, "USLT", 4)) > > > > From avformat.h: > > > > "Keys are unique; there can never be 2 tags with the same key. This > is > > also meant semantically, i.e., a demuxer should not knowingly > produce > > several keys that are literally different but semantically > identical. > > E.g., key=Author5, key=Author6. In this example, all authors must > be > > placed in the same tag." > > > > If this requirement did not exist, I would have fixed #6949 and > #9641 > > long ago. > > > > - Andreas > > Well, we have 3 options, then: > - Export these kinds of duplicate tags concatenated in a single dict > entry (split by slashes or something?) > - Add an AVOption in lavf/options_table.h to opt into multi-key > support > - Remove the requirement altogether in a major API version bump That's the way I would prefer. Doing nothing for formal reasons is not a useful way. Most softwares can read multivalue ID3v2 tags, ffmpeg/probe is more a kind of exception. I think I should also mention that half part of this patch has been submitted before https://patchwork.ffmpeg.org/project/ffmpeg/patch/1118083116.39618.1617751350...@office.mailbox.org/ Best regards, softworkz __
Re: [FFmpeg-devel] [PATCH 2/2] lavf/id3v2dec: support multiple values and TIPL frames
rcombs: > Fixes https://trac.ffmpeg.org/ticket/6949 > > Ordinary text frames in ID3v2 are allowed to have multiple > (null-separated) values. This technically isn't allowed in TXXX, > but it's used in practice by Picard, and supporting it is harmless. > > TIPL/IPL (Involved People List) and TMCL (Musician Credits List) work > similarly to TXXX, but alternate key-value-key-value. > --- > libavformat/id3v2.c | 49 ++--- > 1 file changed, 28 insertions(+), 21 deletions(-) > > diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c > index 191a305ffb..667105e9f9 100644 > --- a/libavformat/id3v2.c > +++ b/libavformat/id3v2.c > @@ -321,8 +321,12 @@ static void read_ttag(AVFormatContext *s, AVIOContext > *pb, int taglen, >AVDictionary **metadata, const char *key) > { > uint8_t *dst; > -int encoding, dict_flags = AV_DICT_DONT_OVERWRITE | > AV_DICT_DONT_STRDUP_VAL; > +uint8_t *dst_key = NULL; > +int encoding, dict_flags = AV_DICT_MULTIKEY | AV_DICT_DONT_STRDUP_VAL; > unsigned genre; > +int count = 0; > +int is_tipl = !(strcmp(key, "TIPL") && strcmp(key, "TMCL") && > +strcmp(key, "IPL")); > > if (taglen < 1) > return; > @@ -330,30 +334,33 @@ static void read_ttag(AVFormatContext *s, AVIOContext > *pb, int taglen, > encoding = avio_r8(pb); > taglen--; /* account for encoding type byte */ > > -if (decode_str(s, pb, encoding, &dst, &taglen) < 0) { > -av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", key); > -return; > -} > - > -if (!(strcmp(key, "TCON") && strcmp(key, "TCO")) > && > -(sscanf(dst, "(%d)", &genre) == 1 || sscanf(dst, "%d", &genre) == 1) > && > -genre <= ID3v1_GENRE_MAX) { > -av_freep(&dst); > -dst = av_strdup(ff_id3v1_genre_str[genre]); > -} else if (!(strcmp(key, "TXXX") && strcmp(key, "TXX"))) { > -/* dst now contains the key, need to get value */ > -key = dst; > +while (taglen > 1) { > if (decode_str(s, pb, encoding, &dst, &taglen) < 0) { > av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", > key); > -av_freep(&key); > return; > } > -dict_flags |= AV_DICT_DONT_STRDUP_KEY; > -} else if (!*dst) > -av_freep(&dst); > > -if (dst) > -av_dict_set(metadata, key, dst, dict_flags); > +count++; > + > +if (!(strcmp(key, "TCON") && strcmp(key, "TCO")) > && > +(sscanf(dst, "(%d)", &genre) == 1 || sscanf(dst, "%d", &genre) > == 1) && > +genre <= ID3v1_GENRE_MAX) { > +av_freep(&dst); > +dst = av_strdup(ff_id3v1_genre_str[genre]); > +} else if (!(strcmp(key, "TXXX") && strcmp(key, "TXX")) || > + (is_tipl && (count & 1))) { > +/* dst now contains the key, need to get value */ > +av_free(dst_key); > +key = dst_key = dst; > +continue; > +} else if (!*dst) > +av_freep(&dst); > + > +if (dst) > +av_dict_set(metadata, key, dst, dict_flags); > +} > + > +av_free(dst_key); > } > > static void read_uslt(AVFormatContext *s, AVIOContext *pb, int taglen, > @@ -1039,7 +1046,7 @@ static void id3v2_parse(AVIOContext *pb, AVDictionary > **metadata, > pbx = &pb_local.pub; // read from sync buffer > } > #endif > -if (tag[0] == 'T') > +if (tag[0] == 'T' || !strcmp(tag, "IPL")) > /* parse text tag */ > read_ttag(s, pbx, tlen, metadata, tag); > else if (!memcmp(tag, "USLT", 4)) >From avformat.h: "Keys are unique; there can never be 2 tags with the same key. This is also meant semantically, i.e., a demuxer should not knowingly produce several keys that are literally different but semantically identical. E.g., key=Author5, key=Author6. In this example, all authors must be placed in the same tag." If this requirement did not exist, I would have fixed #6949 and #9641 long ago. - Andreas ___ 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] fftools/ffprobe: report avio errors
On Mon, 13 Jun 2022, Marton Balint wrote: Signed-off-by: Marton Balint --- fftools/ffprobe.c | 12 1 file changed, 8 insertions(+), 4 deletions(-) Will apply. Regards, Marton diff --git a/fftools/ffprobe.c b/fftools/ffprobe.c index 4e2fdbaec8..5020ba484c 100644 --- a/fftools/ffprobe.c +++ b/fftools/ffprobe.c @@ -545,12 +545,13 @@ static const AVClass writer_class = { .child_next = writer_child_next, }; -static void writer_close(WriterContext **wctx) +static int writer_close(WriterContext **wctx) { int i; +int ret = 0; if (!*wctx) -return; +return -1; if ((*wctx)->writer->uninit) (*wctx)->writer->uninit(*wctx); @@ -562,9 +563,10 @@ static void writer_close(WriterContext **wctx) av_opt_free(*wctx); if ((*wctx)->avio) { avio_flush((*wctx)->avio); -avio_close((*wctx)->avio); +ret = avio_close((*wctx)->avio); } av_freep(wctx); +return ret; } static void bprint_bytes(AVBPrint *bp, const uint8_t *ubuf, size_t ubuf_size) @@ -4145,7 +4147,9 @@ int main(int argc, char **argv) } writer_print_section_footer(wctx); -writer_close(&wctx); +ret = writer_close(&wctx); +if (ret < 0) +av_log(NULL, AV_LOG_ERROR, "Writing output failed: %s\n", av_err2str(ret)); } end: -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-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] avformat/mpegts: remove obsolate hacks for detecting streams with bad PMTs
On Wed, 15 Jun 2022, Marton Balint wrote: Ffmpeg/ffprobe/ffplay sets scan_all_pmts to 1 when finding the streams, that should be enough to handle files for which some early PMTs miss some streams. Fixes ticket #9782. Will apply. Regards, Marton Signed-off-by: Marton Balint --- libavformat/mpegts.c | 12 ++-- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 6e761c07f1..8a3436f2be 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -2870,16 +2870,8 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet, int64_t pos) break; } if (i == ts->nb_prg && ts->nb_prg > 0) { -int types = 0; -for (i = 0; i < ts->stream->nb_streams; i++) { -AVStream *st = ts->stream->streams[i]; -if (st->codecpar->codec_type >= 0) -types |= 1codec_type; -} -if ((types & (1< 10) { -av_log(ts->stream, AV_LOG_DEBUG, "All programs have pmt, headers found\n"); -ts->stream->ctx_flags &= ~AVFMTCTX_NOHEADER; -} +av_log(ts->stream, AV_LOG_DEBUG, "All programs have pmt, headers found\n"); +ts->stream->ctx_flags &= ~AVFMTCTX_NOHEADER; } } -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-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 2/2] avformat/img2enc: use unmatched filename for an invalid or missing sequence pattern
On Mon, 13 Jun 2022, Marton Balint wrote: Also warn the user that for single images -update should be used, for sequences a proper pattern should be specified. Fixes ticket #9748. Ping for this. Note that this patch will show a warning for any non-sequence image filename (unless the -update option is specified) in order to help the user avoid unexpected results with filenames containing %d. Regards, Marton Signed-off-by: Marton Balint --- libavformat/img2enc.c | 18 +++--- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/libavformat/img2enc.c b/libavformat/img2enc.c index 82a04e639b..50e469dd96 100644 --- a/libavformat/img2enc.c +++ b/libavformat/img2enc.c @@ -163,13 +163,17 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) } } else if (av_get_frame_filename2(filename, sizeof(filename), s->url, img->img_number, - AV_FRAME_FILENAME_FLAGS_MULTIPLE) < 0 && - img->img_number > img->start_img_number) { -av_log(s, AV_LOG_ERROR, - "Could not get frame filename number %d from pattern '%s'. " - "Use '-frames:v 1' for a single image, or '-update' option, or use a pattern such as %%03d within the filename.\n", - img->img_number, s->url); -return AVERROR(EINVAL); + AV_FRAME_FILENAME_FLAGS_MULTIPLE) < 0) { +if (img->img_number == img->start_img_number) { +av_log(s, AV_LOG_WARNING, "The specified filename '%s' does not contain an image sequence pattern or a pattern is invalid.\n", s->url); +av_log(s, AV_LOG_WARNING, + "Use a pattern such as %%03d for an image sequence or " + "use the -update option (with -frames:v 1 if needed) to write a single image.\n"); +av_strlcpy(filename, s->url, sizeof(filename)); +} else { +av_log(s, AV_LOG_ERROR, "Cannot write more than one file with the same name. Are you missing the -update option or a sequence pattern?\n"); +return AVERROR(EINVAL); +} } for (i = 0; i < 4; i++) { av_dict_copy(&options, img->protocol_opts, 0); -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-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 1/7] avcodec/v210dec: properly support odd widths
On Sun, 12 Jun 2022, Marton Balint wrote: Fixes ticket #5195. Signed-off-by: Marton Balint --- libavcodec/v210dec.c | 49 +--- 1 file changed, 33 insertions(+), 16 deletions(-) Will apply the series. Regards, Marton diff --git a/libavcodec/v210dec.c b/libavcodec/v210dec.c index 6c10ef6a7c..48ebe57100 100644 --- a/libavcodec/v210dec.c +++ b/libavcodec/v210dec.c @@ -60,14 +60,16 @@ static int v210_decode_slice(AVCodecContext *avctx, void *arg, int jobnr, int th int slice_start = (avctx->height * jobnr) / s->thread_count; int slice_end = (avctx->height * (jobnr+1)) / s->thread_count; uint8_t *psrc = td->buf + stride * slice_start; -uint16_t *y, *u, *v; +int16_t *py = (uint16_t*)frame->data[0] + slice_start * frame->linesize[0] / 2; +int16_t *pu = (uint16_t*)frame->data[1] + slice_start * frame->linesize[1] / 2; +int16_t *pv = (uint16_t*)frame->data[2] + slice_start * frame->linesize[2] / 2; -y = (uint16_t*)frame->data[0] + slice_start * frame->linesize[0] / 2; -u = (uint16_t*)frame->data[1] + slice_start * frame->linesize[1] / 2; -v = (uint16_t*)frame->data[2] + slice_start * frame->linesize[2] / 2; for (h = slice_start; h < slice_end; h++) { const uint32_t *src = (const uint32_t*)psrc; uint32_t val; +uint16_t *y = py; +uint16_t *u = pu; +uint16_t *v = pv; w = (avctx->width / 12) * 12; s->unpack_frame(src, y, u, v, w); @@ -85,25 +87,40 @@ static int v210_decode_slice(AVCodecContext *avctx, void *arg, int jobnr, int th w += 6; } -if (w < avctx->width - 1) { +if (w++ < avctx->width) { READ_PIXELS(u, y, v); -val = av_le2ne32(*src++); -*y++ = val & 0x3FF; -if (w < avctx->width - 3) { -*u++ = (val >> 10) & 0x3FF; -*y++ = (val >> 20) & 0x3FF; - +if (w++ < avctx->width) { val = av_le2ne32(*src++); -*v++ = val & 0x3FF; -*y++ = (val >> 10) & 0x3FF; +*y++ = val & 0x3FF; + +if (w++ < avctx->width) { +*u++ = (val >> 10) & 0x3FF; +*y++ = (val >> 20) & 0x3FF; +val = av_le2ne32(*src++); +*v++ = val & 0x3FF; + +if (w++ < avctx->width) { +*y++ = (val >> 10) & 0x3FF; + +if (w++ < avctx->width) { +*u++ = (val >> 20) & 0x3FF; +val = av_le2ne32(*src++); +*y++ = val & 0x3FF; +*v++ = (val >> 10) & 0x3FF; + +if (w++ < avctx->width) +*y++ = (val >> 20) & 0x3FF; +} +} +} } } psrc += stride; -y += frame->linesize[0] / 2 - avctx->width + (avctx->width & 1); -u += frame->linesize[1] / 2 - avctx->width / 2; -v += frame->linesize[2] / 2 - avctx->width / 2; +py += frame->linesize[0] / 2; +pu += frame->linesize[1] / 2; +pv += frame->linesize[2] / 2; } return 0; -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-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/aarch64: unify formatting
On Tue, 14 Jun 2022, J. Dekker wrote: Performs the following changes: - Lower case format specifiers - Lower case sxtw/uxtw - Numeric labels on same line as next instruction Why do you feel the need to do that? I like the occasional extra spacing that an empty line for such labels adds - at least I wouldn't go changing how that's done in other places. Where there are empty lines and where there aren't, is up to the author IMO, based on how they see their code. - Indentation to 9/25 Signed-off-by: J. Dekker --- I initially started writing a full lexer to do this but ended up wasting too much time on it. Now using Mostly text editor macros. Still need to skim through again and make a few manual changes here and there but wondering if there's any other major automatable changes I missed. libavcodec/aarch64/aacpsdsp_neon.S | 208 +++ libavcodec/aarch64/fft_neon.S| 89 ++- libavcodec/aarch64/fmtconvert_neon.S | 12 +- libavcodec/aarch64/h264cmc_neon.S| 534 +- libavcodec/aarch64/h264dsp_neon.S| 664 +++ libavcodec/aarch64/h264idct_neon.S | 418 +++--- libavcodec/aarch64/h264pred_neon.S | 16 +- libavcodec/aarch64/h264qpel_neon.S | 644 +++--- libavcodec/aarch64/hevcdsp_idct_neon.S | 323 ++- libavcodec/aarch64/hevcdsp_sao_neon.S| 8 +- libavcodec/aarch64/hpeldsp_neon.S| 504 - libavcodec/aarch64/mdct_neon.S | 27 +- libavcodec/aarch64/mpegaudiodsp_neon.S | 26 +- libavcodec/aarch64/neon.S| 246 - libavcodec/aarch64/opusdsp_neon.S| 106 ++-- libavcodec/aarch64/pixblockdsp_neon.S| 6 +- libavcodec/aarch64/sbrdsp_neon.S | 308 +-- libavcodec/aarch64/simple_idct_neon.S| 410 +++--- libavcodec/aarch64/synth_filter_neon.S | 15 +- libavcodec/aarch64/vc1dsp_neon.S | 206 +++ libavcodec/aarch64/videodsp.S| 3 +- libavcodec/aarch64/vp8dsp_neon.S | 485 - libavcodec/aarch64/vp9itxfm_16bpp_neon.S | 64 +-- libavcodec/aarch64/vp9itxfm_neon.S | 50 +- libavcodec/aarch64/vp9lpf_16bpp_neon.S | 24 +- libavcodec/aarch64/vp9lpf_neon.S | 78 +-- libavcodec/aarch64/vp9mc_16bpp_neon.S| 30 +- libavcodec/aarch64/vp9mc_aarch64.S | 9 +- libavcodec/aarch64/vp9mc_neon.S | 39 +- 29 files changed, 2688 insertions(+), 2864 deletions(-) diff --git a/libavcodec/aarch64/aacpsdsp_neon.S b/libavcodec/aarch64/aacpsdsp_neon.S index ff4e6e244a..dfa6a9dc33 100644 --- a/libavcodec/aarch64/aacpsdsp_neon.S +++ b/libavcodec/aarch64/aacpsdsp_neon.S @@ -19,130 +19,130 @@ #include "libavutil/aarch64/asm.S" function ff_ps_add_squares_neon, export=1 -1: ld1 {v0.4S,v1.4S}, [x1], #32 -fmulv0.4S, v0.4S, v0.4S -fmulv1.4S, v1.4S, v1.4S -faddp v2.4S, v0.4S, v1.4S -ld1 {v3.4S}, [x0] -faddv3.4S, v3.4S, v2.4S -st1 {v3.4S}, [x0], #16 -subsw2, w2, #4 +1: ld1 {v0.4s,v1.4s}, [x1], #32 +fmulv0.4s, v0.4s, v0.4s +fmulv1.4s, v1.4s, v1.4s +faddp v2.4s, v0.4s, v1.4s +ld1 {v3.4s}, [x0] +faddv3.4s, v3.4s, v2.4s +st1 {v3.4s}, [x0], #16 +subsw2, w2, #4 b.gt1b This leaves the b.gt parameter misaligned with the rest - same thing in the whole rest of this file. @@ -295,8 +295,7 @@ function fft_pass_neon st1 {v21.4s}, [x1], #16 // {z[o1],z[o1+1]} st1 {v22.4s}, [x2], #16 // {z[o2],z[o2+1]} st1 {v23.4s}, [x3], #16 // {z[o3],z[o3+1]} -1: -ld1 {v20.4s},[x2]// {z[o2],z[o2+1]} +1: ld1 {v20.4s},[x2]// {z[o2],z[o2+1]} ld1 {v22.4s},[x3]// {z[o3],z[o3+1]} I really don't think getting rid of the empty line here or anywhere else adds anything - I think it worsens readability. @@ -359,18 +358,18 @@ function fft\n\()_neon, align=6 endfunc .endm -def_fft32,16, 8 -def_fft64,32,16 -def_fft 128,64,32 -def_fft 256, 128,64 -def_fft 512, 256, 128 -def_fft 1024, 512, 256 -def_fft 2048, 1024, 512 -def_fft 4096, 2048, 1024 -def_fft 8192, 4096, 2048 -def_fft 16384, 8192, 4096 -def_fft 32768, 16384, 8192 -def_fft 65536, 32768, 16384 +def_fft 32,16, 8 +def_fft 64,32,16 +def_fft 128,64,32 +def_fft 256, 128,64 +def_fft 512, 256, 128 +def_fft 1024, 512, 256 +def_fft 2048, 1024, 512 +def_fft 4096, 2048, 1024 +def_ff
[FFmpeg-devel] [PATCH] avformat/flacdec: Implement decoding of 32-bit PCM
Recently libFLAC gained the ability (not in any released version yet though) to create FLAC files containing 32-bit int PCM samples. To keep complexity reasonable, the choice was made to limit residuals to 32-bit integers, which the encoder must make sure of. In case the encoder cannot find any predictor of which the residuals fit this limit, it must default to using a verbatim subframe. Tests have shown that this does not happen often (<0.1% of subframes on a music corpus of various styles). See also discussion here: https://github.com/ietf-wg-cellar/flac-specification/pull/148 This patch adds decoding of these files to ffmpeg. --- libavcodec/flac.c | 4 +- libavcodec/flacdec.c | 248 ++ libavcodec/get_bits.h | 12 ++ libavcodec/mathops.h | 9 ++ 4 files changed, 250 insertions(+), 23 deletions(-) diff --git a/libavcodec/flac.c b/libavcodec/flac.c index dd68830622..f326d8fa5c 100644 --- a/libavcodec/flac.c +++ b/libavcodec/flac.c @@ -27,7 +27,7 @@ #include "flac.h" #include "flacdata.h" -static const int8_t sample_size_table[] = { 0, 8, 12, 0, 16, 20, 24, 0 }; +static const int8_t sample_size_table[] = { 0, 8, 12, 0, 16, 20, 24, 32 }; static const AVChannelLayout flac_channel_layouts[8] = { AV_CHANNEL_LAYOUT_MONO, @@ -81,7 +81,7 @@ int ff_flac_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb, /* bits per sample */ bps_code = get_bits(gb, 3); -if (bps_code == 3 || bps_code == 7) { +if (bps_code == 3) { av_log(avctx, AV_LOG_ERROR + log_level_offset, "invalid sample size code (%d)\n", bps_code); diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c index 87f20c7425..49952ce120 100644 --- a/libavcodec/flacdec.c +++ b/libavcodec/flacdec.c @@ -63,6 +63,9 @@ typedef struct FLACContext { int32_t *decoded[FLAC_MAX_CHANNELS];///< decoded samples uint8_t *decoded_buffer; unsigned int decoded_buffer_size; +int64_t *decoded_33bps; ///< decoded samples for a 33 bps subframe +uint8_t *decoded_buffer_33bps; +unsigned int decoded_buffer_size_33bps; int buggy_lpc; ///< use workaround for old lavc encoded files FLACDSPContext dsp; @@ -154,6 +157,24 @@ static int allocate_buffers(FLACContext *s) s->flac_stream_info.channels, s->flac_stream_info.max_blocksize, AV_SAMPLE_FMT_S32P, 0); +if (ret >= 0 && s->flac_stream_info.bps == 32 && s->flac_stream_info.channels == 2) { +buf_size = av_samples_get_buffer_size(NULL, 1, + s->flac_stream_info.max_blocksize, + AV_SAMPLE_FMT_S64P, 0); +if (buf_size < 0) +return buf_size; + +av_fast_malloc(&s->decoded_buffer_33bps, &s->decoded_buffer_size_33bps, buf_size); +if (!s->decoded_buffer) +return AVERROR(ENOMEM); + +ret = av_samples_fill_arrays((uint8_t **)&s->decoded_33bps, NULL, + s->decoded_buffer_33bps, + 1, + s->flac_stream_info.max_blocksize, + AV_SAMPLE_FMT_S64P, 0); + +} return ret < 0 ? ret : 0; } @@ -331,6 +352,94 @@ static int decode_subframe_fixed(FLACContext *s, int32_t *decoded, return 0; } +static int decode_subframe_fixed_wide(FLACContext *s, int32_t *decoded, + int pred_order, int bps) +{ +const int blocksize = s->blocksize; +int i; +int ret; + +/* warm up samples */ +for (i = 0; i < pred_order; i++) { +decoded[i] = get_sbits_long(&s->gb, bps); +} + +if ((ret = decode_residuals(s, decoded, pred_order)) < 0) +return ret; + +switch (pred_order) { +case 0: +break; +case 1: +for (i = pred_order; i < blocksize; i++) +decoded[i] += decoded[i-1]; +break; +case 2: +for (i = pred_order; i < blocksize; i++) +decoded[i] = (int64_t)decoded[i] + 2*(int64_t)decoded[i-1] - (int64_t)decoded[i-2]; +break; +case 3: +for (i = pred_order; i < blocksize; i++) +decoded[i] = (int64_t)decoded[i] + 3*(int64_t)decoded[i-1] - 3*(int64_t)decoded[i-2] + (int64_t)decoded[i-3]; +break; +case 4: +for (i = pred_order; i < blocksize; i++) +decoded[i] = (int64_t)decoded[i] + 4*(int64_t)decoded[i-1] - 6*(int64_t)decoded[i-2] + 4*(int64_t)decoded[i-3] - (int64_t)decoded[i-4]; +break; +default: +av_log(s->avctx, AV_LOG_ERROR, "illegal pred order %d\n", pred_order); +return AVERROR_INVALIDDATA; +} + +return 0; +} + + +static int decode_subframe_fixed_33bps(FLACContext *s, int64_t *decoded, +
[FFmpeg-devel] [PATCH v2] doc/examples/muxing: code rewrite with improved readability and fixed issues
Please review it! Difference to v1: *) AVCodecParameter(s) allocated with avcodec_parameters_alloc() *) AVRational objects created with av_make_q() (in the original muxing.c they are created through a cast to AVRational) *) removed unuseful "else"s *) fixed error check in case of avcodec_alloc_context3() failsFrom 2e9cc74d3a8b637d8adff5d78632cf1321d7e2cf Mon Sep 17 00:00:00 2001 From: paolo Date: Mon, 20 Jun 2022 20:56:47 +0200 Subject: [PATCH v2] doc/examples/muxing: code rewrite with improved readability and fixed issues Improved readability with functions that have clearer prototypes and that don't mix logically unrelated blocks of code Fixed issues in case of unsupported extensions Fixed memory leaks on errors, which are now properly propagated to the main() function Fixed issue on raw images output fprintf() replaced with av_log() Input A/V parameters exposed in the main() function and easier to customize --- doc/examples/muxing.c | 919 +++--- 1 file changed, 423 insertions(+), 496 deletions(-) diff --git a/doc/examples/muxing.c b/doc/examples/muxing.c index 3acb778322..a91134ac7c 100644 --- a/doc/examples/muxing.c +++ b/doc/examples/muxing.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2003 Fabrice Bellard + * (Code rewrite by Paolo Prete, 2022) * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -24,625 +25,551 @@ * @file * libavformat API example. * - * Output a media file in any supported libavformat format. The default + * Output a media file in a set of supported libavformat formats. The default * codecs are used. * @example muxing.c */ -#include -#include -#include -#include - -#include -#include -#include -#include -#include #include #include -#include +#include #include +#include -#define STREAM_DURATION 10.0 -#define STREAM_FRAME_RATE 25 /* 25 images/s */ -#define STREAM_PIX_FMTAV_PIX_FMT_YUV420P /* default pix_fmt */ - -#define SCALE_FLAGS SWS_BICUBIC +#define VIDEO_FRAME_RATE 25 /* 25 images/s */ +#define VIDEO_SCALE_FLAGS SWS_BICUBIC +#define STREAM_DURATION 10.0 /* 10 seconds */ -// a wrapper around a single output AVStream -typedef struct OutputStream { -AVStream *st; -AVCodecContext *enc; +static void log_error(const char *s, int *num) +{ +if (num) +av_log(NULL, AV_LOG_ERROR, "%s (error '%s')\n", s, av_err2str(*num)); +else +av_log(NULL, AV_LOG_ERROR, "%s\n", s); +} -/* pts of the next frame that will be generated */ -int64_t next_pts; -int samples_count; +static int mux_encoded_pkt(AVPacket *out_pkt, AVFormatContext *out_fmt_ctx, + enum AVMediaType type) +{ +int ret; +AVRational enc_time_base, str_time_base; -AVFrame *frame; -AVFrame *tmp_frame; +if (out_fmt_ctx->streams[0]->codecpar->codec_type == type) +out_pkt->stream_index = 0; +else if ((out_fmt_ctx->nb_streams > 1) && (type == AVMEDIA_TYPE_VIDEO)) +out_pkt->stream_index = 1; +str_time_base = out_fmt_ctx->streams[out_pkt->stream_index]->time_base; -AVPacket *tmp_pkt; +if (type == AVMEDIA_TYPE_AUDIO) +enc_time_base = ((AVRational *)out_fmt_ctx->opaque)[0]; +else +enc_time_base = ((AVRational *)out_fmt_ctx->opaque)[1]; -float t, tincr, tincr2; +av_packet_rescale_ts(out_pkt, enc_time_base, str_time_base); -struct SwsContext *sws_ctx; -struct SwrContext *swr_ctx; -} OutputStream; +av_log(NULL, AV_LOG_INFO, "stream_index=%d, size=%d, pts_time=%s\n", + out_pkt->stream_index, + out_pkt->size, av_ts2timestr(out_pkt->pts, &str_time_base)); -static void log_packet(const AVFormatContext *fmt_ctx, const AVPacket *pkt) -{ -AVRational *time_base = &fmt_ctx->streams[pkt->stream_index]->time_base; +if ((ret = av_interleaved_write_frame(out_fmt_ctx, out_pkt)) < 0) +log_error("Error calling av_interleaved_write_frame()", &ret); -printf("pts:%s pts_time:%s dts:%s dts_time:%s duration:%s duration_time:%s stream_index:%d\n", - av_ts2str(pkt->pts), av_ts2timestr(pkt->pts, time_base), - av_ts2str(pkt->dts), av_ts2timestr(pkt->dts, time_base), - av_ts2str(pkt->duration), av_ts2timestr(pkt->duration, time_base), - pkt->stream_index); +return ret; } -static int write_frame(AVFormatContext *fmt_ctx, AVCodecContext *c, - AVStream *st, AVFrame *frame, AVPacket *pkt) +static int is_extension_supported(const char *filename) { -int ret; - -// send the frame to the encoder -ret = avcodec_send_frame(c, frame); -if (ret < 0) { -fprintf(stderr, "Error sending a frame to the encoder: %s\n", -av_err2str(ret)); -exit(1); -} - -while (ret >=
Re: [FFmpeg-devel] [PATCH v20 1/5] libavutil: Add wchartoutf8(), wchartoansi(), utf8toansi(), getenv_utf8(), freeenv_utf8() and getenv_dup()
On Mon, 20 Jun 2022, Nil Admirari wrote: wchartoutf8() converts strings returned by WinAPI into UTF-8, which is FFmpeg's preffered encoding. Some external dependencies, such as AviSynth, are still not Unicode-enabled. utf8toansi() converts UTF-8 strings into ANSI in two steps: UTF-8 -> wchar_t -> ANSI. wchartoansi() is responsible for the second step of the conversion. Conversion in just one step is not supported by WinAPI. Since these character converting functions allocate the buffer of necessary size, they also facilitate the removal of MAX_PATH limit in places where fixed-size ANSI/WCHAR strings were used as filename buffers. On Windows, getenv_utf8() wraps _wgetenv() converting its input from and its output to UTF-8. Strings returned by getenv_utf8() must be freed by freeenv_utf8(). On all other platforms getenv_utf8() is a wrapper around getenv(), and freeenv_utf8() is a no-op. The value returned by plain getenv() cannot be modified; av_strdup() is usually used when modifications are required. However, on Windows, av_strdup() after getenv_utf8() leads to unnecessary allocation. getenv_dup() is introduced to avoid such an allocation. Value returned by getenv_dup() must be freed by av_free(). Because of cleanup complexities, in places that only test the existence of an environment variable or compare its value with a string consisting entirely of ASCII characters, the use of plain getenv() is still preferred. (libavutil/log.c check_color_terminal() is an example of such a place.) Plain getenv() is also preffered in UNIX-only code, such as bktr.c, fbdev_common.c, oss.c in libavdevice or af_ladspa.c in libavfilter. --- configure | 1 + libavutil/getenv_utf8.h| 86 ++ libavutil/wchar_filename.h | 53 +++ 3 files changed, 140 insertions(+) create mode 100644 libavutil/getenv_utf8.h This set looks good to me, thanks! Will push tomorrow if there's nothing more to add on it. // Martin ___ 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] fftools/ffmpeg: change frame counters to 64 bit
Frame counters can overflow relatively easily (INT_MAX number of frames is slightly more than 1 year for 60 fps content), so make sure we are always using 64 bit values for them. A live stream can easily run for more than a year and the framedup logic breaks on an overflow. Signed-off-by: Marton Balint --- fftools/ffmpeg.c | 38 +++--- fftools/ffmpeg.h | 6 +++--- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 09caa3e3c4..e7384f052a 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -131,9 +131,9 @@ static BenchmarkTimeStamps get_benchmark_time_stamps(void); static int64_t getmaxrss(void); static int ifilter_has_all_input_formats(FilterGraph *fg); -static int nb_frames_dup = 0; -static unsigned dup_warning = 1000; -static int nb_frames_drop = 0; +static int64_t nb_frames_dup = 0; +static uint64_t dup_warning = 1000; +static int64_t nb_frames_drop = 0; static int64_t decode_error_stat[2]; unsigned nb_output_dumped = 0; @@ -839,7 +839,7 @@ static void update_video_stats(OutputStream *ost, const AVPacket *pkt, int write const uint8_t *sd = av_packet_get_side_data(pkt, AV_PKT_DATA_QUALITY_STATS, NULL); AVCodecContext *enc = ost->enc_ctx; -int frame_number; +int64_t frame_number; double ti1, bitrate, avg_bitrate; ost->quality = sd ? AV_RL32(sd) : -1; @@ -866,10 +866,10 @@ static void update_video_stats(OutputStream *ost, const AVPacket *pkt, int write frame_number = ost->packets_encoded; if (vstats_version <= 1) { -fprintf(vstats_file, "frame= %5d q= %2.1f ", frame_number, +fprintf(vstats_file, "frame= %5"PRId64" q= %2.1f ", frame_number, ost->quality / (float)FF_QP2LAMBDA); } else { -fprintf(vstats_file, "out= %2d st= %2d frame= %5d q= %2.1f ", ost->file_index, ost->index, frame_number, +fprintf(vstats_file, "out= %2d st= %2d frame= %5"PRId64" q= %2.1f ", ost->file_index, ost->index, frame_number, ost->quality / (float)FF_QP2LAMBDA); } @@ -1082,7 +1082,7 @@ static void do_video_out(OutputFile *of, int ret; AVCodecContext *enc = ost->enc_ctx; AVRational frame_rate; -int nb_frames, nb0_frames, i; +int64_t nb_frames, nb0_frames, i; double delta, delta0; double duration = 0; double sync_ipts = AV_NOPTS_VALUE; @@ -1152,7 +1152,7 @@ static void do_video_out(OutputFile *of, } else if (delta < -1.1) nb_frames = 0; else if (delta > 1.1) { -nb_frames = lrintf(delta); +nb_frames = llrintf(delta); if (delta0 > 1.1) nb0_frames = llrintf(delta0 - 0.6); } @@ -1188,19 +1188,19 @@ static void do_video_out(OutputFile *of, if (nb0_frames == 0 && ost->last_dropped) { nb_frames_drop++; av_log(NULL, AV_LOG_VERBOSE, - "*** dropping frame %d from stream %d at ts %"PRId64"\n", + "*** dropping frame %"PRId64" from stream %d at ts %"PRId64"\n", ost->frame_number, ost->st->index, ost->last_frame->pts); } if (nb_frames > (nb0_frames && ost->last_dropped) + (nb_frames > nb0_frames)) { if (nb_frames > dts_error_threshold * 30) { -av_log(NULL, AV_LOG_ERROR, "%d frame duplication too large, skipping\n", nb_frames - 1); +av_log(NULL, AV_LOG_ERROR, "%"PRId64" frame duplication too large, skipping\n", nb_frames - 1); nb_frames_drop++; return; } nb_frames_dup += nb_frames - (nb0_frames && ost->last_dropped) - (nb_frames > nb0_frames); -av_log(NULL, AV_LOG_VERBOSE, "*** %d dup!\n", nb_frames - 1); +av_log(NULL, AV_LOG_VERBOSE, "*** %"PRId64" dup!\n", nb_frames - 1); if (nb_frames_dup > dup_warning) { -av_log(NULL, AV_LOG_WARNING, "More than %d frames duplicated\n", dup_warning); +av_log(NULL, AV_LOG_WARNING, "More than %"PRIu64" frames duplicated\n", dup_warning); dup_warning *= 10; } } @@ -1511,7 +1511,7 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti AVFormatContext *oc; int64_t total_size; AVCodecContext *enc; -int frame_number, vid, i; +int vid, i; double bitrate; double speed; int64_t pts = INT64_MIN + 1; @@ -1562,12 +1562,12 @@ static void print_report(int is_last_report, int64_t timer_start, int64_t cur_ti } if (!vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) { float fps; +int64_t frame_number = ost->frame_number; -frame_number = ost->frame_number; fps = t > 1 ? frame_number / t : 0; -av_bprintf(&buf, "frame=%5d fps=%3.*f q=%3.1f ", +av_bprintf(&buf, "frame=%5"PRId64" fps=%3.*f q=%3.1f ",
Re: [FFmpeg-devel] [PATCH 5/6] avformat/movenc: utilize existing AC-3 parsing workflow for AC-3
On Mon, Jun 20, 2022 at 12:10 PM Andreas Rheinhardt wrote: > > Jan Ekström: > > From: Jan Ekström > > > > Signed-off-by: Jan Ekström > > --- > > libavformat/Makefile | 1 + > > libavformat/ac3_bitrate_tab.c | 22 ++ > > libavformat/movenc.c | 55 +-- > > 3 files changed, 50 insertions(+), 28 deletions(-) > > create mode 100644 libavformat/ac3_bitrate_tab.c > > > > diff --git a/libavformat/Makefile b/libavformat/Makefile > > index 1416bf31bd..c71de95b2f 100644 > > --- a/libavformat/Makefile > > +++ b/libavformat/Makefile > > @@ -699,6 +699,7 @@ SHLIBOBJS-$(CONFIG_FLV_MUXER)+= > > mpeg4audio_sample_rates.o > > SHLIBOBJS-$(CONFIG_HLS_DEMUXER) += ac3_channel_layout_tab.o > > SHLIBOBJS-$(CONFIG_MATROSKA_DEMUXER) += mpeg4audio_sample_rates.o > > SHLIBOBJS-$(CONFIG_MOV_DEMUXER) += ac3_channel_layout_tab.o > > +SHLIBOBJS-$(CONFIG_MOV_MUXER)+= ac3_bitrate_tab.o > > SHLIBOBJS-$(CONFIG_MP3_MUXER)+= mpegaudiotabs.o > > SHLIBOBJS-$(CONFIG_MXF_MUXER)+= golomb_tab.o > > SHLIBOBJS-$(CONFIG_NUT_MUXER)+= mpegaudiotabs.o > > The above line only takes care of duplicating ac3_bitrate_tab.o into > lavf for shared builds; yet there needs to be a corresponding STLIBOBJS > entry in lavc/Makefile so that lavc/ac3_bitrate_tab.o is compiled in > case the mov muxer is enabled in a static build. > It would work either way in this case because #2 made the mov muxer > depend upon the ac3 parser which makes lavc/ac3_bitrate_tab.o be included. > OK, then I clearly missed something since I thought I was following how you had done things earlier for the other table. Will look into this tomorrow morning. > > diff --git a/libavformat/ac3_bitrate_tab.c b/libavformat/ac3_bitrate_tab.c > > new file mode 100644 > > index 00..57b6181511 > > --- /dev/null > > +++ b/libavformat/ac3_bitrate_tab.c > > @@ -0,0 +1,22 @@ > > +/* > > + * AC-3 bit rate table > > + * copyright (c) 2001 Fabrice Bellard > > + * > > + * This file is part of FFmpeg. > > + * > > + * FFmpeg is free software; you can redistribute it and/or > > + * modify it under the terms of the GNU Lesser General Public > > + * License as published by the Free Software Foundation; either > > + * version 2.1 of the License, or (at your option) any later version. > > + * > > + * FFmpeg is distributed in the hope that it will be useful, > > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > > + * Lesser General Public License for more details. > > + * > > + * You should have received a copy of the GNU Lesser General Public > > + * License along with FFmpeg; if not, write to the Free Software > > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA > > 02110-1301 USA > > + */ > > + > > +#include "libavcodec/ac3_bitrate_tab.h" > > diff --git a/libavformat/movenc.c b/libavformat/movenc.c > > index 103f958d75..a071f1cdd5 100644 > > --- a/libavformat/movenc.c > > +++ b/libavformat/movenc.c > > @@ -36,6 +36,7 @@ > > #include "av1.h" > > #include "avc.h" > > #include "libavcodec/ac3_parser_internal.h" > > +#include "libavcodec/ac3tab.h" > > #include "libavcodec/dnxhddata.h" > > #include "libavcodec/flac.h" > > #include "libavcodec/get_bits.h" > > @@ -362,44 +363,42 @@ struct eac3_info { > > > > static int mov_write_ac3_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack > > *track) > > { > > -GetBitContext gbc; > > +struct eac3_info *info = track->eac3_priv; > > +int8_t ac3_bit_rate_code = -1; > > PutBitContext pbc; > > uint8_t buf[3]; > > -int fscod, bsid, bsmod, acmod, lfeon, frmsizecod; > > > > -if (track->vos_len < 7) { > > +if (!info || !info->ec3_done) { > > av_log(s, AV_LOG_ERROR, > > "Cannot write moov atom before AC3 packets." > > " Set the delay_moov flag to fix this.\n"); > > return AVERROR(EINVAL); > > } > > > > -avio_wb32(pb, 11); > > -ffio_wfourcc(pb, "dac3"); > > +for (unsigned int i = 0; i < FF_ARRAY_ELEMS(ff_ac3_bitrate_tab); i++) { > > +if (info->data_rate == ff_ac3_bitrate_tab[i]) { > > +ac3_bit_rate_code = i; > > Anyway, I see that you use ff_ac3_bitrate_tab in lavf instead of adding > the frame_size_code to AC3HeaderInfo. Did it turn out to be easier this > way or what is the reason for this? I did partially go through the reasoning in the cover letter, but here's a short rewording: 1. This way doesn't extend the semi-public avpriv. 2. While reviewing I noticed that bsid 9, 10 streams (apparently some RealAudio fork of AC-3) actually have the sample/bit rate values bit shifted (divided by either 2 or 4). The table in the ETSI specification is based on the effective bit rate. While it is highly unlikely that someone would put that type of AC-3 into MP4, In that case I'd then have to re-index
Re: [FFmpeg-devel] [PATCH 4/5] lavc/bitstream: make skip_remaining() public
Anton Khirnov: > Also rename it to bitstream_skip_cache(), which is more descriptive and > follows the naming conventions of tis API. > --- > libavcodec/bitstream.h | 1 + > libavcodec/bitstream_template.h | 19 --- > 2 files changed, 13 insertions(+), 7 deletions(-) > > diff --git a/libavcodec/bitstream.h b/libavcodec/bitstream.h > index 3fa63695d3..364245453b 100644 > --- a/libavcodec/bitstream.h > +++ b/libavcodec/bitstream.h > @@ -116,6 +116,7 @@ static inline void bitstream_unget(BitstreamContext *bc, > uint64_t value, > #define bitstream_peek bitstream_peek_be > #define bitstream_peek_signed bitstream_peek_signed_be > #define bitstream_skip bitstream_skip_be > +#define bitstream_skip_cachebitstream_skip_cache_be > #define bitstream_seek bitstream_seek_be > #define bitstream_align bitstream_align_be > #define bitstream_read_xbitsbitstream_read_xbits_be > diff --git a/libavcodec/bitstream_template.h b/libavcodec/bitstream_template.h > index 14a420139c..717473ca40 100644 > --- a/libavcodec/bitstream_template.h > +++ b/libavcodec/bitstream_template.h > @@ -225,7 +225,12 @@ static inline int > BS_FUNC(bitstream_peek_signed)(BitstreamContext *bc, unsigned > return sign_extend(BS_FUNC(bitstream_peek)(bc, n), n); > } > > -static inline void BS_FUNC(skip_remaining)(BitstreamContext *bc, unsigned > int n) > +/** > + * Skip n bits from the cache. This may only be called if at least n bits are > + * guaranteed to be in the cache, e.g. right after bitstream_peek(n). > + * Otherwise use bitstream_skip(). > + */ > +static inline void BS_FUNC(bitstream_skip_cache)(BitstreamContext *bc, > unsigned int n) > { > #ifdef BITSTREAM_LE > bc->bits >>= n; > @@ -241,7 +246,7 @@ static inline void > BS_FUNC(skip_remaining)(BitstreamContext *bc, unsigned int n) > static inline void BS_FUNC(bitstream_skip)(BitstreamContext *bc, unsigned > int n) > { > if (n < bc->bits_left) > -BS_FUNC(skip_remaining)(bc, n); > +BS_FUNC(bitstream_skip_cache)(bc, n); > else { > n -= bc->bits_left; > bc->bits = 0; > @@ -255,7 +260,7 @@ static inline void > BS_FUNC(bitstream_skip)(BitstreamContext *bc, unsigned int n) > } > BS_FUNC(refill_64)(bc); > if (n) > -BS_FUNC(skip_remaining)(bc, n); > +BS_FUNC(bitstream_skip_cache)(bc, n); > } > } > > @@ -291,7 +296,7 @@ static inline int > BS_FUNC(bitstream_read_xbits)(BitstreamContext *bc, unsigned i > { > int32_t cache = BS_FUNC(bitstream_peek)(bc, 32); > int sign = ~cache >> 31; > -BS_FUNC(skip_remaining)(bc, n); > +BS_FUNC(bitstream_skip_cache)(bc, n); > > return uint32_t)(sign ^ cache)) >> (32 - n)) ^ sign) - sign; > } > @@ -374,14 +379,14 @@ static inline int > BS_FUNC(bitstream_read_vlc)(BitstreamContext *bc, VLC_TYPE (*t > int n= table[idx][1]; > > if (max_depth > 1 && n < 0) { > -BS_FUNC(skip_remaining)(bc, bits); > +BS_FUNC(bitstream_skip_cache)(bc, bits); > code = BS_FUNC(set_idx)(bc, code, &n, &nb_bits, table); > if (max_depth > 2 && n < 0) { > -BS_FUNC(skip_remaining)(bc, nb_bits); > +BS_FUNC(bitstream_skip_cache)(bc, nb_bits); > code = BS_FUNC(set_idx)(bc, code, &n, &nb_bits, table); > } > } > -BS_FUNC(skip_remaining)(bc, n); > +BS_FUNC(bitstream_skip_cache)(bc, n); > > return code; > } How do you intend to avoid the issue described here: https://ffmpeg.org/pipermail/ffmpeg-devel/2022-June/297850.html? Bitstream_peek() does not guarantee that there are bits bits in the cache even though your documentation says otherwise. - Andreas ___ 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] avcodec/get_bits: Don't let number of bits_left become invalid
When using the checked cached bitstream reader, it can currently happen that the GetBitContext's number of bits_left becomes wrong, namely off by UINT_MAX due to wraparound (if it were an int, it would become negative). The reason for this is that reading new input is performed through show_bits() which does not update get_vlc2() if one is already past the end of input*, so that the following skip_remaining() may remove more bits than are actually present (it seems to have been designed as if it were only to be called if there are enough bits left). (The issue could be reproduced with fraps-v5-bouncing-balls-partial.avi from the FATE suite if fraps were modified to use a checked bitstream reader.) At the moment, this does not seem to cause any issues: The only place where bits_left is used as in the right operand of a shift is when refilling and this doesn't happen if one is already at the end. Furthermore, get_bits_count() and get_bits_left() return proper values, because they return an int and so being off by UINT_MAX doesn't matter. Some functions that check whether the cache has enough bits left will directly read from the cache. This commit nevertheless intends to fix this by adding a variant of refill_32() that always adds 32 bits to bits_left, but reports if it has added fake bits (not read from the bitstream), so that they can be compensated for. To do so, the first thing get_vlc2() does is ensuring that at least 32 bits are in the cache (even if fake bits), so that all the following operations can be performed on the cache (the earlier code potentially refilled the cache at every reading stage). This is also beneficial for code size. In the following, Clang means Clang 14 and GCC GCC 11.2: | Clang old | Clang new | GCC old | GCC new _ fraps |f84|f04| c9e | b7e magicyuv | 1f2f| 1ecf| 1b1b | 1a49 mvha |c8a|bfa| 11f4 | 1168 photocd| 12d5| 12f9| 15ca | 15aa sheervideo | 14f2a| 11778| 103d3 | 10339 utvideodec | 35a1| 34d1| 3037 | 2ea7 (None of the above files (which are all files that use the cached bitstream reader) call get_vlc2() with a max depth of one; in this case, saving refill_32() wins size-wise. This is unfortunately not true in case of max_depth == 1, where the added check leads to a slight codesize increase.) It is unfortunately not beneficial for speed in the majority of cases, probably because of the additional branch that is added to the common case in which the result is obtained after only one lookup. *: The unchecked bitstream reader does not have this check and is therefore unaffected by this issue. Signed-off-by: Andreas Rheinhardt --- get_xbits() also suffers from the problem that it skips bits that need not be present (no user of get_xbits() uses the cached bitstream reader). I think that there is another potential issue with the cached bitstream reader: Checking for whether an overread already happened may not work, namely if the buffer length is a multiple of four and != 4. In this case get_bits_left() will return 0 even after an overread. This could be fixed by modifying the overread check s->index >> 3 >= s->buffer_end - s->buffer to ">" (this is similar to using size_in_bits_plus8 in the ordinary GetBitContext). libavcodec/get_bits.h | 77 +-- 1 file changed, 67 insertions(+), 10 deletions(-) diff --git a/libavcodec/get_bits.h b/libavcodec/get_bits.h index 16f8af5107..d48ff111a4 100644 --- a/libavcodec/get_bits.h +++ b/libavcodec/get_bits.h @@ -227,13 +227,8 @@ static inline int get_bits_count(const GetBitContext *s) } #if CACHED_BITSTREAM_READER -static inline void refill_32(GetBitContext *s, int is_le) +static av_always_inline void refill_32_internal(GetBitContext *s, int is_le) { -#if !UNCHECKED_BITSTREAM_READER -if (s->index >> 3 >= s->buffer_end - s->buffer) -return; -#endif - if (is_le) s->cache = (uint64_t)AV_RL32(s->buffer + (s->index >> 3)) << s->bits_left | s->cache; else @@ -242,6 +237,52 @@ static inline void refill_32(GetBitContext *s, int is_le) s->bits_left += 32; } +/** + * If the end of input has not been reached yet, refill the GetBitContext + * with 32 bits read from the bitstream. + * Otherwise just pretend that it read 32 zeroes. One can then use + * show_val()/get_val()/skip_remaining() (which require enough cache bits + * to be available) as if there were at least 32 bits available; + * all other functions not solely based upon these are forbidden. + * Lateron one has to use fixup_fake with the return value of this function + * to restore the GetBitContext. + * + * This function is internal to the GetBit-API; access from users is forbidden. + * + * @return The amount of fake bits added. + */ +static inline unsigned refill_32_fake(GetBitContext *s, int is_le) +{ +#if !UNCHECK
Re: [FFmpeg-devel] [PATCH 00/41] Stop including superseded functions for x64
Andreas Rheinhardt: > Andreas Rheinhardt: >> x64 requires MMX, MMXEXT, SSE and SSE2; yet there is no shortage >> of code like the following: >> >> if (EXTERNAL_MMX(cpu_flags)) { >> c->ssd_int8_vs_int16 = ff_ssd_int8_vs_int16_mmx; >> } >> if (EXTERNAL_SSE2(cpu_flags)) { >> c->ssd_int8_vs_int16 = ff_ssd_int8_vs_int16_sse2; >> } >> >> Given that SSE2 is always present on x64, the only way >> for the mmx version to be chosen in the above example >> is if SSE2 has been disabled either at compile-time >> or at runtime, i.e. it is never used unless one shoots >> oneself in the foot. >> This patchset therefore disables such functions for x64 >> by #if'ing them away; x86 has not been affected. This >> saves about 140KB. >> >> (Another way to handle this would be to remove every function >> that would be overridden if one had a processor capable of >> MMX, MMXEXT, SSE and SSE2. x86 processors not fulfilling >> this requirement (which are truely ancient nowadays) >> would still work, but would be slower, i.e. they would be treated >> as second-class citizens. This would have the advantage of >> avoiding #ifs and would lighten x86 binaries of code that is >> not used at all by the overwhelming majority of users. >> I'll update this patchset if it is preferred to do it that way.) >> > > I have now implemented this other way mentioned above (i.e. removing > stuff that is overridden if SSE2 is available altogether also for > x86-32); the result can be seen here: > https://github.com/mkver/FFmpeg/commits/mmx2 > I prefer this to the old version because of the reduced complexity which > dwarfs the potential to slow down some ancient systems a bit (if these > ancient systems use an up-to-date FFmpeg which is quite unlikely). > Furthermore, some of the MMX scale functions that are removed are > buggy/not bixexact. See > https://github.com/mkver/FFmpeg/commit/c5513ad962100040601b5eba0042692a740ac50a > (or shall I post these patches?) > Is anyone against this removal? > Given that no one was against removing these old functions, but several people (on IRC) supported the idea I will go ahead and do it. I will apply https://github.com/mkver/FFmpeg/commits/mmx3 (an updated and extended version of the branch linked to above) in two days unless there are objections. (I can also send this to the mailing list if desired.) - Andreas ___ 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 v17 1/5] libavutil: Add wchartoutf8(), wchartoansi(), utf8toansi() and getenv_utf8()
> Or any reuses the #ifs from getenv_utf8.h. > https://github.com/mkver/FFmpeg/commits/getenv contains a version that > does this. Introduced getenv_dup() and simplified #ifs a little: https://ffmpeg.org/pipermail/ffmpeg-devel/2022-June/297841.html ___ 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 v19 3/5] fftools: Remove MAX_PATH limit and switch to UTF-8 versions of fopen() and getenv()
> ./libavutil/getenv_utf8.h: In function ‘freeenv_utf8’: > ./libavutil/getenv_utf8.h:69:1: error: parameter name omitted > static inline void freeenv_utf8(const char *) > ^~ Fixed: https://ffmpeg.org/pipermail/ffmpeg-devel/2022-June/297841.html ___ 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 v19 1/5] libavutil: Add wchartoutf8(), wchartoansi(), utf8toansi(), getenv_utf8() and freeenv_utf8()
> Looks good overall, thanks! The freeenv_utf8 function needed a couple > minor fixes though, to fix these warnings/errors: Fixed: https://ffmpeg.org/pipermail/ffmpeg-devel/2022-June/297841.html ___ 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 v20 4/5] libavformat: Remove MAX_PATH limit and use UTF-8 version of getenv()
1. getenv() is replaced with getenv_utf8() across libavformat. 2. New versions of AviSynth+ are now called with UTF-8 filenames. 3. Old versions of AviSynth are still using ANSI strings, but MAX_PATH limit on filename is removed. --- libavformat/avisynth.c| 39 +++ libavformat/http.c| 22 ++ libavformat/ipfsgateway.c | 36 libavformat/tls.c | 11 +-- 4 files changed, 74 insertions(+), 34 deletions(-) diff --git a/libavformat/avisynth.c b/libavformat/avisynth.c index 8ba2bdead2..a97d12b6b6 100644 --- a/libavformat/avisynth.c +++ b/libavformat/avisynth.c @@ -34,6 +34,7 @@ /* Platform-specific directives. */ #ifdef _WIN32 #include "compat/w32dlfcn.h" + #include "libavutil/wchar_filename.h" #undef EXTERN_C #define AVISYNTH_LIB "avisynth" #else @@ -56,6 +57,7 @@ typedef struct AviSynthLibrary { #define AVSC_DECLARE_FUNC(name) name ## _func name AVSC_DECLARE_FUNC(avs_bit_blt); AVSC_DECLARE_FUNC(avs_clip_get_error); +AVSC_DECLARE_FUNC(avs_check_version); AVSC_DECLARE_FUNC(avs_create_script_environment); AVSC_DECLARE_FUNC(avs_delete_script_environment); AVSC_DECLARE_FUNC(avs_get_audio); @@ -137,6 +139,7 @@ static av_cold int avisynth_load_library(void) LOAD_AVS_FUNC(avs_bit_blt, 0); LOAD_AVS_FUNC(avs_clip_get_error, 0); +LOAD_AVS_FUNC(avs_check_version, 0); LOAD_AVS_FUNC(avs_create_script_environment, 0); LOAD_AVS_FUNC(avs_delete_script_environment, 0); LOAD_AVS_FUNC(avs_get_audio, 0); @@ -807,26 +810,38 @@ static int avisynth_create_stream(AVFormatContext *s) static int avisynth_open_file(AVFormatContext *s) { AviSynthContext *avs = s->priv_data; -AVS_Value arg, val; +AVS_Value val; int ret; -#ifdef _WIN32 -char filename_ansi[MAX_PATH * 4]; -wchar_t filename_wc[MAX_PATH * 4]; -#endif if (ret = avisynth_context_create(s)) return ret; +if (!avs_library.avs_check_version(avs->env, 7)) { +AVS_Value args[] = { +avs_new_value_string(s->url), +avs_new_value_bool(1) // filename is in UTF-8 +}; +val = avs_library.avs_invoke(avs->env, "Import", + avs_new_value_array(args, 2), 0); +} else { +AVS_Value arg; #ifdef _WIN32 -/* Convert UTF-8 to ANSI code page */ -MultiByteToWideChar(CP_UTF8, 0, s->url, -1, filename_wc, MAX_PATH * 4); -WideCharToMultiByte(CP_THREAD_ACP, 0, filename_wc, -1, filename_ansi, -MAX_PATH * 4, NULL, NULL); -arg = avs_new_value_string(filename_ansi); +char *filename_ansi; +/* Convert UTF-8 to ANSI code page */ +if (utf8toansi(s->url, &filename_ansi)) { +ret = AVERROR_UNKNOWN; +goto fail; +} +arg = avs_new_value_string(filename_ansi); #else -arg = avs_new_value_string(s->url); +arg = avs_new_value_string(s->url); #endif -val = avs_library.avs_invoke(avs->env, "Import", arg, 0); +val = avs_library.avs_invoke(avs->env, "Import", arg, 0); +#ifdef _WIN32 +av_free(filename_ansi); +#endif +} + if (avs_is_error(val)) { av_log(s, AV_LOG_ERROR, "%s\n", avs_as_error(val)); ret = AVERROR_UNKNOWN; diff --git a/libavformat/http.c b/libavformat/http.c index c8f3f4b6a3..f80ea7bf35 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -29,6 +29,7 @@ #include "libavutil/avassert.h" #include "libavutil/avstring.h" #include "libavutil/bprint.h" +#include "libavutil/getenv_utf8.h" #include "libavutil/opt.h" #include "libavutil/time.h" #include "libavutil/parseutils.h" @@ -198,12 +199,13 @@ void ff_http_init_auth_state(URLContext *dest, const URLContext *src) static int http_open_cnx_internal(URLContext *h, AVDictionary **options) { const char *path, *proxy_path, *lower_proto = "tcp", *local_path; +char *env_http_proxy, *env_no_proxy; char *hashmark; char hostname[1024], hoststr[1024], proto[10]; char auth[1024], proxyauth[1024] = ""; char path1[MAX_URL_SIZE], sanitized_path[MAX_URL_SIZE + 1]; char buf[1024], urlbuf[MAX_URL_SIZE]; -int port, use_proxy, err; +int port, use_proxy, err = 0; HTTPContext *s = h->priv_data; av_url_split(proto, sizeof(proto), auth, sizeof(auth), @@ -211,9 +213,13 @@ static int http_open_cnx_internal(URLContext *h, AVDictionary **options) path1, sizeof(path1), s->location); ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL); -proxy_path = s->http_proxy ? s->http_proxy : getenv("http_proxy"); -use_proxy = !ff_http_match_no_proxy(getenv("no_proxy"), hostname) && +env_http_proxy = getenv_utf8("http_proxy"); +proxy_path = s->http_proxy ? s->http_proxy : env_http_proxy; + +env_no_proxy = getenv_utf8("no_proxy"); +use_proxy = !ff_http_match_no_proxy(env_no_proxy, h
[FFmpeg-devel] [PATCH v20 5/5] libavfilter/vf_frei0r.c: Use UTF-8 version of getenv()
--- libavfilter/vf_frei0r.c | 14 ++ 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c index f11ae6e55c..1e01114b76 100644 --- a/libavfilter/vf_frei0r.c +++ b/libavfilter/vf_frei0r.c @@ -31,6 +31,7 @@ #include "libavutil/avstring.h" #include "libavutil/common.h" #include "libavutil/eval.h" +#include "libavutil/getenv_utf8.h" #include "libavutil/imgutils.h" #include "libavutil/internal.h" #include "libavutil/mathematics.h" @@ -204,7 +205,7 @@ static av_cold int frei0r_init(AVFilterContext *ctx, } /* see: http://frei0r.dyne.org/codedoc/html/group__pluglocations.html */ -if ((path = av_strdup(getenv("FREI0R_PATH" { +if (path = getenv_dup("FREI0R_PATH")) { #ifdef _WIN32 const char *separator = ";"; #else @@ -231,12 +232,17 @@ static av_cold int frei0r_init(AVFilterContext *ctx, if (ret < 0) return ret; } -if (!s->dl_handle && (path = getenv("HOME"))) { +if (!s->dl_handle && (path = getenv_utf8("HOME"))) { char *prefix = av_asprintf("%s/.frei0r-1/lib/", path); -if (!prefix) -return AVERROR(ENOMEM); +if (!prefix) { +ret = AVERROR(ENOMEM); +goto home_path_end; +} ret = load_path(ctx, &s->dl_handle, prefix, dl_name); av_free(prefix); + +home_path_end: +freeenv_utf8(path); if (ret < 0) return ret; } -- 2.34.1 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
[FFmpeg-devel] [PATCH v20 2/5] compat/w32dlfcn.h: Remove MAX_PATH limit and replace LoadLibraryExA with LoadLibraryExW
--- compat/w32dlfcn.h | 100 -- libavcodec/mf_utils.h | 1 + 2 files changed, 79 insertions(+), 22 deletions(-) diff --git a/compat/w32dlfcn.h b/compat/w32dlfcn.h index 52a94efafb..fb1aa1b72e 100644 --- a/compat/w32dlfcn.h +++ b/compat/w32dlfcn.h @@ -20,11 +20,40 @@ #define COMPAT_W32DLFCN_H #ifdef _WIN32 +#include + #include + #include "config.h" -#if (_WIN32_WINNT < 0x0602) || HAVE_WINRT +#include "libavutil/macros.h" #include "libavutil/wchar_filename.h" -#endif + +static inline wchar_t *get_module_filename(HMODULE module) +{ +wchar_t *path = NULL, *new_path; +DWORD path_size = 0, path_len; + +do { +path_size = path_size ? FFMIN(2 * path_size, INT16_MAX + 1) : MAX_PATH; +new_path = av_realloc_array(path, path_size, sizeof *path); +if (!new_path) { +av_free(path); +return NULL; +} +path = new_path; +// Returns path_size in case of insufficient buffer. +// Whether the error is set or not and whether the output +// is null-terminated or not depends on the version of Windows. +path_len = GetModuleFileNameW(module, path, path_size); +} while (path_len && path_size <= INT16_MAX && path_size <= path_len); + +if (!path_len) { +av_free(path); +return NULL; +} +return path; +} + /** * Safe function used to open dynamic libs. This attempts to improve program security * by removing the current directory from the dll search path. Only dll's found in the @@ -34,29 +63,53 @@ */ static inline HMODULE win32_dlopen(const char *name) { +wchar_t *name_w; +HMODULE module = NULL; +if (utf8towchar(name, &name_w)) +name_w = NULL; #if _WIN32_WINNT < 0x0602 -// Need to check if KB2533623 is available +// On Win7 and earlier we check if KB2533623 is available if (!GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "SetDefaultDllDirectories")) { -HMODULE module = NULL; -wchar_t *path = NULL, *name_w = NULL; -DWORD pathlen; -if (utf8towchar(name, &name_w)) +wchar_t *path = NULL, *new_path; +DWORD pathlen, pathsize, namelen; +if (!name_w) goto exit; -path = (wchar_t *)av_calloc(MAX_PATH, sizeof(wchar_t)); +namelen = wcslen(name_w); // Try local directory first -pathlen = GetModuleFileNameW(NULL, path, MAX_PATH); -pathlen = wcsrchr(path, '\\') - path; -if (pathlen == 0 || pathlen + wcslen(name_w) + 2 > MAX_PATH) +path = get_module_filename(NULL); +if (!path) +goto exit; +new_path = wcsrchr(path, '\\'); +if (!new_path) goto exit; -path[pathlen] = '\\'; +pathlen = new_path - path; +pathsize = pathlen + namelen + 2; +new_path = av_realloc_array(path, pathsize, sizeof *path); +if (!new_path) +goto exit; +path = new_path; wcscpy(path + pathlen + 1, name_w); module = LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); if (module == NULL) { // Next try System32 directory -pathlen = GetSystemDirectoryW(path, MAX_PATH); -if (pathlen == 0 || pathlen + wcslen(name_w) + 2 > MAX_PATH) +pathlen = GetSystemDirectoryW(path, pathsize); +if (!pathlen) goto exit; -path[pathlen] = '\\'; +// Buffer is not enough in two cases: +// 1. system directory + \ + module name +// 2. system directory even without the module name. +if (pathlen + namelen + 2 > pathsize) { +pathsize = pathlen + namelen + 2; +new_path = av_realloc_array(path, pathsize, sizeof *path); +if (!new_path) +goto exit; +path = new_path; +// Query again to handle the case #2. +pathlen = GetSystemDirectoryW(path, pathsize); +if (!pathlen) +goto exit; +} +path[pathlen] = L'\\'; wcscpy(path + pathlen + 1, name_w); module = LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); } @@ -73,16 +126,19 @@ exit: # define LOAD_LIBRARY_SEARCH_SYSTEM320x0800 #endif #if HAVE_WINRT -wchar_t *name_w = NULL; -int ret; -if (utf8towchar(name, &name_w)) +if (!name_w) return NULL; -ret = LoadPackagedLibrary(name_w, 0); -av_free(name_w); -return ret; +module = LoadPackagedLibrary(name_w, 0); #else -return LoadLibraryExA(name, NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32); +#define LOAD_FLAGS (LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32) +/* filename may be be in CP_ACP */ +if (!name_w) +return LoadLibraryExA(name, NULL, LOAD_FLAGS); +
[FFmpeg-devel] [PATCH v20 3/5] fftools: Remove MAX_PATH limit and switch to UTF-8 versions of fopen() and getenv()
--- fftools/cmdutils.c | 53 +--- fftools/ffmpeg_opt.c | 9 ++-- 2 files changed, 47 insertions(+), 15 deletions(-) diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c index 5d7cdc3e10..69a6f54ea3 100644 --- a/fftools/cmdutils.c +++ b/fftools/cmdutils.c @@ -39,6 +39,7 @@ #include "libavutil/avstring.h" #include "libavutil/channel_layout.h" #include "libavutil/display.h" +#include "libavutil/getenv_utf8.h" #include "libavutil/mathematics.h" #include "libavutil/imgutils.h" #include "libavutil/libm.h" @@ -47,9 +48,11 @@ #include "libavutil/dict.h" #include "libavutil/opt.h" #include "cmdutils.h" +#include "fopen_utf8.h" #include "opt_common.h" #ifdef _WIN32 #include +#include "compat/w32dlfcn.h" #endif AVDictionary *sws_dict; @@ -465,7 +468,7 @@ static void check_options(const OptionDef *po) void parse_loglevel(int argc, char **argv, const OptionDef *options) { int idx = locate_option(argc, argv, options, "loglevel"); -const char *env; +char *env; check_options(options); @@ -474,7 +477,8 @@ void parse_loglevel(int argc, char **argv, const OptionDef *options) if (idx && argv[idx + 1]) opt_loglevel(NULL, "loglevel", argv[idx + 1]); idx = locate_option(argc, argv, options, "report"); -if ((env = getenv("FFREPORT")) || idx) { +env = getenv_utf8("FFREPORT"); +if (env || idx) { FILE *report_file = NULL; init_report(env, &report_file); if (report_file) { @@ -487,6 +491,7 @@ void parse_loglevel(int argc, char **argv, const OptionDef *options) fflush(report_file); } } +freeenv_utf8(env); idx = locate_option(argc, argv, options, "hide_banner"); if (idx) hide_banner = 1; @@ -812,28 +817,45 @@ FILE *get_preset_file(char *filename, size_t filename_size, { FILE *f = NULL; int i; -const char *base[3] = { getenv("FFMPEG_DATADIR"), -getenv("HOME"), +#if HAVE_GETMODULEHANDLE && defined(_WIN32) +char *datadir = NULL; +#endif +char *env_home = getenv_utf8("HOME"); +char *env_ffmpeg_datadir = getenv_utf8("FFMPEG_DATADIR"); +const char *base[3] = { env_home, +env_ffmpeg_datadir, FFMPEG_DATADIR, }; if (is_path) { av_strlcpy(filename, preset_name, filename_size); -f = fopen(filename, "r"); +f = fopen_utf8(filename, "r"); } else { #if HAVE_GETMODULEHANDLE && defined(_WIN32) -char datadir[MAX_PATH], *ls; +wchar_t *datadir_w = get_module_filename(NULL); base[2] = NULL; -if (GetModuleFileNameA(GetModuleHandleA(NULL), datadir, sizeof(datadir) - 1)) +if (wchartoutf8(datadir_w, &datadir)) +datadir = NULL; +av_free(datadir_w); + +if (datadir) { -for (ls = datadir; ls < datadir + strlen(datadir); ls++) +char *ls; +for (ls = datadir; *ls; ls++) if (*ls == '\\') *ls = '/'; if (ls = strrchr(datadir, '/')) { -*ls = 0; -strncat(datadir, "/ffpresets", sizeof(datadir) - 1 - strlen(datadir)); -base[2] = datadir; +ptrdiff_t datadir_len = ls - datadir; +size_t desired_size = datadir_len + strlen("/ffpresets") + 1; +char *new_datadir = av_realloc_array( +datadir, desired_size, sizeof *datadir); +if (new_datadir) { +datadir = new_datadir; +datadir[datadir_len] = 0; +strncat(datadir, "/ffpresets", desired_size - 1 - datadir_len); +base[2] = datadir; +} } } #endif @@ -842,17 +864,22 @@ FILE *get_preset_file(char *filename, size_t filename_size, continue; snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i], i != 1 ? "" : "/.ffmpeg", preset_name); -f = fopen(filename, "r"); +f = fopen_utf8(filename, "r"); if (!f && codec_name) { snprintf(filename, filename_size, "%s%s/%s-%s.ffpreset", base[i], i != 1 ? "" : "/.ffmpeg", codec_name, preset_name); -f = fopen(filename, "r"); +f = fopen_utf8(filename, "r"); } } } +#if HAVE_GETMODULEHANDLE && defined(_WIN32) +av_free(datadir); +#endif +freeenv_utf8(env_ffmpeg_datadir); +freeenv_utf8(env_home); return f; } diff --git a/fftools/ffmpeg_opt.c b/fftools/ffmpeg_opt.c index 398067da96..e08455478f 100644 --- a/fftools/ffmpeg_opt.c +++ b/fftools/ffmpeg_opt.c @@ -44,6 +44,7 @@ #include "libavutil/avutil.h" #include "libavutil/bprint.h" #include "libavutil/channel_layout.h" +#include "libavut
[FFmpeg-devel] [PATCH v20 1/5] libavutil: Add wchartoutf8(), wchartoansi(), utf8toansi(), getenv_utf8(), freeenv_utf8() and getenv_dup()
wchartoutf8() converts strings returned by WinAPI into UTF-8, which is FFmpeg's preffered encoding. Some external dependencies, such as AviSynth, are still not Unicode-enabled. utf8toansi() converts UTF-8 strings into ANSI in two steps: UTF-8 -> wchar_t -> ANSI. wchartoansi() is responsible for the second step of the conversion. Conversion in just one step is not supported by WinAPI. Since these character converting functions allocate the buffer of necessary size, they also facilitate the removal of MAX_PATH limit in places where fixed-size ANSI/WCHAR strings were used as filename buffers. On Windows, getenv_utf8() wraps _wgetenv() converting its input from and its output to UTF-8. Strings returned by getenv_utf8() must be freed by freeenv_utf8(). On all other platforms getenv_utf8() is a wrapper around getenv(), and freeenv_utf8() is a no-op. The value returned by plain getenv() cannot be modified; av_strdup() is usually used when modifications are required. However, on Windows, av_strdup() after getenv_utf8() leads to unnecessary allocation. getenv_dup() is introduced to avoid such an allocation. Value returned by getenv_dup() must be freed by av_free(). Because of cleanup complexities, in places that only test the existence of an environment variable or compare its value with a string consisting entirely of ASCII characters, the use of plain getenv() is still preferred. (libavutil/log.c check_color_terminal() is an example of such a place.) Plain getenv() is also preffered in UNIX-only code, such as bktr.c, fbdev_common.c, oss.c in libavdevice or af_ladspa.c in libavfilter. --- configure | 1 + libavutil/getenv_utf8.h| 86 ++ libavutil/wchar_filename.h | 53 +++ 3 files changed, 140 insertions(+) create mode 100644 libavutil/getenv_utf8.h diff --git a/configure b/configure index 7ffbb85e21..3a97610209 100755 --- a/configure +++ b/configure @@ -2272,6 +2272,7 @@ SYSTEM_FUNCS=" fcntl getaddrinfo getauxval +getenv gethrtime getopt GetModuleHandle diff --git a/libavutil/getenv_utf8.h b/libavutil/getenv_utf8.h new file mode 100644 index 00..c10291adfc --- /dev/null +++ b/libavutil/getenv_utf8.h @@ -0,0 +1,86 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVUTIL_GETENV_UTF8_H +#define AVUTIL_GETENV_UTF8_H + +#include + +#include "config.h" +#include "mem.h" + +#if HAVE_GETENV && defined(_WIN32) + +#include "libavutil/wchar_filename.h" + +static inline char *getenv_utf8(const char *varname) +{ +wchar_t *varname_w, *var_w; +char *var; + +if (utf8towchar(varname, &varname_w)) +return NULL; +if (!varname_w) +return NULL; + +var_w = _wgetenv(varname_w); +av_free(varname_w); + +if (!var_w) +return NULL; +if (wchartoutf8(var_w, &var)) +return NULL; + +return var; + +// No CP_ACP fallback compared to other *_utf8() functions: +// non UTF-8 strings must not be returned. +} + +static inline void freeenv_utf8(char *var) +{ +av_free(var); +} + +static inline char *getenv_dup(const char *varname) +{ +return getenv_utf8(varname); +} + +#else + +static inline char *getenv_utf8(const char *varname) +{ +return getenv(varname); +} + +static inline void freeenv_utf8(char *var) +{ +} + +static inline char *getenv_dup(const char *varname) +{ +char *var = getenv(varname); +if (!var) +return NULL; +return av_strdup(var); +} + +#endif // HAVE_GETENV && defined(_WIN32) + +#endif // AVUTIL_GETENV_UTF8_H diff --git a/libavutil/wchar_filename.h b/libavutil/wchar_filename.h index f36d9dfea3..08de073ed7 100644 --- a/libavutil/wchar_filename.h +++ b/libavutil/wchar_filename.h @@ -20,6 +20,8 @@ #define AVUTIL_WCHAR_FILENAME_H #ifdef _WIN32 + +#define WIN32_LEAN_AND_MEAN #include #include "mem.h" @@ -41,6 +43,57 @@ static inline int utf8towchar(const char *filename_utf8, wchar_t **filename_w) return 0; } +av_warn_unused_result +static inline int wchartocp(unsigned int code_page, const wchar_t *filename_w, +char **filename) +{ +DWORD flags = code_page == CP_UTF8 ? WC_ERR_INVALID_CHARS : 0; +int num_chars = WideCharToMultiB
Re: [FFmpeg-devel] [PATCH v3] avcodec/mfenc: set variable frame size flag.
On 2022-06-19 09:14 pm, Gyan Doshi wrote: On 2022-06-19 03:15 pm, Gyan Doshi wrote: Default avctx->frame_size is 0 which led to init failure for audio MediaFoundation encoders since 827d6fe73d. The MF audio encoders accept variable frame size input buffers. Fixes #9802 Plan to push tomorrow. Pushed as 56419428a85fa83c2d2275b6eb82a4e7ac543401 Regards, Gyan ___ 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] libavcodec/qsvenc_hevc: Use default value from MSDK to set bf.
Change the default value of "bf" for hevc_qsv to -1. 8 isn't the best choice so let MSDK to decide the number of b frames. Signed-off-by: Wenbin Chen --- libavcodec/qsvenc_hevc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/qsvenc_hevc.c b/libavcodec/qsvenc_hevc.c index da2bf457af..f6027f600b 100644 --- a/libavcodec/qsvenc_hevc.c +++ b/libavcodec/qsvenc_hevc.c @@ -287,7 +287,7 @@ static const FFCodecDefault qsv_enc_defaults[] = { { "refs", "0" }, // same as the x264 default { "g", "248" }, -{ "bf","8" }, +{ "bf","-1"}, { "qmin", "-1"}, { "qmax", "-1"}, { "trellis", "-1"}, -- 2.32.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".
Re: [FFmpeg-devel] [PATCH 5/6] avformat/movenc: utilize existing AC-3 parsing workflow for AC-3
Jan Ekström: > From: Jan Ekström > > Signed-off-by: Jan Ekström > --- > libavformat/Makefile | 1 + > libavformat/ac3_bitrate_tab.c | 22 ++ > libavformat/movenc.c | 55 +-- > 3 files changed, 50 insertions(+), 28 deletions(-) > create mode 100644 libavformat/ac3_bitrate_tab.c > > diff --git a/libavformat/Makefile b/libavformat/Makefile > index 1416bf31bd..c71de95b2f 100644 > --- a/libavformat/Makefile > +++ b/libavformat/Makefile > @@ -699,6 +699,7 @@ SHLIBOBJS-$(CONFIG_FLV_MUXER)+= > mpeg4audio_sample_rates.o > SHLIBOBJS-$(CONFIG_HLS_DEMUXER) += ac3_channel_layout_tab.o > SHLIBOBJS-$(CONFIG_MATROSKA_DEMUXER) += mpeg4audio_sample_rates.o > SHLIBOBJS-$(CONFIG_MOV_DEMUXER) += ac3_channel_layout_tab.o > +SHLIBOBJS-$(CONFIG_MOV_MUXER)+= ac3_bitrate_tab.o > SHLIBOBJS-$(CONFIG_MP3_MUXER)+= mpegaudiotabs.o > SHLIBOBJS-$(CONFIG_MXF_MUXER)+= golomb_tab.o > SHLIBOBJS-$(CONFIG_NUT_MUXER)+= mpegaudiotabs.o The above line only takes care of duplicating ac3_bitrate_tab.o into lavf for shared builds; yet there needs to be a corresponding STLIBOBJS entry in lavc/Makefile so that lavc/ac3_bitrate_tab.o is compiled in case the mov muxer is enabled in a static build. It would work either way in this case because #2 made the mov muxer depend upon the ac3 parser which makes lavc/ac3_bitrate_tab.o be included. > diff --git a/libavformat/ac3_bitrate_tab.c b/libavformat/ac3_bitrate_tab.c > new file mode 100644 > index 00..57b6181511 > --- /dev/null > +++ b/libavformat/ac3_bitrate_tab.c > @@ -0,0 +1,22 @@ > +/* > + * AC-3 bit rate table > + * copyright (c) 2001 Fabrice Bellard > + * > + * This file is part of FFmpeg. > + * > + * FFmpeg is free software; you can redistribute it and/or > + * modify it under the terms of the GNU Lesser General Public > + * License as published by the Free Software Foundation; either > + * version 2.1 of the License, or (at your option) any later version. > + * > + * FFmpeg is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU > + * Lesser General Public License for more details. > + * > + * You should have received a copy of the GNU Lesser General Public > + * License along with FFmpeg; if not, write to the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 > USA > + */ > + > +#include "libavcodec/ac3_bitrate_tab.h" > diff --git a/libavformat/movenc.c b/libavformat/movenc.c > index 103f958d75..a071f1cdd5 100644 > --- a/libavformat/movenc.c > +++ b/libavformat/movenc.c > @@ -36,6 +36,7 @@ > #include "av1.h" > #include "avc.h" > #include "libavcodec/ac3_parser_internal.h" > +#include "libavcodec/ac3tab.h" > #include "libavcodec/dnxhddata.h" > #include "libavcodec/flac.h" > #include "libavcodec/get_bits.h" > @@ -362,44 +363,42 @@ struct eac3_info { > > static int mov_write_ac3_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack > *track) > { > -GetBitContext gbc; > +struct eac3_info *info = track->eac3_priv; > +int8_t ac3_bit_rate_code = -1; > PutBitContext pbc; > uint8_t buf[3]; > -int fscod, bsid, bsmod, acmod, lfeon, frmsizecod; > > -if (track->vos_len < 7) { > +if (!info || !info->ec3_done) { > av_log(s, AV_LOG_ERROR, > "Cannot write moov atom before AC3 packets." > " Set the delay_moov flag to fix this.\n"); > return AVERROR(EINVAL); > } > > -avio_wb32(pb, 11); > -ffio_wfourcc(pb, "dac3"); > +for (unsigned int i = 0; i < FF_ARRAY_ELEMS(ff_ac3_bitrate_tab); i++) { > +if (info->data_rate == ff_ac3_bitrate_tab[i]) { > +ac3_bit_rate_code = i; Anyway, I see that you use ff_ac3_bitrate_tab in lavf instead of adding the frame_size_code to AC3HeaderInfo. Did it turn out to be easier this way or what is the reason for this? > +break; > +} > +} > > -init_get_bits(&gbc, track->vos_data + 4, (track->vos_len - 4) * 8); > -fscod = get_bits(&gbc, 2); > -frmsizecod = get_bits(&gbc, 6); > -bsid = get_bits(&gbc, 5); > -bsmod = get_bits(&gbc, 3); > -acmod = get_bits(&gbc, 3); > -if (acmod == 2) { > -skip_bits(&gbc, 2); // dsurmod > -} else { > -if ((acmod & 1) && acmod != 1) > -skip_bits(&gbc, 2); // cmixlev > -if (acmod & 4) > -skip_bits(&gbc, 2); // surmixlev > +if (ac3_bit_rate_code < 0) { > +av_log(s, AV_LOG_ERROR, > + "No valid AC3 bit rate code for data rate of %d!\n", > + info->data_rate); > +return AVERROR(EINVAL); > } > -lfeon = get_bits1(&gbc); > + > +avio_wb32(pb, 11); > +ffio_wfourcc(pb, "dac3"); > > init_put_bits(&pbc, buf, sizeof(b
Re: [FFmpeg-devel] [PATCH] lavc/libx264.c: Fix possible UB by NULL pointer LHS
Am 16.06.22 um 22:01 schrieb Michael Niedermayer: On Thu, Jun 16, 2022 at 05:58:09PM +0200, Thilo Borgmann wrote: Hi, the LHS pointer might be NULL so that += would be UB. Thanks, Thilo libx264.c |4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 558de1ca7a30aa728193297a7d605c051b5bbfc0 0001-lavc-libx264.c-Fix-possible-UB-by-NULL-pointer-LHS.patch From cfb7ce8092c34436fae3120645aa96fe082af4ea Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 16 Jun 2022 17:52:56 +0200 Subject: [PATCH] lavc/libx264.c: Fix possible UB by NULL pointer LHS It is UB to attempt to do pointer arithmetic on NULL pointer LHS, even if that pointer arithmetic ends up being "+= 0" (i.e. !!p == 0 if p == NULL). --- libavcodec/libx264.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) should be ok Pushed, thanks! -Thilo ___ 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] tests/checkasm/sw_scale: Fix alignment for movdqa
Am 18.06.22 um 23:50 schrieb Martin Storsjö: On Thu, 16 Jun 2022, Thilo Borgmann wrote: Hi, movdqa in ff_yuv2yuvX_sse3() expects a 16-byte alignment according to its documentation causing segfaults in fate-checkasm-sw_scale. LGTM, thanks! Pushed, Thanks! -Thilo ___ 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/dovi_rpu: Fix UB for possible left shift of negative values
Am 16.06.22 um 13:19 schrieb Thilo Borgmann: Am 16.06.22 um 12:40 schrieb Andreas Rheinhardt: Thilo Borgmann: Am 16.06.22 um 12:13 schrieb Andreas Rheinhardt: Thilo Borgmann: diff --git a/libavcodec/dovi_rpu.c b/libavcodec/dovi_rpu.c index a87562c8a3..833ce9e705 100644 --- a/libavcodec/dovi_rpu.c +++ b/libavcodec/dovi_rpu.c @@ -153,7 +153,7 @@ static inline uint64_t get_ue_coef(GetBitContext *gb, const AVDOVIRpuDataHeader case RPU_COEFF_FIXED: ipart = get_ue_golomb_long(gb); fpart.u32 = get_bits_long(gb, hdr->coef_log2_denom); - return (ipart << hdr->coef_log2_denom) + fpart.u32; + return ipart * (1 << hdr->coef_log2_denom) + fpart.u32; case RPU_COEFF_FLOAT: fpart.u32 = get_bits_long(gb, 32); @@ -172,7 +172,7 @@ static inline int64_t get_se_coef(GetBitContext *gb, const AVDOVIRpuDataHeader * case RPU_COEFF_FIXED: ipart = get_se_golomb_long(gb); fpart.u32 = get_bits_long(gb, hdr->coef_log2_denom); - return (ipart << hdr->coef_log2_denom) + fpart.u32; + return ipart * (1 << hdr->coef_log2_denom) + fpart.u32; case RPU_COEFF_FLOAT: fpart.u32 = get_bits_long(gb, 32); coef_log2_denom can be in the range 13..32. This means that 1 << hdr->coef_log2_denom can be UB (namely if coef_log2_denom is 31 or 32 for ordinary 32 bit ints); this time it is not UB that happens to work as expected, because 1 << 32 will be 0 or 1 (depending upon the system) and not 2^32. In case of get_ue_coef() this actually adds UB to otherwise fine code. So 1LL it needs to be, not? Am I still missing something? This version should not add new UB. I btw don't get why you are changing get_ue_coef() at all: It's fine as-is; consistency should only trump when the choice is between several equally good alternatives which is IMO not true here. (The reason that C makes left shifts of negative values UB is because of non-two's complement systems, so it is unfortunate for a project like FFmpeg that requires two's complement that it has to workaround this restriction by using a * (1 << b).) Just overthinking consistency, I guess. v4 changes get_se_coef() only. Pushing soon if there are no more comments. Thanks, Thilo ___ 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 0/6 v2] avformat/movenc: normalize on AC-3 parser usage
On Fri, Jun 17, 2022 at 4:04 PM Jan Ekström wrote: > > The simplified parsing currently in `mov_write_ac3_tag` trusts the content > of the packets a bit too much (the AC-3 parser returns all data fed to it, > including any possible data before the start code), while the existing E-AC-3 > logic does proper header validation by utilizing the (E-)AC-3 parser. > > Thus, normalize on AC-3 parser usage for both AC-3 and E-AC-3. > > Difference to v1: > * Instead of expanding the avpriv parser interface, make the bit rate table > available to libavformat as well as libavcodec. This also theoretically > allows the calculation based on data rate, thus allowing the correct > bit rate to be signaled with bsids 9 and 10, which have their effective > bit rate and sample rate values divided by 2 and 4 respectively. > I will move towards pulling this patch set in tomorrow unless there are objections. The earlier version of this patch set has been successfully working in various locations, and the effective result from this version of the patch set seems to be the same. Jan ___ 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".