From 7cbc2e60af72e2154ddc160b1bfce200a95a6532 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 16 Jun 2011 07:24:14 +0200 Subject: [PATCH 001/109] codec-regression: remove pointless -r options for dnxhd --- tests/codec-regression.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/codec-regression.sh b/tests/codec-regression.sh index 335e1f70f7..a858250e2f 100755 --- a/tests/codec-regression.sh +++ b/tests/codec-regression.sh @@ -219,17 +219,17 @@ fi if [ -n "$do_dnxhd_1080i" ] ; then # FIXME: interlaced raw DNxHD decoding is broken do_video_encoding dnxhd-1080i.mov "-vcodec dnxhd -flags +ildct -s hd1080 -b 120M -pix_fmt yuv422p -vframes 5 -an" -do_video_decoding "-r 25" "-s cif -pix_fmt yuv420p" +do_video_decoding "" "-s cif -pix_fmt yuv420p" fi if [ -n "$do_dnxhd_720p" ] ; then do_video_encoding dnxhd-720p.dnxhd "-s hd720 -b 90M -pix_fmt yuv422p -vframes 5 -an" -do_video_decoding "-r 25" "-s cif -pix_fmt yuv420p" +do_video_decoding "" "-s cif -pix_fmt yuv420p" fi if [ -n "$do_dnxhd_720p_rd" ] ; then do_video_encoding dnxhd-720p-rd.dnxhd "-threads 4 -mbd rd -s hd720 -b 90M -pix_fmt yuv422p -vframes 5 -an" -do_video_decoding "-r 25" "-s cif -pix_fmt yuv420p" +do_video_decoding "" "-s cif -pix_fmt yuv420p" fi if [ -n "$do_svq1" ] ; then From 6095388812ce1b2a95e9917b89e5857639208f88 Mon Sep 17 00:00:00 2001 From: Kirill Zorin Date: Wed, 15 Jun 2011 19:18:29 +0200 Subject: [PATCH 002/109] mmsh: fixed printf injection bug in mmsh request MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/mmsh.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/mmsh.c b/libavformat/mmsh.c index b19973ea76..af040e27a9 100644 --- a/libavformat/mmsh.c +++ b/libavformat/mmsh.c @@ -231,7 +231,7 @@ static int mmsh_open(URLContext *h, const char *uri, int flags) host, sizeof(host), &port, path, sizeof(path), location); if (port<0) port = 80; // default mmsh protocol port - ff_url_join(httpname, sizeof(httpname), "http", NULL, host, port, path); + ff_url_join(httpname, sizeof(httpname), "http", NULL, host, port, "%s", path); if (ffurl_alloc(&mms->mms_hd, httpname, AVIO_FLAG_READ) < 0) { return AVERROR(EIO); From d840733937a3f00dcedbf20507077a4891173516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 16 Jun 2011 11:04:27 +0300 Subject: [PATCH 003/109] rtsp: Don't pass string pointer as format string to ff_url_join MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In this case, the string that was passed couldn't contain user-defined data and thus there was no risk for injection bugs, but it's safer this way, if we later change the content of the options string. Signed-off-by: Martin Storsjö --- libavformat/rtsp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index b2735f6165..eeea9be4a0 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -1234,10 +1234,10 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, if (reply->transports[0].source[0]) { ff_url_join(url, sizeof(url), "rtp", NULL, reply->transports[0].source, - reply->transports[0].server_port_min, options); + reply->transports[0].server_port_min, "%s", options); } else { ff_url_join(url, sizeof(url), "rtp", NULL, host, - reply->transports[0].server_port_min, options); + reply->transports[0].server_port_min, "%s", options); } if (!(rt->server_type == RTSP_SERVER_WMS && i > 1) && rtp_set_remote_url(rtsp_st->rtp_handle, url) < 0) { From 1d076f46a0db987e3cde0914277473f18f1ba03e Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 16 Jun 2011 17:04:06 +0200 Subject: [PATCH 004/109] rtpenc_latm: Consistently use "Libav" in license boilerplate. --- libavformat/rtpenc_latm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/rtpenc_latm.c b/libavformat/rtpenc_latm.c index aa6e29117f..64676771a7 100644 --- a/libavformat/rtpenc_latm.c +++ b/libavformat/rtpenc_latm.c @@ -9,13 +9,13 @@ * 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, + * Libav 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 + * License along with Libav; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ From 62940bb42f39b98c45105b036055dacdbe47a175 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 16 Jun 2011 06:24:54 +0200 Subject: [PATCH 005/109] ffmpeg: initialise encoders earlier. Fixes choosing supported samplerate and framerate. --- ffmpeg.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index 652fbfce32..5b1702edc7 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -2164,6 +2164,8 @@ static int transcode(AVFormatContext **output_files, abort(); } } else { + if (!ost->enc) + ost->enc = avcodec_find_encoder(ost->st->codec->codec_id); switch(codec->codec_type) { case AVMEDIA_TYPE_AUDIO: ost->fifo= av_fifo_alloc(1024); @@ -2175,7 +2177,7 @@ static int transcode(AVFormatContext **output_files, if (icodec->lowres) codec->sample_rate >>= icodec->lowres; } - choose_sample_rate(ost->st, codec->codec); + choose_sample_rate(ost->st, ost->enc); codec->time_base = (AVRational){1, codec->sample_rate}; if (!codec->channels) codec->channels = icodec->channels; @@ -2228,9 +2230,9 @@ static int transcode(AVFormatContext **output_files, if (!ost->frame_rate.num) ost->frame_rate = ist->st->r_frame_rate.num ? ist->st->r_frame_rate : (AVRational){25,1}; - if (codec->codec && codec->codec->supported_framerates && !force_fps) { - int idx = av_find_nearest_q_idx(ost->frame_rate, codec->codec->supported_framerates); - ost->frame_rate = codec->codec->supported_framerates[idx]; + if (ost->enc && ost->enc->supported_framerates && !force_fps) { + int idx = av_find_nearest_q_idx(ost->frame_rate, ost->enc->supported_framerates); + ost->frame_rate = ost->enc->supported_framerates[idx]; } codec->time_base = (AVRational){ost->frame_rate.den, ost->frame_rate.num}; @@ -2297,8 +2299,6 @@ static int transcode(AVFormatContext **output_files, if (ost->encoding_needed) { AVCodec *codec = ost->enc; AVCodecContext *dec = input_streams[ost->source_index].st->codec; - if (!codec) - codec = avcodec_find_encoder(ost->st->codec->codec_id); if (!codec) { snprintf(error, sizeof(error), "Encoder (codec id %d) not found for output stream #%d.%d", ost->st->codec->codec_id, ost->file_index, ost->index); From 9446d75941d639f19cfa9ae007eb4c5ca041f200 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 16 Jun 2011 18:04:56 +0200 Subject: [PATCH 006/109] ffmpeg: merge output_codecs array into AVOutputStream members. There's no point in keeping them separate. --- ffmpeg.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index 1b31d5655f..652fbfce32 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -113,9 +113,7 @@ static int nb_input_codecs = 0; static int nb_input_files_ts_scale[MAX_FILES] = {0}; static AVFormatContext *output_files[MAX_FILES]; -static AVCodec **output_codecs = NULL; static int nb_output_files = 0; -static int nb_output_codecs = 0; static AVStreamMap *stream_maps = NULL; static int nb_stream_maps; @@ -264,6 +262,8 @@ typedef struct AVOutputStream { struct AVInputStream *sync_ist; /* input stream to sync against */ int64_t sync_opts; /* output frame counter, could be changed to some true timestamp */ //FIXME look at frame_number AVBitStreamFilterContext *bitstream_filters; + AVCodec *enc; + /* video only */ int video_resample; AVFrame pict_tmp; /* temporary image for resampling */ @@ -480,7 +480,6 @@ static int ffmpeg_exit(int ret) av_free(streamid_map); av_free(input_codecs); - av_free(output_codecs); av_free(stream_maps); av_free(meta_data_maps); @@ -2296,7 +2295,7 @@ static int transcode(AVFormatContext **output_files, for(i=0;iencoding_needed) { - AVCodec *codec = i < nb_output_codecs ? output_codecs[i] : NULL; + AVCodec *codec = ost->enc; AVCodecContext *dec = input_streams[ost->source_index].st->codec; if (!codec) codec = avcodec_find_encoder(ost->st->codec->codec_id); @@ -3418,13 +3417,12 @@ static void new_video_stream(AVFormatContext *oc, int file_idx) } ost = new_output_stream(oc, file_idx); - output_codecs = grow_array(output_codecs, sizeof(*output_codecs), &nb_output_codecs, nb_output_codecs + 1); if(!video_stream_copy){ if (video_codec_name) { codec_id = find_codec_or_die(video_codec_name, AVMEDIA_TYPE_VIDEO, 1, avcodec_opts[AVMEDIA_TYPE_VIDEO]->strict_std_compliance); codec = avcodec_find_encoder_by_name(video_codec_name); - output_codecs[nb_output_codecs-1] = codec; + ost->enc = codec; } else { codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO); codec = avcodec_find_encoder(codec_id); @@ -3561,13 +3559,12 @@ static void new_audio_stream(AVFormatContext *oc, int file_idx) } ost = new_output_stream(oc, file_idx); - output_codecs = grow_array(output_codecs, sizeof(*output_codecs), &nb_output_codecs, nb_output_codecs + 1); if(!audio_stream_copy){ if (audio_codec_name) { codec_id = find_codec_or_die(audio_codec_name, AVMEDIA_TYPE_AUDIO, 1, avcodec_opts[AVMEDIA_TYPE_AUDIO]->strict_std_compliance); codec = avcodec_find_encoder_by_name(audio_codec_name); - output_codecs[nb_output_codecs-1] = codec; + ost->enc = codec; } else { codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_AUDIO); codec = avcodec_find_encoder(codec_id); @@ -3633,7 +3630,6 @@ static void new_data_stream(AVFormatContext *oc, int file_idx) } new_output_stream(oc, file_idx); data_enc = st->codec; - output_codecs = grow_array(output_codecs, sizeof(*output_codecs), &nb_output_codecs, nb_output_codecs + 1); if (!data_stream_copy) { fprintf(stderr, "Data stream encoding not supported yet (only streamcopy)\n"); ffmpeg_exit(1); @@ -3673,12 +3669,12 @@ static void new_subtitle_stream(AVFormatContext *oc, int file_idx) } ost = new_output_stream(oc, file_idx); subtitle_enc = st->codec; - output_codecs = grow_array(output_codecs, sizeof(*output_codecs), &nb_output_codecs, nb_output_codecs + 1); if(!subtitle_stream_copy){ if (subtitle_codec_name) { codec_id = find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 1, avcodec_opts[AVMEDIA_TYPE_SUBTITLE]->strict_std_compliance); - codec= output_codecs[nb_output_codecs-1] = avcodec_find_encoder_by_name(subtitle_codec_name); + codec = avcodec_find_encoder_by_name(subtitle_codec_name); + ost->enc = codec; } else { codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_SUBTITLE); codec = avcodec_find_encoder(codec_id); From 6ec2fd5f77d5c5a3d569978cc6f099af15d25fba Mon Sep 17 00:00:00 2001 From: Kirill Zorin Date: Thu, 16 Jun 2011 20:15:53 +0200 Subject: [PATCH 007/109] mmsh: fix 400 bad request There is no need to write two HTTP newlines (\r\n) into "headers", because http_connect (in http.c) already appends one HTTP newline at the end of the given headers chunk, which would result in sending three HTTP newlines after the headers. Most of the time it's okay (although not RFC-conforming), but many proxy servers and the occasional strict httpd will puke with a "400 bad request". --- libavformat/mmsh.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/mmsh.c b/libavformat/mmsh.c index 64760e8555..a66e1d9ab2 100644 --- a/libavformat/mmsh.c +++ b/libavformat/mmsh.c @@ -244,7 +244,7 @@ static int mmsh_open(URLContext *h, const char *uri, int flags) "Pragma: no-cache,rate=1.000000,stream-time=0," "stream-offset=0:0,request-context=%u,max-duration=0\r\n" CLIENTGUID - "Connection: Close\r\n\r\n", + "Connection: Close\r\n", host, port, mmsh->request_seq++); ff_http_set_headers(mms->mms_hd, headers); @@ -284,7 +284,7 @@ static int mmsh_open(URLContext *h, const char *uri, int flags) CLIENTGUID "Pragma: stream-switch-count=%d\r\n" "Pragma: stream-switch-entry=%s\r\n" - "Connection: Close\r\n\r\n", + "Connection: Close\r\n", host, port, mmsh->request_seq++, mms->stream_num, stream_selection); av_freep(&stream_selection); if (err < 0) { From 10de86b882f980a7e856a903bcb45a8fa7816cfd Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 15 Jun 2011 08:00:03 +0200 Subject: [PATCH 008/109] ffmpeg: don't abuse a global for passing pixel format from input to output It's broken with multiple files or video streams. --- ffmpeg.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index 5b1702edc7..952707d9eb 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -2192,6 +2192,10 @@ static int transcode(AVFormatContext **output_files, ost->resample_channels = icodec->channels; break; case AVMEDIA_TYPE_VIDEO: + if (codec->pix_fmt == PIX_FMT_NONE) + codec->pix_fmt = icodec->pix_fmt; + choose_pixel_fmt(ost->st, ost->enc); + if (ost->st->codec->pix_fmt == PIX_FMT_NONE) { fprintf(stderr, "Video pixel format is unknown, stream cannot be encoded\n"); ffmpeg_exit(1); @@ -3295,7 +3299,6 @@ static int opt_input_file(const char *opt, const char *filename) set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM, input_codecs[nb_input_codecs-1]); frame_height = dec->height; frame_width = dec->width; - frame_pix_fmt = dec->pix_fmt; rfps = ic->streams[i]->r_frame_rate.num; rfps_base = ic->streams[i]->r_frame_rate.den; if (dec->lowres) { @@ -3348,6 +3351,7 @@ static int opt_input_file(const char *opt, const char *filename) video_channel = 0; frame_rate = (AVRational){0, 0}; + frame_pix_fmt = PIX_FMT_NONE; audio_sample_rate = 0; audio_channels = 0; @@ -3471,8 +3475,6 @@ static void new_video_stream(AVFormatContext *oc, int file_idx) video_enc->pix_fmt = frame_pix_fmt; st->sample_aspect_ratio = video_enc->sample_aspect_ratio; - choose_pixel_fmt(st, codec); - if (intra_only) video_enc->gop_size = 0; if (video_qscale || same_quality) { From 0b7ccad6bf79cebe5cd8392105276a4ba19d19f9 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 15 Jun 2011 08:00:03 +0200 Subject: [PATCH 009/109] ffmpeg: don't abuse a global for passing frame size from input to output It's broken with multiple files or video streams. --- ffmpeg.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index 952707d9eb..6a4fb5358f 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -2226,6 +2226,10 @@ static int transcode(AVFormatContext **output_files, #endif codec->bits_per_raw_sample= 0; } + if (!codec->width || !codec->height) { + codec->width = icodec->width; + codec->height = icodec->height; + } ost->resample_height = icodec->height; ost->resample_width = icodec->width; ost->resample_pix_fmt= icodec->pix_fmt; @@ -3297,16 +3301,12 @@ static int opt_input_file(const char *opt, const char *filename) case AVMEDIA_TYPE_VIDEO: input_codecs[nb_input_codecs-1] = avcodec_find_decoder_by_name(video_codec_name); set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM, input_codecs[nb_input_codecs-1]); - frame_height = dec->height; - frame_width = dec->width; rfps = ic->streams[i]->r_frame_rate.num; rfps_base = ic->streams[i]->r_frame_rate.den; if (dec->lowres) { dec->flags |= CODEC_FLAG_EMU_EDGE; - frame_height >>= dec->lowres; - frame_width >>= dec->lowres; - dec->height = frame_height; - dec->width = frame_width; + dec->height >>= dec->lowres; + dec->width >>= dec->lowres; } if(me_threshold) dec->debug |= FF_DEBUG_MV; @@ -3352,6 +3352,8 @@ static int opt_input_file(const char *opt, const char *filename) video_channel = 0; frame_rate = (AVRational){0, 0}; frame_pix_fmt = PIX_FMT_NONE; + frame_height = 0; + frame_width = 0; audio_sample_rate = 0; audio_channels = 0; @@ -3893,6 +3895,8 @@ static void opt_output_file(const char *filename) set_context_opts(oc, avformat_opts, AV_OPT_FLAG_ENCODING_PARAM, NULL); frame_rate = (AVRational){0, 0}; + frame_width = 0; + frame_height = 0; audio_sample_rate = 0; audio_channels = 0; From 7e83e1c511baf0d02f3af75b6180d6af4d50aa99 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 22 May 2011 12:52:50 +0200 Subject: [PATCH 010/109] AVOptions: add av_opt_set_dict() mapping a dictionary struct to a context. This way the caller can pass all the options in one nice package. --- libavutil/opt.c | 22 ++++++++++++++++++++++ libavutil/opt.h | 17 +++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/libavutil/opt.c b/libavutil/opt.c index 7775bb2af3..55bb6d24f0 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -29,6 +29,7 @@ #include "avstring.h" #include "opt.h" #include "eval.h" +#include "dict.h" //FIXME order them and do a bin search const AVOption *av_find_opt(void *v, const char *name, const char *unit, int mask, int flags) @@ -538,6 +539,27 @@ void av_opt_free(void *obj) av_freep((uint8_t *)obj + o->offset); } +int av_opt_set_dict(void *obj, AVDictionary **options) +{ + AVDictionaryEntry *t = NULL; + AVDictionary *tmp = NULL; + int ret = 0; + + while ((t = av_dict_get(*options, "", t, AV_DICT_IGNORE_SUFFIX))) { + ret = av_set_string3(obj, t->key, t->value, 1, NULL); + if (ret == AVERROR_OPTION_NOT_FOUND) + av_dict_set(&tmp, t->key, t->value, 0); + else if (ret < 0) { + av_log(obj, AV_LOG_ERROR, "Error setting option %s to value %s.\n", t->key, t->value); + break; + } + ret = 0; + } + av_dict_free(options); + *options = tmp; + return ret; +} + #ifdef TEST #undef printf diff --git a/libavutil/opt.h b/libavutil/opt.h index 46ad8acce1..ef984d9a9c 100644 --- a/libavutil/opt.h +++ b/libavutil/opt.h @@ -29,6 +29,7 @@ #include "rational.h" #include "avutil.h" +#include "dict.h" enum AVOptionType{ FF_OPT_TYPE_FLAGS, @@ -191,4 +192,20 @@ void av_opt_free(void *obj); */ int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name); +/* + * Set all the options from a given dictionary on an object. + * + * @param obj a struct whose first element is a pointer to AVClass + * @param options options to process. This dictionary will be freed and replaced + * by a new one containing all options not found in obj. + * Of course this new dictionary needs to be freed by caller + * with av_dict_free(). + * + * @return 0 on success, a negative AVERROR if some option was found in obj, + * but could not be set. + * + * @see av_dict_copy() + */ +int av_opt_set_dict(void *obj, struct AVDictionary **options); + #endif /* AVUTIL_OPT_H */ From dc59ec5e79d813228e3dfbc8942a5fe424b399a0 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 22 May 2011 13:25:19 +0200 Subject: [PATCH 011/109] AVOptions: add av_opt_find() as a replacement for av_find_opt. --- cmdutils.c | 6 +++--- ffserver.c | 2 +- libavutil/avutil.h | 3 +++ libavutil/log.h | 7 +++++++ libavutil/opt.c | 30 +++++++++++++++++++++++++----- libavutil/opt.h | 31 +++++++++++++++++++++++++++++++ 6 files changed, 70 insertions(+), 9 deletions(-) diff --git a/cmdutils.c b/cmdutils.c index c73d5a1ca2..9422fc1f03 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -299,7 +299,7 @@ int opt_default(const char *opt, const char *arg){ int opt_types[]={AV_OPT_FLAG_VIDEO_PARAM, AV_OPT_FLAG_AUDIO_PARAM, 0, AV_OPT_FLAG_SUBTITLE_PARAM, 0}; for(type=0; *avcodec_opts && type= 0; type++){ - const AVOption *o2 = av_find_opt(avcodec_opts[0], opt, NULL, opt_types[type], opt_types[type]); + const AVOption *o2 = av_opt_find(avcodec_opts[0], opt, NULL, opt_types[type], 0); if(o2) ret = av_set_string3(avcodec_opts[type], opt, arg, 1, &o); } @@ -324,13 +324,13 @@ int opt_default(const char *opt, const char *arg){ AVOutputFormat *oformat = NULL; while ((p=av_codec_next(p))){ const AVClass *c = p->priv_class; - if(c && av_find_opt(&c, opt, NULL, 0, 0)) + if(c && av_opt_find(&c, opt, NULL, 0, 0)) break; } if (!p) { while ((oformat = av_oformat_next(oformat))) { const AVClass *c = oformat->priv_class; - if (c && av_find_opt(&c, opt, NULL, 0, 0)) + if (c && av_opt_find(&c, opt, NULL, 0, 0)) break; } } diff --git a/ffserver.c b/ffserver.c index 0f57979c9c..2ac7e6abf9 100644 --- a/ffserver.c +++ b/ffserver.c @@ -3944,7 +3944,7 @@ static int ffserver_opt_default(const char *opt, const char *arg, AVCodecContext *avctx, int type) { int ret = 0; - const AVOption *o = av_find_opt(avctx, opt, NULL, type, type); + const AVOption *o = av_opt_find(avctx, opt, NULL, type, 0); if(o) ret = av_set_string3(avctx, opt, arg, 1, NULL); return ret; diff --git a/libavutil/avutil.h b/libavutil/avutil.h index 0299bdf797..21df460c1f 100644 --- a/libavutil/avutil.h +++ b/libavutil/avutil.h @@ -60,6 +60,9 @@ #ifndef FF_API_GET_BITS_PER_SAMPLE_FMT #define FF_API_GET_BITS_PER_SAMPLE_FMT (LIBAVUTIL_VERSION_MAJOR < 52) #endif +#ifndef FF_API_FIND_OPT +#define FF_API_FIND_OPT (LIBAVUTIL_VERSION_MAJOR < 52) +#endif /** * Return the LIBAVUTIL_VERSION_INT constant. diff --git a/libavutil/log.h b/libavutil/log.h index 1cd9269c43..c823a763ee 100644 --- a/libavutil/log.h +++ b/libavutil/log.h @@ -70,6 +70,13 @@ typedef struct { * can be NULL of course */ int parent_log_context_offset; + + /** + * A function for extended searching, e.g. in possible + * children objects. + */ + const struct AVOption* (*opt_find)(void *obj, const char *name, const char *unit, + int opt_flags, int search_flags); } AVClass; /* av_log API */ diff --git a/libavutil/opt.c b/libavutil/opt.c index 55bb6d24f0..518863a8b8 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -31,6 +31,7 @@ #include "eval.h" #include "dict.h" +#if FF_API_FIND_OPT //FIXME order them and do a bin search const AVOption *av_find_opt(void *v, const char *name, const char *unit, int mask, int flags) { @@ -43,6 +44,7 @@ const AVOption *av_find_opt(void *v, const char *name, const char *unit, int mas } return NULL; } +#endif const AVOption *av_next_option(void *obj, const AVOption *last) { @@ -53,7 +55,7 @@ const AVOption *av_next_option(void *obj, const AVOption *last) static int av_set_number2(void *obj, const char *name, double num, int den, int64_t intnum, const AVOption **o_out) { - const AVOption *o= av_find_opt(obj, name, NULL, 0, 0); + const AVOption *o = av_opt_find(obj, name, NULL, 0, 0); void *dst; if (o_out) *o_out= o; @@ -116,7 +118,7 @@ static int hexchar2int(char c) { int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out) { int ret; - const AVOption *o= av_find_opt(obj, name, NULL, 0, 0); + const AVOption *o = av_opt_find(obj, name, NULL, 0, 0); if (o_out) *o_out = o; if (!o) @@ -163,7 +165,7 @@ int av_set_string3(void *obj, const char *name, const char *val, int alloc, cons buf[i]=0; { - const AVOption *o_named= av_find_opt(obj, buf, o->unit, 0, 0); + const AVOption *o_named = av_opt_find(obj, buf, o->unit, 0, 0); if (o_named && o_named->type == FF_OPT_TYPE_CONST) d= o_named->default_val.dbl; else if (!strcmp(buf, "default")) d= o->default_val.dbl; @@ -228,7 +230,7 @@ const AVOption *av_set_int(void *obj, const char *name, int64_t n) */ const char *av_get_string(void *obj, const char *name, const AVOption **o_out, char *buf, int buf_len) { - const AVOption *o= av_find_opt(obj, name, NULL, 0, 0); + const AVOption *o = av_opt_find(obj, name, NULL, 0, 0); void *dst; uint8_t *bin; int len, i; @@ -261,7 +263,7 @@ const char *av_get_string(void *obj, const char *name, const AVOption **o_out, c static int av_get_number(void *obj, const char *name, const AVOption **o_out, double *num, int *den, int64_t *intnum) { - const AVOption *o= av_find_opt(obj, name, NULL, 0, 0); + const AVOption *o = av_opt_find(obj, name, NULL, 0, 0); void *dst; if (!o || o->offset<=0) goto error; @@ -560,6 +562,24 @@ int av_opt_set_dict(void *obj, AVDictionary **options) return ret; } +const AVOption *av_opt_find(void *obj, const char *name, const char *unit, + int opt_flags, int search_flags) +{ + AVClass *c = *(AVClass**)obj; + const AVOption *o = NULL; + + if (c->opt_find && search_flags & AV_OPT_SEARCH_CHILDREN && + (o = c->opt_find(obj, name, unit, opt_flags, search_flags))) + return o; + + while (o = av_next_option(obj, o)) { + if (!strcmp(o->name, name) && (!unit || (o->unit && !strcmp(o->unit, unit))) && + (o->flags & opt_flags) == opt_flags) + return o; + } + return NULL; +} + #ifdef TEST #undef printf diff --git a/libavutil/opt.h b/libavutil/opt.h index ef984d9a9c..30aa54f5b6 100644 --- a/libavutil/opt.h +++ b/libavutil/opt.h @@ -92,6 +92,7 @@ typedef struct AVOption { const char *unit; } AVOption; +#if FF_API_FIND_OPT /** * Look for an option in obj. Look only for the options which * have the flags set as specified in mask and flags (that is, @@ -103,8 +104,12 @@ typedef struct AVOption { * @param[in] unit the unit of the option to look for, or any if NULL * @return a pointer to the option found, or NULL if no option * has been found + * + * @deprecated use av_opt_find. */ +attribute_deprecated const AVOption *av_find_opt(void *obj, const char *name, const char *unit, int mask, int flags); +#endif /** * Set the field of obj with the given name to value. @@ -208,4 +213,30 @@ int av_opt_flag_is_set(void *obj, const char *field_name, const char *flag_name) */ int av_opt_set_dict(void *obj, struct AVDictionary **options); +#define AV_OPT_SEARCH_CHILDREN 0x0001 /**< Search in possible children of the + given object first. */ + +/** + * Look for an option in an object. Consider only options which + * have all the specified flags set. + * + * @param[in] obj A pointer to a struct whose first element is a + * pointer to an AVClass. + * @param[in] name The name of the option to look for. + * @param[in] unit When searching for named constants, name of the unit + * it belongs to. + * @param opt_flags Find only options with all the specified flags set (AV_OPT_FLAG). + * @param search_flags A combination of AV_OPT_SEARCH_*. + * + * @return A pointer to the option found, or NULL if no option + * was found. + * + * @note Options found with AV_OPT_SEARCH_CHILDREN flag may not be settable + * directly with av_set_string3(). Use special calls which take an options + * AVDictionary (e.g. avformat_open_input()) to set options found with this + * flag. + */ +const AVOption *av_opt_find(void *obj, const char *name, const char *unit, + int opt_flags, int search_flags); + #endif /* AVUTIL_OPT_H */ From 05e84c95c7f0543553af8f0ebd50fb5604e7e2ff Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 22 May 2011 08:37:25 +0200 Subject: [PATCH 012/109] lavf: add avformat_open_input() as a replacement for av_open_input_* Add support for demuxer private options. --- libavformat/avformat.h | 22 +++++++++ libavformat/options.c | 28 +++++++++++ libavformat/utils.c | 104 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 153 insertions(+), 1 deletion(-) diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 2b5b50e381..56a9d57a66 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -730,6 +730,7 @@ typedef struct AVFormatContext { #if FF_API_FLAG_RTP_HINT #define AVFMT_FLAG_RTP_HINT 0x0040 ///< Deprecated, use the -movflags rtphint muxer specific AVOption instead #endif +#define AVFMT_FLAG_CUSTOM_IO 0x0080 ///< The caller has supplied a custom AVIOContext, don't avio_close() it. int loop_input; @@ -1040,6 +1041,27 @@ int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, int buf_size, AVFormatParameters *ap); +/** + * Open an input stream and read the header. The codecs are not opened. + * The stream must be closed with av_close_input_file(). + * + * @param ps Pointer to user-supplied AVFormatContext (allocated by avformat_alloc_context). + * May be a pointer to NULL, in which case an AVFormatContext is allocated by this + * function and written into ps. + * Note that a user-supplied AVFormatContext will be freed on failure. + * @param filename Name of the stream to open. + * @param fmt If non-NULL, this parameter forces a specific input format. + * Otherwise the format is autodetected. + * @param options A dictionary filled with AVFormatContext and demuxer-private options. + * On return this parameter will be destroyed and replaced with a dict containing + * options that were not found. May be NULL. + * + * @return 0 on success, a negative AVERROR on failure. + * + * @note If you want to use custom IO, preallocate the format context and set its pb field. + */ +int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options); + /** * Allocate an AVFormatContext. * avformat_free_context() can be used to free the context and everything diff --git a/libavformat/options.c b/libavformat/options.c index c11f19e687..c2729b75d9 100644 --- a/libavformat/options.c +++ b/libavformat/options.c @@ -33,6 +33,33 @@ static const char* format_to_name(void* ptr) else return "NULL"; } +static const AVOption *opt_find(void *obj, const char *name, const char *unit, int opt_flags, int search_flags) +{ + AVFormatContext *s = obj; + AVInputFormat *ifmt = NULL; + AVOutputFormat *ofmt = NULL; + if (s->priv_data) { + if ((s->iformat && !s->iformat->priv_class) || + (s->oformat && !s->oformat->priv_class)) + return NULL; + return av_opt_find(s->priv_data, name, unit, opt_flags, search_flags); + } + + while ((ifmt = av_iformat_next(ifmt))) { + const AVOption *o; + + if (ifmt->priv_class && (o = av_opt_find(&ifmt->priv_class, name, unit, opt_flags, search_flags))) + return o; + } + while ((ofmt = av_oformat_next(ofmt))) { + const AVOption *o; + + if (ofmt->priv_class && (o = av_opt_find(&ofmt->priv_class, name, unit, opt_flags, search_flags))) + return o; + } + return NULL; +} + #define OFFSET(x) offsetof(AVFormatContext,x) #define DEFAULT 0 //should be NAN but it does not work as it is not a constant in glibc as required by ANSI/ISO C //these names are too long to be readable @@ -72,6 +99,7 @@ static const AVClass av_format_context_class = { .item_name = format_to_name, .option = options, .version = LIBAVUTIL_VERSION_INT, + .opt_find = opt_find, }; static void avformat_get_context_defaults(AVFormatContext *s) diff --git a/libavformat/utils.c b/libavformat/utils.c index 60f4d03e4b..31cdde3edb 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -605,6 +605,107 @@ int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, } +/* open input file and probe the format if necessary */ +static int init_input(AVFormatContext *s, const char *filename) +{ + int ret; + AVProbeData pd = {filename, NULL, 0}; + + if (s->pb) { + s->flags |= AVFMT_FLAG_CUSTOM_IO; + if (!s->iformat) + return av_probe_input_buffer(s->pb, &s->iformat, filename, s, 0, 0); + else if (s->iformat->flags & AVFMT_NOFILE) + return AVERROR(EINVAL); + return 0; + } + + if ( (s->iformat && s->iformat->flags & AVFMT_NOFILE) || + (!s->iformat && (s->iformat = av_probe_input_format(&pd, 0)))) + return 0; + + if ((ret = avio_open(&s->pb, filename, AVIO_FLAG_READ)) < 0) + return ret; + if (s->iformat) + return 0; + return av_probe_input_buffer(s->pb, &s->iformat, filename, s, 0, 0); +} + +int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options) +{ + AVFormatContext *s = *ps; + int ret = 0; + AVFormatParameters ap = { 0 }; + AVDictionary *tmp = NULL; + + if (!s && !(s = avformat_alloc_context())) + return AVERROR(ENOMEM); + if (fmt) + s->iformat = fmt; + + if (options) + av_dict_copy(&tmp, *options, 0); + + if ((ret = av_opt_set_dict(s, &tmp)) < 0) + goto fail; + + if ((ret = init_input(s, filename)) < 0) + goto fail; + + /* check filename in case an image number is expected */ + if (s->iformat->flags & AVFMT_NEEDNUMBER) { + if (!av_filename_number_test(filename)) { + ret = AVERROR(EINVAL); + goto fail; + } + } + + s->duration = s->start_time = AV_NOPTS_VALUE; + av_strlcpy(s->filename, filename, sizeof(s->filename)); + + /* allocate private data */ + if (s->iformat->priv_data_size > 0) { + if (!(s->priv_data = av_mallocz(s->iformat->priv_data_size))) { + ret = AVERROR(ENOMEM); + goto fail; + } + if (s->iformat->priv_class) { + *(const AVClass**)s->priv_data = s->iformat->priv_class; + av_opt_set_defaults(s->priv_data); + if ((ret = av_opt_set_dict(s->priv_data, &tmp)) < 0) + goto fail; + } + } + + /* e.g. AVFMT_NOFILE formats will not have a AVIOContext */ + if (s->pb) + ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC); + + if (s->iformat->read_header) + if ((ret = s->iformat->read_header(s, &ap)) < 0) + goto fail; + + if (s->pb && !s->data_offset) + s->data_offset = avio_tell(s->pb); + + s->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE; + + if (options) { + av_dict_free(options); + *options = tmp; + } + *ps = s; + return 0; + +fail: + av_dict_free(&tmp); + if (s->pb && !(s->flags & AVFMT_FLAG_CUSTOM_IO)) + avio_close(s->pb); + avformat_free_context(s); + *ps = NULL; + return ret; +} + /*******************************************************/ static AVPacket *add_to_pktbuf(AVPacketList **packet_buffer, AVPacket *pkt, @@ -2573,7 +2674,8 @@ void avformat_free_context(AVFormatContext *s) void av_close_input_file(AVFormatContext *s) { - AVIOContext *pb = s->iformat->flags & AVFMT_NOFILE ? NULL : s->pb; + AVIOContext *pb = (s->iformat->flags & AVFMT_NOFILE) || (s->flags & AVFMT_FLAG_CUSTOM_IO) ? + NULL : s->pb; av_close_input_stream(s); if (pb) avio_close(pb); From 603b8bc2a109978c8499b06d2556f1433306eca7 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 4 Jun 2011 17:36:30 +0200 Subject: [PATCH 013/109] Deprecate av_open_input_* and remove their uses. Deprecate the last remaining member of AVFormatParameters. --- libavfilter/vsrc_movie.c | 4 +- libavformat/applehttp.c | 9 ++- libavformat/avformat.h | 11 ++- libavformat/avidec.c | 8 +- libavformat/rdt.c | 4 +- libavformat/rtpdec_asf.c | 7 +- libavformat/sapdec.c | 7 +- libavformat/utils.c | 159 ++++++++++++++------------------------- 8 files changed, 88 insertions(+), 121 deletions(-) diff --git a/libavfilter/vsrc_movie.c b/libavfilter/vsrc_movie.c index a26787d561..7556fa2e9e 100644 --- a/libavfilter/vsrc_movie.c +++ b/libavfilter/vsrc_movie.c @@ -91,9 +91,9 @@ static int movie_init(AVFilterContext *ctx) iformat = movie->format_name ? av_find_input_format(movie->format_name) : NULL; movie->format_ctx = NULL; - if ((ret = av_open_input_file(&movie->format_ctx, movie->file_name, iformat, 0, NULL)) < 0) { + if ((ret = avformat_open_input(&movie->format_ctx, movie->file_name, iformat, NULL)) < 0) { av_log(ctx, AV_LOG_ERROR, - "Failed to av_open_input_file '%s'\n", movie->file_name); + "Failed to avformat_open_input '%s'\n", movie->file_name); return ret; } if ((ret = av_find_stream_info(movie->format_ctx)) < 0) diff --git a/libavformat/applehttp.c b/libavformat/applehttp.c index 86e8b5fbce..38f33a24f3 100644 --- a/libavformat/applehttp.c +++ b/libavformat/applehttp.c @@ -473,6 +473,11 @@ static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap) if (v->n_segments == 0) continue; + if (!(v->ctx = avformat_alloc_context())) { + ret = AVERROR(ENOMEM); + goto fail; + } + v->index = i; v->needed = 1; v->parent = s; @@ -491,8 +496,8 @@ static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap) NULL, 0, 0); if (ret < 0) goto fail; - ret = av_open_input_stream(&v->ctx, &v->pb, v->segments[0]->url, - in_fmt, NULL); + v->ctx->pb = &v->pb; + ret = avformat_open_input(&v->ctx, v->segments[0]->url, in_fmt, NULL); if (ret < 0) goto fail; v->stream_offset = stream_offset; diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 56a9d57a66..6c5b9c6e56 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -247,8 +247,8 @@ typedef struct AVFormatParameters { attribute_deprecated unsigned int mpeg2ts_compute_pcr:1; attribute_deprecated unsigned int initial_pause:1; /**< Do not begin to play the stream immediately (RTSP only). */ + attribute_deprecated unsigned int prealloced_context:1; #endif - unsigned int prealloced_context:1; } AVFormatParameters; //! Demuxer will use avio_open, no opened file should be provided by the caller. @@ -1016,11 +1016,13 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt, const char *filename, void *logctx, unsigned int offset, unsigned int max_probe_size); +#if FF_API_FORMAT_PARAMETERS /** * Allocate all the structures needed to read an input stream. * This does not open the needed codecs for decoding the stream[s]. + * @deprecated use avformat_open_input instead. */ -int av_open_input_stream(AVFormatContext **ic_ptr, +attribute_deprecated int av_open_input_stream(AVFormatContext **ic_ptr, AVIOContext *pb, const char *filename, AVInputFormat *fmt, AVFormatParameters *ap); @@ -1035,11 +1037,14 @@ int av_open_input_stream(AVFormatContext **ic_ptr, * @param ap Additional parameters needed when opening the file * (NULL if default). * @return 0 if OK, AVERROR_xxx otherwise + * + * @deprecated use avformat_open_input instead. */ -int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, +attribute_deprecated int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, AVInputFormat *fmt, int buf_size, AVFormatParameters *ap); +#endif /** * Open an input stream and read the header. The codecs are not opened. diff --git a/libavformat/avidec.c b/libavformat/avidec.c index dacd230613..85fc794362 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -774,7 +774,11 @@ static int read_gab2_sub(AVStream *st, AVPacket *pkt) { if (!(sub_demuxer = av_probe_input_format2(&pd, 1, &score))) goto error; - if (!av_open_input_stream(&ast->sub_ctx, pb, "", sub_demuxer, NULL)) { + if (!(ast->sub_ctx = avformat_alloc_context())) + goto error; + + ast->sub_ctx->pb = pb; + if (!avformat_open_input(&ast->sub_ctx, "", sub_demuxer, NULL)) { av_read_packet(ast->sub_ctx, &ast->sub_pkt); *st->codec = *ast->sub_ctx->streams[0]->codec; ast->sub_ctx->streams[0]->codec->extradata = NULL; @@ -1334,7 +1338,7 @@ static int avi_read_close(AVFormatContext *s) if (ast) { if (ast->sub_ctx) { av_freep(&ast->sub_ctx->pb); - av_close_input_stream(ast->sub_ctx); + av_close_input_file(ast->sub_ctx); } av_free(ast->sub_buffer); av_free_packet(&ast->sub_pkt); diff --git a/libavformat/rdt.c b/libavformat/rdt.c index bc3c17bd0d..9155cfc480 100644 --- a/libavformat/rdt.c +++ b/libavformat/rdt.c @@ -523,7 +523,7 @@ rdt_new_context (void) { PayloadContext *rdt = av_mallocz(sizeof(PayloadContext)); - av_open_input_stream(&rdt->rmctx, NULL, "", &ff_rdt_demuxer, NULL); + avformat_open_input(&rdt->rmctx, "", &ff_rdt_demuxer, NULL); return rdt; } @@ -539,7 +539,7 @@ rdt_free_context (PayloadContext *rdt) av_freep(&rdt->rmst[i]); } if (rdt->rmctx) - av_close_input_stream(rdt->rmctx); + av_close_input_file(rdt->rmctx); av_freep(&rdt->mlti_data); av_freep(&rdt->rmst); av_free(rdt); diff --git a/libavformat/rtpdec_asf.c b/libavformat/rtpdec_asf.c index ef78426f1f..287025f377 100644 --- a/libavformat/rtpdec_asf.c +++ b/libavformat/rtpdec_asf.c @@ -107,10 +107,13 @@ int ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p) "Failed to fix invalid RTSP-MS/ASF min_pktsize\n"); init_packetizer(&pb, buf, len); if (rt->asf_ctx) { - av_close_input_stream(rt->asf_ctx); + av_close_input_file(rt->asf_ctx); rt->asf_ctx = NULL; } - ret = av_open_input_stream(&rt->asf_ctx, &pb, "", &ff_asf_demuxer, NULL); + if (!(rt->asf_ctx = avformat_alloc_context())) + return AVERROR(ENOMEM); + rt->asf_ctx->pb = &pb; + ret = avformat_open_input(&rt->asf_ctx, "", &ff_asf_demuxer, NULL); if (ret < 0) return ret; av_dict_copy(&s->metadata, rt->asf_ctx->metadata, 0); diff --git a/libavformat/sapdec.c b/libavformat/sapdec.c index 88150fc772..15d772c780 100644 --- a/libavformat/sapdec.c +++ b/libavformat/sapdec.c @@ -52,7 +52,7 @@ static int sap_read_close(AVFormatContext *s) { struct SAPState *sap = s->priv_data; if (sap->sdp_ctx) - av_close_input_stream(sap->sdp_ctx); + av_close_input_file(sap->sdp_ctx); if (sap->ann_fd) ffurl_close(sap->ann_fd); av_freep(&sap->sdp); @@ -156,9 +156,8 @@ static int sap_read_header(AVFormatContext *s, goto fail; } sap->sdp_ctx->max_delay = s->max_delay; - ap->prealloced_context = 1; - ret = av_open_input_stream(&sap->sdp_ctx, &sap->sdp_pb, "temp.sdp", - infmt, ap); + sap->sdp_ctx->pb = &sap->sdp_pb; + ret = avformat_open_input(&sap->sdp_ctx, "temp.sdp", infmt, NULL); if (ret < 0) goto fail; if (sap->sdp_ctx->ctx_flags & AVFMTCTX_NOHEADER) diff --git a/libavformat/utils.c b/libavformat/utils.c index 31cdde3edb..5865495954 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -27,6 +27,7 @@ #include "libavcodec/internal.h" #include "libavutil/opt.h" #include "libavutil/dict.h" +#include "libavutil/pixdesc.h" #include "metadata.h" #include "id3v2.h" #include "libavutil/avstring.h" @@ -388,6 +389,47 @@ static int set_codec_from_probe_data(AVFormatContext *s, AVStream *st, AVProbeDa /************************************************************/ /* input media file */ +#if FF_API_FORMAT_PARAMETERS +static AVDictionary *convert_format_parameters(AVFormatParameters *ap) +{ + char buf[1024]; + AVDictionary *opts = NULL; + + if (ap->time_base.num) { + snprintf(buf, sizeof(buf), "%d/%d", ap->time_base.den, ap->time_base.num); + av_dict_set(&opts, "framerate", buf, 0); + } + if (ap->sample_rate) { + snprintf(buf, sizeof(buf), "%d", ap->sample_rate); + av_dict_set(&opts, "sample_rate", buf, 0); + } + if (ap->channels) { + snprintf(buf, sizeof(buf), "%d", ap->channels); + av_dict_set(&opts, "channels", buf, 0); + } + if (ap->width || ap->height) { + snprintf(buf, sizeof(buf), "%dx%d", ap->width, ap->height); + av_dict_set(&opts, "video_size", buf, 0); + } + if (ap->pix_fmt != PIX_FMT_NONE) { + av_dict_set(&opts, "pixel_format", av_get_pix_fmt_name(ap->pix_fmt), 0); + } + if (ap->channel) { + snprintf(buf, sizeof(buf), "%d", ap->channel); + av_dict_set(&opts, "channel", buf, 0); + } + if (ap->standard) { + av_dict_set(&opts, "standard", ap->standard, 0); + } + if (ap->mpeg2ts_compute_pcr) { + av_dict_set(&opts, "mpeg2ts_compute_pcr", "1", 0); + } + if (ap->initial_pause) { + av_dict_set(&opts, "initial_pause", "1", 0); + } + return opts; +} + /** * Open a media file from an IO stream. 'fmt' must be specified. */ @@ -396,6 +438,7 @@ int av_open_input_stream(AVFormatContext **ic_ptr, AVInputFormat *fmt, AVFormatParameters *ap) { int err; + AVDictionary *opts; AVFormatContext *ic; AVFormatParameters default_ap; @@ -403,6 +446,7 @@ int av_open_input_stream(AVFormatContext **ic_ptr, ap=&default_ap; memset(ap, 0, sizeof(default_ap)); } + opts = convert_format_parameters(ap); if(!ap->prealloced_context) ic = avformat_alloc_context(); @@ -412,63 +456,15 @@ int av_open_input_stream(AVFormatContext **ic_ptr, err = AVERROR(ENOMEM); goto fail; } - ic->iformat = fmt; ic->pb = pb; - ic->duration = AV_NOPTS_VALUE; - ic->start_time = AV_NOPTS_VALUE; - av_strlcpy(ic->filename, filename, sizeof(ic->filename)); - /* allocate private data */ - if (fmt->priv_data_size > 0) { - ic->priv_data = av_mallocz(fmt->priv_data_size); - if (!ic->priv_data) { - err = AVERROR(ENOMEM); - goto fail; - } - if (fmt->priv_class) { - *(const AVClass**)ic->priv_data = fmt->priv_class; - av_opt_set_defaults(ic->priv_data); - } - } else { - ic->priv_data = NULL; - } + err = avformat_open_input(ic_ptr, filename, fmt, &opts); - // e.g. AVFMT_NOFILE formats will not have a AVIOContext - if (ic->pb) - ff_id3v2_read(ic, ID3v2_DEFAULT_MAGIC); - - if (ic->iformat->read_header) { - err = ic->iformat->read_header(ic, ap); - if (err < 0) - goto fail; - } - - if (pb && !ic->data_offset) - ic->data_offset = avio_tell(ic->pb); - - ic->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE; - - *ic_ptr = ic; - return 0; - fail: - if (ic) { - int i; - av_freep(&ic->priv_data); - for(i=0;inb_streams;i++) { - AVStream *st = ic->streams[i]; - if (st) { - av_free(st->priv_data); - av_free(st->codec->extradata); - av_free(st->codec); - av_free(st->info); - } - av_free(st); - } - } - av_free(ic); - *ic_ptr = NULL; +fail: + av_dict_free(&opts); return err; } +#endif /** size of probe buffer, for guessing file type from file contents */ #define PROBE_BUF_MIN 2048 @@ -541,69 +537,24 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt, return ret; } +#if FF_API_FORMAT_PARAMETERS int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, AVInputFormat *fmt, int buf_size, AVFormatParameters *ap) { int err; - AVProbeData probe_data, *pd = &probe_data; - AVIOContext *pb = NULL; - void *logctx= ap && ap->prealloced_context ? *ic_ptr : NULL; + AVDictionary *opts = convert_format_parameters(ap); - pd->filename = ""; - if (filename) - pd->filename = filename; - pd->buf = NULL; - pd->buf_size = 0; + if (!ap->prealloced_context) + *ic_ptr = NULL; - if (!fmt) { - /* guess format if no file can be opened */ - fmt = av_probe_input_format(pd, 0); - } + err = avformat_open_input(ic_ptr, filename, fmt, &opts); - /* Do not open file if the format does not need it. XXX: specific - hack needed to handle RTSP/TCP */ - if (!fmt || !(fmt->flags & AVFMT_NOFILE)) { - /* if no file needed do not try to open one */ - if ((err=avio_open(&pb, filename, AVIO_FLAG_READ)) < 0) { - goto fail; - } - if (buf_size > 0) { - ffio_set_buf_size(pb, buf_size); - } - if (!fmt && (err = av_probe_input_buffer(pb, &fmt, filename, logctx, 0, logctx ? (*ic_ptr)->probesize : 0)) < 0) { - goto fail; - } - } - - /* if still no format found, error */ - if (!fmt) { - err = AVERROR_INVALIDDATA; - goto fail; - } - - /* check filename in case an image number is expected */ - if (fmt->flags & AVFMT_NEEDNUMBER) { - if (!av_filename_number_test(filename)) { - err = AVERROR(EINVAL); - goto fail; - } - } - err = av_open_input_stream(ic_ptr, pb, filename, fmt, ap); - if (err) - goto fail; - return 0; - fail: - av_freep(&pd->buf); - if (pb) - avio_close(pb); - if (ap && ap->prealloced_context) - av_free(*ic_ptr); - *ic_ptr = NULL; + av_dict_free(&opts); return err; - } +#endif /* open input file and probe the format if necessary */ static int init_input(AVFormatContext *s, const char *filename) From 25de5958c8fd727777ebf8c4f7a9df6f9b8eb82d Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 22 May 2011 13:53:33 +0200 Subject: [PATCH 014/109] lavf: add avformat_write_header() as a replacement for av_write_header(). It supports more convenient setting of AVOptions. --- libavformat/avformat.h | 30 ++++++++++++++++-- libavformat/rtpenc_chain.c | 2 +- libavformat/utils.c | 63 ++++++++++++++++++++++++++++++-------- 3 files changed, 80 insertions(+), 15 deletions(-) diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 6c5b9c6e56..9abc9c51a4 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1322,7 +1322,12 @@ int64_t av_gen_search(AVFormatContext *s, int stream_index, /** * media file output */ -int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap); +#if FF_API_FORMAT_PARAMETERS +/** + * @deprecated pass the options to avformat_write_header directly. + */ +attribute_deprecated int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap); +#endif /** * Split a URL string into components. @@ -1350,6 +1355,24 @@ void av_url_split(char *proto, int proto_size, char *path, int path_size, const char *url); +/** + * Allocate the stream private data and write the stream header to + * an output media file. + * + * @param s Media file handle, must be allocated with avformat_alloc_context(). + * Its oformat field must be set to the desired output format; + * Its pb field must be set to an already openened AVIOContext. + * @param options An AVDictionary filled with AVFormatContext and muxer-private options. + * On return this parameter will be destroyed and replaced with a dict containing + * options that were not found. May be NULL. + * + * @return 0 on success, negative AVERROR on failure. + * + * @see av_opt_find, av_dict_set, avio_open, av_oformat_next. + */ +int avformat_write_header(AVFormatContext *s, AVDictionary **options); + +#if FF_API_FORMAT_PARAMETERS /** * Allocate the stream private data and write the stream header to an * output media file. @@ -1358,8 +1381,11 @@ void av_url_split(char *proto, int proto_size, * * @param s media file handle * @return 0 if OK, AVERROR_xxx on error + * + * @deprecated use avformat_write_header. */ -int av_write_header(AVFormatContext *s); +attribute_deprecated int av_write_header(AVFormatContext *s); +#endif /** * Write a packet to an output media file. diff --git a/libavformat/rtpenc_chain.c b/libavformat/rtpenc_chain.c index 87c1688dfc..0fb47f6234 100644 --- a/libavformat/rtpenc_chain.c +++ b/libavformat/rtpenc_chain.c @@ -66,7 +66,7 @@ AVFormatContext *ff_rtp_chain_mux_open(AVFormatContext *s, AVStream *st, ffio_fdopen(&rtpctx->pb, handle); } else ffio_open_dyn_packet_buf(&rtpctx->pb, packet_size); - ret = av_write_header(rtpctx); + ret = avformat_write_header(rtpctx, NULL); if (ret) { if (handle) { diff --git a/libavformat/utils.c b/libavformat/utils.c index 5865495954..e3485e6ffa 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2733,6 +2733,7 @@ AVChapter *ff_new_chapter(AVFormatContext *s, int id, AVRational time_base, int6 /************************************************************/ /* output media file */ +#if FF_API_FORMAT_PARAMETERS int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap) { int ret; @@ -2755,6 +2756,7 @@ int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap) } return 0; } +#endif static int validate_codec_tag(AVFormatContext *s, AVStream *st) { @@ -2789,15 +2791,29 @@ static int validate_codec_tag(AVFormatContext *s, AVStream *st) return 1; } +#if FF_API_FORMAT_PARAMETERS int av_write_header(AVFormatContext *s) { - int ret, i; + return avformat_write_header(s, NULL); +} +#endif + +int avformat_write_header(AVFormatContext *s, AVDictionary **options) +{ + int ret = 0, i; AVStream *st; + AVDictionary *tmp = NULL; + + if (options) + av_dict_copy(&tmp, *options, 0); + if ((ret = av_opt_set_dict(s, &tmp)) < 0) + goto fail; // some sanity checks if (s->nb_streams == 0 && !(s->oformat->flags & AVFMT_NOSTREAMS)) { av_log(s, AV_LOG_ERROR, "no streams\n"); - return AVERROR(EINVAL); + ret = AVERROR(EINVAL); + goto fail; } for(i=0;inb_streams;i++) { @@ -2807,7 +2823,8 @@ int av_write_header(AVFormatContext *s) case AVMEDIA_TYPE_AUDIO: if(st->codec->sample_rate<=0){ av_log(s, AV_LOG_ERROR, "sample rate not set\n"); - return AVERROR(EINVAL); + ret = AVERROR(EINVAL); + goto fail; } if(!st->codec->block_align) st->codec->block_align = st->codec->channels * @@ -2816,15 +2833,18 @@ int av_write_header(AVFormatContext *s) case AVMEDIA_TYPE_VIDEO: if(st->codec->time_base.num<=0 || st->codec->time_base.den<=0){ //FIXME audio too? av_log(s, AV_LOG_ERROR, "time base not set\n"); - return AVERROR(EINVAL); + ret = AVERROR(EINVAL); + goto fail; } if((st->codec->width<=0 || st->codec->height<=0) && !(s->oformat->flags & AVFMT_NODIMENSIONS)){ av_log(s, AV_LOG_ERROR, "dimensions not set\n"); - return AVERROR(EINVAL); + ret = AVERROR(EINVAL); + goto fail; } if(av_cmp_q(st->sample_aspect_ratio, st->codec->sample_aspect_ratio)){ av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between encoder and muxer layer\n"); - return AVERROR(EINVAL); + ret = AVERROR(EINVAL); + goto fail; } break; } @@ -2841,7 +2861,8 @@ int av_write_header(AVFormatContext *s) av_log(s, AV_LOG_ERROR, "Tag %s/0x%08x incompatible with output codec id '%d'\n", tagbuf, st->codec->codec_tag, st->codec->codec_id); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto fail; } }else st->codec->codec_tag= av_codec_get_tag(s->oformat->codec_tag, st->codec->codec_id); @@ -2854,8 +2875,16 @@ int av_write_header(AVFormatContext *s) if (!s->priv_data && s->oformat->priv_data_size > 0) { s->priv_data = av_mallocz(s->oformat->priv_data_size); - if (!s->priv_data) - return AVERROR(ENOMEM); + if (!s->priv_data) { + ret = AVERROR(ENOMEM); + goto fail; + } + if (s->oformat->priv_class) { + *(const AVClass**)s->priv_data= s->oformat->priv_class; + av_opt_set_defaults(s->priv_data); + if ((ret = av_opt_set_dict(s->priv_data, &tmp)) < 0) + goto fail; + } } /* set muxer identification string */ @@ -2866,7 +2895,7 @@ int av_write_header(AVFormatContext *s) if(s->oformat->write_header){ ret = s->oformat->write_header(s); if (ret < 0) - return ret; + goto fail; } /* init PTS generation */ @@ -2885,12 +2914,22 @@ int av_write_header(AVFormatContext *s) break; } if (den != AV_NOPTS_VALUE) { - if (den <= 0) - return AVERROR_INVALIDDATA; + if (den <= 0) { + ret = AVERROR_INVALIDDATA; + goto fail; + } av_frac_init(&st->pts, 0, 0, den); } } + + if (options) { + av_dict_free(options); + *options = tmp; + } return 0; +fail: + av_dict_free(&tmp); + return ret; } //FIXME merge with compute_pkt_fields From 1b9b37b8a416e77b4c6425dcdcee21cf8a1f5d67 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 4 Jun 2011 18:43:05 +0200 Subject: [PATCH 015/109] dict: add AV_DICT_APPEND flag. --- libavutil/dict.c | 13 ++++++++++++- libavutil/dict.h | 2 ++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/libavutil/dict.c b/libavutil/dict.c index 56f1513d32..3ea7e55b30 100644 --- a/libavutil/dict.c +++ b/libavutil/dict.c @@ -19,6 +19,7 @@ */ #include +#include "avstring.h" #include "dict.h" #include "internal.h" #include "mem.h" @@ -51,6 +52,7 @@ int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags { AVDictionary *m = *pm; AVDictionaryEntry *tag = av_dict_get(m, key, NULL, flags); + char *oldval = NULL; if(!m) m = *pm = av_mallocz(sizeof(*m)); @@ -58,7 +60,10 @@ int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags if(tag) { if (flags & AV_DICT_DONT_OVERWRITE) return 0; - av_free(tag->value); + if (flags & AV_DICT_APPEND) + oldval = tag->value; + else + av_free(tag->value); av_free(tag->key); *tag = m->elems[--m->count]; } else { @@ -75,6 +80,12 @@ int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags m->elems[m->count].key = av_strdup(key ); if (flags & AV_DICT_DONT_STRDUP_VAL) { m->elems[m->count].value = value; + } else if (oldval && flags & AV_DICT_APPEND) { + int len = strlen(oldval) + strlen(value) + 1; + if (!(oldval = av_realloc(oldval, len))) + return AVERROR(ENOMEM); + av_strlcat(oldval, value, len); + m->elems[m->count].value = oldval; } else m->elems[m->count].value = av_strdup(value); m->count++; diff --git a/libavutil/dict.h b/libavutil/dict.h index bfd7f2682c..ff24b36f81 100644 --- a/libavutil/dict.h +++ b/libavutil/dict.h @@ -29,6 +29,8 @@ #define AV_DICT_DONT_STRDUP_KEY 4 #define AV_DICT_DONT_STRDUP_VAL 8 #define AV_DICT_DONT_OVERWRITE 16 ///< Don't overwrite existing entries. +#define AV_DICT_APPEND 32 /**< If the entry already exists, append to it. Note that no + delimiter is added, the strings are simply concatenated. */ typedef struct { char *key; From 9ba38229e5bd0cf6201a8206b2d8be6335f45f46 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 25 May 2011 16:42:41 +0200 Subject: [PATCH 016/109] cmdutils: add opt_default2(). It stores options in a dictionary to be passed to new open calls. It will replace opt_default once all the pieces are in place. --- cmdutils.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++---- cmdutils.h | 1 + 2 files changed, 47 insertions(+), 4 deletions(-) diff --git a/cmdutils.c b/cmdutils.c index 9422fc1f03..943a77c82c 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -38,6 +38,7 @@ #include "libavutil/parseutils.h" #include "libavutil/pixdesc.h" #include "libavutil/eval.h" +#include "libavutil/dict.h" #include "libavutil/opt.h" #include "cmdutils.h" #include "version.h" @@ -54,6 +55,7 @@ static int opt_name_count; AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB]; AVFormatContext *avformat_opts; struct SwsContext *sws_opts; +AVDictionary *format_opts, *video_opts, *audio_opts, *sub_opts; static const int this_year = 2011; @@ -90,6 +92,10 @@ void uninit_opts(void) av_freep(&opt_names); av_freep(&opt_values); opt_name_count = 0; + av_dict_free(&format_opts); + av_dict_free(&video_opts); + av_dict_free(&audio_opts); + av_dict_free(&sub_opts); } void log_callback_help(void* ptr, int level, const char* fmt, va_list vl) @@ -292,6 +298,43 @@ unknown_opt: } } +#define FLAGS (o->type == FF_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0 +#define SET_PREFIXED_OPTS(ch, flag, output) \ + if (opt[0] == ch && avcodec_opts[0] && (o = av_opt_find(avcodec_opts[0], opt+1, NULL, flag, 0)))\ + av_dict_set(&output, opt+1, arg, FLAGS); +static int opt_default2(const char *opt, const char *arg) +{ + const AVOption *o; + if ((o = av_opt_find(avcodec_opts[0], opt, NULL, 0, AV_OPT_SEARCH_CHILDREN))) { + if (o->flags & AV_OPT_FLAG_VIDEO_PARAM) + av_dict_set(&video_opts, opt, arg, FLAGS); + if (o->flags & AV_OPT_FLAG_AUDIO_PARAM) + av_dict_set(&audio_opts, opt, arg, FLAGS); + if (o->flags & AV_OPT_FLAG_SUBTITLE_PARAM) + av_dict_set(&sub_opts, opt, arg, FLAGS); + } else if ((o = av_opt_find(avformat_opts, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN))) + av_dict_set(&format_opts, opt, arg, FLAGS); + else if ((o = av_opt_find(sws_opts, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN))) { + // XXX we only support sws_flags, not arbitrary sws options + int ret = av_set_string3(sws_opts, opt, arg, 1, NULL); + if (ret < 0) { + av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt); + return ret; + } + } + + if (!o) { + SET_PREFIXED_OPTS('v', AV_OPT_FLAG_VIDEO_PARAM, video_opts) + SET_PREFIXED_OPTS('a', AV_OPT_FLAG_AUDIO_PARAM, audio_opts) + SET_PREFIXED_OPTS('s', AV_OPT_FLAG_SUBTITLE_PARAM, sub_opts) + } + + if (o) + return 0; + fprintf(stderr, "Unrecognized option '%s'\n", opt); + return AVERROR_OPTION_NOT_FOUND; +} + int opt_default(const char *opt, const char *arg){ int type; int ret= 0; @@ -334,12 +377,11 @@ int opt_default(const char *opt, const char *arg){ break; } } - if(!p && !oformat){ - fprintf(stderr, "Unrecognized option '%s'\n", opt); - exit(1); - } } + if ((ret = opt_default2(opt, arg)) < 0) + return ret; + // av_log(NULL, AV_LOG_ERROR, "%s:%s: %f 0x%0X\n", opt, arg, av_get_double(avcodec_opts, opt, NULL), (int)av_get_int(avcodec_opts, opt, NULL)); //FIXME we should always use avcodec_opts, ... for storing options so there will not be any need to keep track of what i set over this diff --git a/cmdutils.h b/cmdutils.h index e231b1ff84..02fcea4426 100644 --- a/cmdutils.h +++ b/cmdutils.h @@ -43,6 +43,7 @@ extern const char **opt_names; extern AVCodecContext *avcodec_opts[AVMEDIA_TYPE_NB]; extern AVFormatContext *avformat_opts; extern struct SwsContext *sws_opts; +extern AVDictionary *format_opts, *video_opts, *audio_opts, *sub_opts; /** * Initialize the cmdutils option system, in particular From d0e142bb68fdc817fb84f2395ae416d43ca141ce Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 9 Jun 2011 10:58:23 +0200 Subject: [PATCH 017/109] ffplay: use new avformat_open_* API. --- ffplay.c | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/ffplay.c b/ffplay.c index 5700883828..c9891d3cdc 100644 --- a/ffplay.c +++ b/ffplay.c @@ -27,6 +27,7 @@ #include "libavutil/colorspace.h" #include "libavutil/pixdesc.h" #include "libavutil/imgutils.h" +#include "libavutil/dict.h" #include "libavutil/parseutils.h" #include "libavutil/samplefmt.h" #include "libavformat/avformat.h" @@ -2309,15 +2310,13 @@ static int decode_interrupt_cb(void) static int decode_thread(void *arg) { VideoState *is = arg; - AVFormatContext *ic; + AVFormatContext *ic = NULL; int err, i, ret; int st_index[AVMEDIA_TYPE_NB]; AVPacket pkt1, *pkt = &pkt1; - AVFormatParameters params, *ap = ¶ms; int eof=0; int pkt_in_play_range = 0; - - ic = avformat_alloc_context(); + AVDictionaryEntry *t; memset(st_index, -1, sizeof(st_index)); is->video_stream = -1; @@ -2327,22 +2326,17 @@ static int decode_thread(void *arg) global_video_state = is; avio_set_interrupt_cb(decode_interrupt_cb); - memset(ap, 0, sizeof(*ap)); - - ap->prealloced_context = 1; - ap->width = frame_width; - ap->height= frame_height; - ap->time_base= (AVRational){1, 25}; - ap->pix_fmt = frame_pix_fmt; - - set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM, NULL); - - err = av_open_input_file(&ic, is->filename, is->iformat, 0, ap); + err = avformat_open_input(&ic, is->filename, is->iformat, &format_opts); if (err < 0) { print_error(is->filename, err); ret = -1; goto fail; } + if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) { + av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key); + ret = AVERROR_OPTION_NOT_FOUND; + goto fail; + } is->ic = ic; if(genpts) From e0518705c8f575488a50407eee3edcc94c905973 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 9 Jun 2011 10:58:23 +0200 Subject: [PATCH 018/109] ffprobe: use new avformat_open_* API. --- ffprobe.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/ffprobe.c b/ffprobe.c index e00790f54b..711a17246d 100644 --- a/ffprobe.c +++ b/ffprobe.c @@ -262,15 +262,18 @@ static void show_format(AVFormatContext *fmt_ctx) static int open_input_file(AVFormatContext **fmt_ctx_ptr, const char *filename) { int err, i; - AVFormatContext *fmt_ctx; + AVFormatContext *fmt_ctx = NULL; + AVDictionaryEntry *t; - fmt_ctx = avformat_alloc_context(); - set_context_opts(fmt_ctx, avformat_opts, AV_OPT_FLAG_DECODING_PARAM, NULL); - - if ((err = av_open_input_file(&fmt_ctx, filename, iformat, 0, NULL)) < 0) { + if ((err = avformat_open_input(&fmt_ctx, filename, iformat, &format_opts)) < 0) { print_error(filename, err); return err; } + if ((t = av_dict_get(format_opts, "", NULL, AV_DICT_IGNORE_SUFFIX))) { + av_log(NULL, AV_LOG_ERROR, "Option %s not found.\n", t->key); + return AVERROR_OPTION_NOT_FOUND; + } + /* fill the streams in the format context */ if ((err = av_find_stream_info(fmt_ctx)) < 0) { From 50f2dfad679747d417879d6b49c929286aff69b1 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 9 Jun 2011 10:58:23 +0200 Subject: [PATCH 019/109] ffserver: use new avformat_open_* API. --- ffserver.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/ffserver.c b/ffserver.c index 2ac7e6abf9..65a97b20cc 100644 --- a/ffserver.c +++ b/ffserver.c @@ -205,7 +205,7 @@ typedef struct FFStream { char filename[1024]; /* stream filename */ struct FFStream *feed; /* feed we are using (can be null if coming from file) */ - AVFormatParameters *ap_in; /* input parameters */ + AVDictionary *in_opts; /* input parameters */ AVInputFormat *ifmt; /* if non NULL, force input format */ AVOutputFormat *fmt; IPAddressACL *acl; @@ -2126,7 +2126,7 @@ static int open_input_stream(HTTPContext *c, const char *info) { char buf[128]; char input_filename[1024]; - AVFormatContext *s; + AVFormatContext *s = NULL; int buf_size, i, ret; int64_t stream_pos; @@ -2157,8 +2157,7 @@ static int open_input_stream(HTTPContext *c, const char *info) return -1; /* open stream */ - if ((ret = av_open_input_file(&s, input_filename, c->stream->ifmt, - buf_size, c->stream->ap_in)) < 0) { + if ((ret = avformat_open_input(&s, input_filename, c->stream->ifmt, &c->stream->in_opts)) < 0) { http_log("could not open %s: %d\n", input_filename, ret); return -1; } @@ -2268,8 +2267,7 @@ static int http_prepare_data(HTTPContext *c) c->fmt_ctx.preload = (int)(0.5*AV_TIME_BASE); c->fmt_ctx.max_delay = (int)(0.7*AV_TIME_BASE); - av_set_parameters(&c->fmt_ctx, NULL); - if (av_write_header(&c->fmt_ctx) < 0) { + if (avformat_write_header(&c->fmt_ctx, NULL) < 0) { http_log("Error writing output header\n"); return -1; } @@ -2709,11 +2707,14 @@ static int http_receive_data(HTTPContext *c) } } else { /* We have a header in our hands that contains useful data */ - AVFormatContext *s = NULL; + AVFormatContext *s = avformat_alloc_context(); AVIOContext *pb; AVInputFormat *fmt_in; int i; + if (!s) + goto fail; + /* use feed output format name to find corresponding input format */ fmt_in = av_find_input_format(feed->fmt->name); if (!fmt_in) @@ -2723,7 +2724,8 @@ static int http_receive_data(HTTPContext *c) 0, NULL, NULL, NULL, NULL); pb->seekable = 0; - if (av_open_input_stream(&s, pb, c->stream->feed_filename, fmt_in, NULL) < 0) { + s->pb = pb; + if (avformat_open_input(&s, c->stream->feed_filename, fmt_in, NULL) < 0) { av_free(pb); goto fail; } @@ -3442,8 +3444,7 @@ static int rtp_new_av_stream(HTTPContext *c, /* XXX: close stream */ goto fail; } - av_set_parameters(ctx, NULL); - if (av_write_header(ctx) < 0) { + if (avformat_write_header(ctx, NULL) < 0) { fail: if (h) url_close(h); @@ -3597,28 +3598,25 @@ static void extract_mpeg4_header(AVFormatContext *infile) static void build_file_streams(void) { FFStream *stream, *stream_next; - AVFormatContext *infile; int i, ret; /* gather all streams */ for(stream = first_stream; stream != NULL; stream = stream_next) { + AVFormatContext *infile = NULL; stream_next = stream->next; if (stream->stream_type == STREAM_TYPE_LIVE && !stream->feed) { /* the stream comes from a file */ /* try to open the file */ /* open stream */ - stream->ap_in = av_mallocz(sizeof(AVFormatParameters)); if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) { /* specific case : if transport stream output to RTP, we use a raw transport stream reader */ - stream->ap_in->mpeg2ts_raw = 1; - stream->ap_in->mpeg2ts_compute_pcr = 1; + av_dict_set(&stream->in_opts, "mpeg2ts_compute_pcr", "1", 0); } http_log("Opening file '%s'\n", stream->feed_filename); - if ((ret = av_open_input_file(&infile, stream->feed_filename, - stream->ifmt, 0, stream->ap_in)) < 0) { + if ((ret = avformat_open_input(&infile, stream->feed_filename, stream->ifmt, &stream->in_opts)) < 0) { http_log("Could not open '%s': %d\n", stream->feed_filename, ret); /* remove stream (no need to spend more time on it) */ fail: @@ -3678,10 +3676,10 @@ static void build_feed_streams(void) if (avio_check(feed->feed_filename, AVIO_FLAG_READ) > 0) { /* See if it matches */ - AVFormatContext *s; + AVFormatContext *s = NULL; int matches = 0; - if (av_open_input_file(&s, feed->feed_filename, NULL, FFM_PACKET_SIZE, NULL) >= 0) { + if (avformat_open_input(&s, feed->feed_filename, NULL, NULL) >= 0) { /* Now see if it matches */ if (s->nb_streams == feed->nb_streams) { matches = 1; @@ -3767,8 +3765,7 @@ static void build_feed_streams(void) s->oformat = feed->fmt; s->nb_streams = feed->nb_streams; s->streams = feed->streams; - av_set_parameters(s, NULL); - if (av_write_header(s) < 0) { + if (avformat_write_header(s, NULL) < 0) { http_log("Container doesn't supports the required parameters\n"); exit(1); } From 8035f429684e368fe54af8ccedc2d4776a2d6154 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 9 Jun 2011 10:58:23 +0200 Subject: [PATCH 020/109] ffmpeg: use new avformat_open_* API. --- ffmpeg.c | 77 ++++++++++++++++++++++++++++++------------------- tests/fate2.mak | 2 +- 2 files changed, 48 insertions(+), 31 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index 6a4fb5358f..91783708cf 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -113,6 +113,7 @@ static int nb_input_codecs = 0; static int nb_input_files_ts_scale[MAX_FILES] = {0}; static AVFormatContext *output_files[MAX_FILES]; +static AVDictionary *output_opts[MAX_FILES]; static int nb_output_files = 0; static AVStreamMap *stream_maps = NULL; @@ -465,6 +466,7 @@ static int ffmpeg_exit(int ret) avio_close(s->pb); avformat_free_context(s); av_free(output_streams_for_file[i]); + av_dict_free(&output_opts[i]); } for(i=0;ikey); + ffmpeg_exit(1); + } +} + /* similar to ff_dynarray_add() and av_fast_realloc() */ static void *grow_array(void *array, int elem_size, int *size, int new_size) { @@ -666,10 +677,10 @@ static AVOutputStream *new_output_stream(AVFormatContext *oc, int file_idx) static int read_ffserver_streams(AVFormatContext *s, const char *filename) { int i, err; - AVFormatContext *ic; + AVFormatContext *ic = NULL; int nopts = 0; - err = av_open_input_file(&ic, filename, NULL, FFM_PACKET_SIZE, NULL); + err = avformat_open_input(&ic, filename, NULL, NULL); if (err < 0) return err; /* copy stream format */ @@ -2470,11 +2481,12 @@ static int transcode(AVFormatContext **output_files, /* open files and write file headers */ for(i=0;ioformat->name, "rtp")) { want_sdp = 0; } @@ -3148,10 +3160,10 @@ static enum CodecID find_codec_or_die(const char *name, int type, int encoder, i static int opt_input_file(const char *opt, const char *filename) { AVFormatContext *ic; - AVFormatParameters params, *ap = ¶ms; AVInputFormat *file_iformat = NULL; int err, i, ret, rfps, rfps_base; int64_t timestamp; + uint8_t buf[128]; if (last_asked_format) { if (!(file_iformat = av_find_input_format(last_asked_format))) { @@ -3173,21 +3185,24 @@ static int opt_input_file(const char *opt, const char *filename) print_error(filename, AVERROR(ENOMEM)); ffmpeg_exit(1); } - - memset(ap, 0, sizeof(*ap)); - ap->prealloced_context = 1; - ap->sample_rate = audio_sample_rate; - ap->channels = audio_channels; - ap->time_base.den = frame_rate.num; - ap->time_base.num = frame_rate.den; - ap->width = frame_width; - ap->height = frame_height; - ap->pix_fmt = frame_pix_fmt; - // ap->sample_fmt = audio_sample_fmt; //FIXME:not implemented in libavformat - ap->channel = video_channel; - ap->standard = video_standard; - - set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM, NULL); + if (audio_sample_rate) { + snprintf(buf, sizeof(buf), "%d", audio_sample_rate); + av_dict_set(&format_opts, "sample_rate", buf, 0); + } + if (audio_channels) { + snprintf(buf, sizeof(buf), "%d", audio_channels); + av_dict_set(&format_opts, "channels", buf, 0); + } + if (frame_rate.num) { + snprintf(buf, sizeof(buf), "%d/%d", frame_rate.num, frame_rate.den); + av_dict_set(&format_opts, "framerate", buf, 0); + } + if (frame_width && frame_height) { + snprintf(buf, sizeof(buf), "%dx%d", frame_width, frame_height); + av_dict_set(&format_opts, "video_size", buf, 0); + } + if (frame_pix_fmt != PIX_FMT_NONE) + av_dict_set(&format_opts, "pixel_format", av_get_pix_fmt_name(frame_pix_fmt), 0); ic->video_codec_id = find_codec_or_die(video_codec_name , AVMEDIA_TYPE_VIDEO , 0, @@ -3201,11 +3216,13 @@ static int opt_input_file(const char *opt, const char *filename) ic->flags |= AVFMT_FLAG_NONBLOCK; /* open the input file with generic libav function */ - err = av_open_input_file(&ic, filename, file_iformat, 0, ap); + err = avformat_open_input(&ic, filename, file_iformat, &format_opts); if (err < 0) { print_error(filename, err); ffmpeg_exit(1); } + assert_avoptions(format_opts); + if(opt_programid) { int i, j; int found=0; @@ -3760,7 +3777,6 @@ static void opt_output_file(const char *filename) AVFormatContext *oc; int err, use_video, use_audio, use_subtitle, use_data; int input_has_video, input_has_audio, input_has_subtitle, input_has_data; - AVFormatParameters params, *ap = ¶ms; AVOutputFormat *file_oformat; if (!strcmp(filename, "-")) @@ -3841,6 +3857,7 @@ static void opt_output_file(const char *filename) av_dict_free(&metadata); } + av_dict_copy(&output_opts[nb_output_files], format_opts, 0); output_files[nb_output_files++] = oc; /* check filename in case of an image number is expected */ @@ -3880,20 +3897,11 @@ static void opt_output_file(const char *filename) } } - memset(ap, 0, sizeof(*ap)); - if (av_set_parameters(oc, ap) < 0) { - fprintf(stderr, "%s: Invalid encoding parameters\n", - oc->filename); - ffmpeg_exit(1); - } - oc->preload= (int)(mux_preload*AV_TIME_BASE); oc->max_delay= (int)(mux_max_delay*AV_TIME_BASE); oc->loop_output = loop_output; oc->flags |= AVFMT_FLAG_NONBLOCK; - set_context_opts(oc, avformat_opts, AV_OPT_FLAG_ENCODING_PARAM, NULL); - frame_rate = (AVRational){0, 0}; frame_width = 0; frame_height = 0; @@ -3988,6 +3996,7 @@ static void show_help(void) { AVCodec *c; AVOutputFormat *oformat = NULL; + AVInputFormat *iformat = NULL; av_log_set_callback(log_callback_help); show_usage(); @@ -4038,6 +4047,14 @@ static void show_help(void) } } + /* individual demuxer options */ + while ((iformat = av_iformat_next(iformat))) { + if (iformat->priv_class) { + av_opt_show2(&iformat->priv_class, NULL, AV_OPT_FLAG_DECODING_PARAM, 0); + printf("\n"); + } + } + av_opt_show2(sws_opts, NULL, AV_OPT_FLAG_ENCODING_PARAM|AV_OPT_FLAG_DECODING_PARAM, 0); } diff --git a/tests/fate2.mak b/tests/fate2.mak index 066f9ef583..b4139f35f7 100644 --- a/tests/fate2.mak +++ b/tests/fate2.mak @@ -165,7 +165,7 @@ fate-wmapro-2ch: CMP = oneoff fate-wmapro-2ch: REF = $(SAMPLES)/wmapro/Beethovens_9th-1_small.pcm FATE_TESTS += fate-ansi -fate-ansi: CMD = framecrc -ar 44100 -i $(SAMPLES)/ansi/TRE-IOM5.ANS -pix_fmt rgb24 +fate-ansi: CMD = framecrc -chars_per_frame 44100 -i $(SAMPLES)/ansi/TRE-IOM5.ANS -pix_fmt rgb24 FATE_TESTS += fate-wmv8-drm # discard last packet to avoid fails due to overread of VC-1 decoder From 55ba12e3009fd6c8f78102f7c747496d500d0bac Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 15 Jun 2011 07:34:12 +0200 Subject: [PATCH 021/109] ffmpeg: deprecate -vc and -tvstd They've been replaced by demuxer private options. --- ffmpeg.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index 91783708cf..b28408741c 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -213,9 +213,6 @@ static int copy_initial_nonkeyframes = 0; static int rate_emu = 0; -static int video_channel = 0; -static char *video_standard; - static int audio_volume = 256; static int exit_on_error = 0; @@ -493,8 +490,6 @@ static int ffmpeg_exit(int ret) av_free(subtitle_codec_name); av_free(data_codec_name); - av_free(video_standard); - uninit_opts(); av_free(audio_buf); av_free(audio_out); @@ -2922,13 +2917,15 @@ static int opt_audio_channels(const char *opt, const char *arg) static int opt_video_channel(const char *opt, const char *arg) { - video_channel = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX); + av_log(NULL, AV_LOG_WARNING, "This option is deprecated, use -channel.\n"); + opt_default("channel", arg); return 0; } static int opt_video_standard(const char *opt, const char *arg) { - video_standard = av_strdup(arg); + av_log(NULL, AV_LOG_WARNING, "This option is deprecated, use -standard.\n"); + opt_default("standard", arg); return 0; } @@ -3366,7 +3363,6 @@ static int opt_input_file(const char *opt, const char *filename) input_files[nb_input_files - 1].ctx = ic; input_files[nb_input_files - 1].ist_index = nb_input_streams - ic->nb_streams; - video_channel = 0; frame_rate = (AVRational){0, 0}; frame_pix_fmt = PIX_FMT_NONE; frame_height = 0; @@ -4397,8 +4393,8 @@ static const OptionDef options[] = { { "stag", HAS_ARG | OPT_EXPERT | OPT_SUBTITLE, {(void*)opt_codec_tag}, "force subtitle tag/fourcc", "fourcc/tag" }, /* grab options */ - { "vc", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_GRAB, {(void*)opt_video_channel}, "set video grab channel (DV1394 only)", "channel" }, - { "tvstd", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_GRAB, {(void*)opt_video_standard}, "set television standard (NTSC, PAL (SECAM))", "standard" }, + { "vc", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_GRAB, {(void*)opt_video_channel}, "deprecated, use -channel", "channel" }, + { "tvstd", HAS_ARG | OPT_EXPERT | OPT_VIDEO | OPT_GRAB, {(void*)opt_video_standard}, "deprecated, use -standard", "standard" }, { "isync", OPT_BOOL | OPT_EXPERT | OPT_GRAB, {(void*)&input_sync}, "sync read on input", "" }, /* muxer options */ From 7c44d716e76cbd1c29369563a8b384addd5e7c03 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 16 Jun 2011 17:21:46 +0200 Subject: [PATCH 022/109] Add minor bumps and APIChanges entries for lavf private options. --- doc/APIchanges | 10 ++++++++++ libavformat/version.h | 4 ++-- libavutil/avutil.h | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 0ab658d89c..460e8dde83 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,16 @@ libavutil: 2011-04-18 API changes, most recent first: +2011-06-xx - xxxxxxx - lavf 53.2.0 - avformat.h + Add avformat_open_input and avformat_write_header(). + Deprecate av_open_input_stream, av_open_input_file, + AVFormatParameters and av_write_header. + +2011-06-xx - xxxxxxx - lavu 51.7.0 - opt.h + Add av_opt_set_dict() and av_opt_find(). + Deprecate av_find_opt(). + Add AV_DICT_APPEND flag. + 2011-06-xx - xxxxxxx - lavu 51.6.0 - opt.h Add av_opt_flag_is_set(). diff --git a/libavformat/version.h b/libavformat/version.h index 83fa431246..3cc1718f2b 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -24,8 +24,8 @@ #include "libavutil/avutil.h" #define LIBAVFORMAT_VERSION_MAJOR 53 -#define LIBAVFORMAT_VERSION_MINOR 1 -#define LIBAVFORMAT_VERSION_MICRO 3 +#define LIBAVFORMAT_VERSION_MINOR 2 +#define LIBAVFORMAT_VERSION_MICRO 0 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ diff --git a/libavutil/avutil.h b/libavutil/avutil.h index 21df460c1f..18461467b4 100644 --- a/libavutil/avutil.h +++ b/libavutil/avutil.h @@ -40,7 +40,7 @@ #define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c) #define LIBAVUTIL_VERSION_MAJOR 51 -#define LIBAVUTIL_VERSION_MINOR 6 +#define LIBAVUTIL_VERSION_MINOR 7 #define LIBAVUTIL_VERSION_MICRO 0 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ From aa15e68721b15f8020da9d392954b343f195f22c Mon Sep 17 00:00:00 2001 From: Mike Scheutzow Date: Thu, 28 Apr 2011 10:14:26 -0400 Subject: [PATCH 023/109] Fix decoding of mpegts streams with h264 video that does *NOT* have b frames One of the causes of this bug is that the h264 parser defaults low_delay to 1, but the h264 codec defaults low_delay to 0. Really Ugly. After many hours of looking at this, I'm still not sure how has_b_frames is *intended* to behave, but to me the implementation appears way more complicated than it ought to be. My patch relies on the encoder to set an optional field in the SPS. This works for libx264 streams, but I'm not sure that all h264 encoders will set it. Signed-off-by: Anton Khirnov --- libavcodec/h264.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 78ca4141a4..0aac09754a 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -3768,7 +3768,8 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ init_get_bits(&s->gb, ptr, bit_length); ff_h264_decode_seq_parameter_set(h); - if(s->flags& CODEC_FLAG_LOW_DELAY) + if (s->flags& CODEC_FLAG_LOW_DELAY || + (h->sps.bitstream_restriction_flag && !h->sps.num_reorder_frames)) s->low_delay=1; if(avctx->has_b_frames < 2) From c98b928fa7dea6418c24a163e7bcd36b0eb922a3 Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Tue, 14 Jun 2011 21:53:30 +0000 Subject: [PATCH 024/109] intreadwrite.h: fix AV_RL32/AV_RB32 signedness. The output type of the AV_RL32/AV_RB32 macros was signed int. The resulting overflow broke at least some ASF streams with large timestamps. Fix by adding a cast to uint32_t. Signed-off-by: Ronald S. Bultje Signed-off-by: Anton Khirnov --- libavutil/intreadwrite.h | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/libavutil/intreadwrite.h b/libavutil/intreadwrite.h index c8489f1138..01eb27804a 100644 --- a/libavutil/intreadwrite.h +++ b/libavutil/intreadwrite.h @@ -229,11 +229,11 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias; #endif #ifndef AV_RB32 -# define AV_RB32(x) \ - ((((const uint8_t*)(x))[0] << 24) | \ - (((const uint8_t*)(x))[1] << 16) | \ - (((const uint8_t*)(x))[2] << 8) | \ - ((const uint8_t*)(x))[3]) +# define AV_RB32(x) \ + (((uint32_t)((const uint8_t*)(x))[0] << 24) | \ + (((const uint8_t*)(x))[1] << 16) | \ + (((const uint8_t*)(x))[2] << 8) | \ + ((const uint8_t*)(x))[3]) #endif #ifndef AV_WB32 # define AV_WB32(p, d) do { \ @@ -245,11 +245,11 @@ union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias; #endif #ifndef AV_RL32 -# define AV_RL32(x) \ - ((((const uint8_t*)(x))[3] << 24) | \ - (((const uint8_t*)(x))[2] << 16) | \ - (((const uint8_t*)(x))[1] << 8) | \ - ((const uint8_t*)(x))[0]) +# define AV_RL32(x) \ + (((uint32_t)((const uint8_t*)(x))[3] << 24) | \ + (((const uint8_t*)(x))[2] << 16) | \ + (((const uint8_t*)(x))[1] << 8) | \ + ((const uint8_t*)(x))[0]) #endif #ifndef AV_WL32 # define AV_WL32(p, d) do { \ From 3803af22d8e1092e658110e77db093922ce63e80 Mon Sep 17 00:00:00 2001 From: Alexander Strange Date: Sun, 12 Jun 2011 20:40:00 +0000 Subject: [PATCH 025/109] h264: Complexify frame num gap shortening code By observation it did not seem to handle prev_frame_num > frame_num. This does not affect any files I have. Signed-off-by: Ronald S. Bultje Signed-off-by: Anton Khirnov --- libavcodec/h264.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 0aac09754a..ad591269c6 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -2681,9 +2681,20 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ h->mb_field_decoding_flag= s->picture_structure != PICT_FRAME; if(h0->current_slice == 0){ - if(h->frame_num != h->prev_frame_num && - (h->prev_frame_num+1)%(1<sps.log2_max_frame_num) < (h->frame_num - h->sps.ref_frame_count)) - h->prev_frame_num = h->frame_num - h->sps.ref_frame_count - 1; + // Shorten frame num gaps so we don't have to allocate reference frames just to throw them away + if(h->frame_num != h->prev_frame_num) { + int unwrap_prev_frame_num = h->prev_frame_num, max_frame_num = 1<sps.log2_max_frame_num; + + if (unwrap_prev_frame_num > h->frame_num) unwrap_prev_frame_num -= max_frame_num; + + if ((h->frame_num - unwrap_prev_frame_num) > h->sps.ref_frame_count) { + unwrap_prev_frame_num = (h->frame_num - h->sps.ref_frame_count) - 1; + if (unwrap_prev_frame_num < 0) + unwrap_prev_frame_num += max_frame_num; + + h->prev_frame_num = unwrap_prev_frame_num; + } + } while(h->frame_num != h->prev_frame_num && h->frame_num != (h->prev_frame_num+1)%(1<sps.log2_max_frame_num)){ From f6e2af4f5aed088d4926c2ceb320bb4bf514132b Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Thu, 16 Jun 2011 23:06:27 +0200 Subject: [PATCH 026/109] ffmpeg: Force 420 with target dvd and svcd. Fixes ticket283 Signed-off-by: Michael Niedermayer --- ffmpeg.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ffmpeg.c b/ffmpeg.c index a5b43227b6..a679fa48dc 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -4225,6 +4225,7 @@ static int opt_target(const char *opt, const char *arg) opt_frame_size("s", norm == PAL ? "480x576" : "480x480"); opt_frame_rate("r", frame_rates[norm]); + opt_frame_pix_fmt("pix_fmt", "yuv420p"); opt_default("g", norm == PAL ? "15" : "18"); opt_default("b", "2040000"); @@ -4247,6 +4248,7 @@ static int opt_target(const char *opt, const char *arg) opt_frame_size("vcodec", norm == PAL ? "720x576" : "720x480"); opt_frame_rate("r", frame_rates[norm]); + opt_frame_pix_fmt("pix_fmt", "yuv420p"); opt_default("g", norm == PAL ? "15" : "18"); opt_default("b", "6000000"); From 5fb67d8039e15a34c5aef8a1c87c8e252296938b Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Thu, 16 Jun 2011 23:14:17 +0200 Subject: [PATCH 027/109] Fix compilation with old yasm. --- libavcodec/x86/h264_deblock.asm | 6 ++++++ libavcodec/x86/h264_deblock_10bit.asm | 8 ++++++++ libavcodec/x86/h264dsp_mmx.c | 2 +- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/libavcodec/x86/h264_deblock.asm b/libavcodec/x86/h264_deblock.asm index 2a6da0fe90..6c2ef18bc2 100644 --- a/libavcodec/x86/h264_deblock.asm +++ b/libavcodec/x86/h264_deblock.asm @@ -386,8 +386,10 @@ cglobal deblock_h_luma_8_%1, 5,7 INIT_XMM DEBLOCK_LUMA sse2 +%ifdef HAVE_AVX INIT_AVX DEBLOCK_LUMA avx +%endif %else @@ -506,8 +508,10 @@ INIT_MMX DEBLOCK_LUMA mmxext, v8, 8 INIT_XMM DEBLOCK_LUMA sse2, v, 16 +%ifdef HAVE_AVX INIT_AVX DEBLOCK_LUMA avx, v, 16 +%endif %endif ; ARCH @@ -778,8 +782,10 @@ cglobal deblock_h_luma_intra_8_%1, 2,4 INIT_XMM DEBLOCK_LUMA_INTRA sse2, v +%ifdef HAVE_AVX INIT_AVX DEBLOCK_LUMA_INTRA avx , v +%endif %ifndef ARCH_X86_64 INIT_MMX DEBLOCK_LUMA_INTRA mmxext, v8 diff --git a/libavcodec/x86/h264_deblock_10bit.asm b/libavcodec/x86/h264_deblock_10bit.asm index 699fc4a687..ee316258d3 100644 --- a/libavcodec/x86/h264_deblock_10bit.asm +++ b/libavcodec/x86/h264_deblock_10bit.asm @@ -419,9 +419,11 @@ cglobal deblock_h_luma_10_%1, 5,7,15 INIT_XMM DEBLOCK_LUMA_64 sse2 +%ifdef HAVE_AVX INIT_AVX DEBLOCK_LUMA_64 avx %endif +%endif %macro SWAPMOVA 2 %ifid %1 @@ -714,8 +716,10 @@ cglobal deblock_h_luma_intra_10_%1, 4,7,16 INIT_XMM DEBLOCK_LUMA_INTRA_64 sse2 +%ifdef HAVE_AVX INIT_AVX DEBLOCK_LUMA_INTRA_64 avx +%endif %endif @@ -799,10 +803,12 @@ DEBLOCK_LUMA_INTRA mmxext INIT_XMM DEBLOCK_LUMA sse2 DEBLOCK_LUMA_INTRA sse2 +%ifdef HAVE_AVX INIT_AVX DEBLOCK_LUMA avx DEBLOCK_LUMA_INTRA avx %endif +%endif ; in: %1=p0, %2=q0, %3=p1, %4=q1, %5=mask, %6=tmp, %7=tmp ; out: %1=p0', %2=q0' @@ -913,5 +919,7 @@ DEBLOCK_CHROMA mmxext %endif INIT_XMM DEBLOCK_CHROMA sse2 +%ifdef HAVE_AVX INIT_AVX DEBLOCK_CHROMA avx +%endif diff --git a/libavcodec/x86/h264dsp_mmx.c b/libavcodec/x86/h264dsp_mmx.c index 3bb4384a5f..6c1b0a5619 100644 --- a/libavcodec/x86/h264dsp_mmx.c +++ b/libavcodec/x86/h264dsp_mmx.c @@ -418,7 +418,7 @@ void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth) c->biweight_h264_pixels_tab[3]= ff_h264_biweight_8x8_ssse3; c->biweight_h264_pixels_tab[4]= ff_h264_biweight_8x4_ssse3; } - if (mm_flags&AV_CPU_FLAG_AVX) { + if (HAVE_AVX && mm_flags&AV_CPU_FLAG_AVX) { #if HAVE_ALIGNED_STACK c->h264_v_loop_filter_luma = ff_deblock_v_luma_8_avx; c->h264_h_loop_filter_luma = ff_deblock_h_luma_8_avx; From 5ad05dd500ba5dd46370808025951c55811a49bf Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Thu, 16 Jun 2011 23:16:58 +0200 Subject: [PATCH 028/109] Fix documentation for -ar and -ac. --- doc/ffmpeg.texi | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index fe9e9a9e92..4c02677437 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -557,10 +557,8 @@ The timestamps must be specified in ascending order. @item -aframes @var{number} Set the number of audio frames to record. @item -ar @var{freq} -Set the audio sampling frequency. For input streams it is set by -default to 44100 Hz, for output streams it is set by default to the -frequency of the input stream. If the input file has audio streams -with different frequencies, the behaviour is undefined. +Set the audio sampling frequency. there is no default for input streams, +for output streams it is set by default to the frequency of the input stream. @item -ab @var{bitrate} Set the audio bitrate in bit/s (default = 64k). @item -aq @var{q} @@ -568,8 +566,7 @@ Set the audio quality (codec-specific, VBR). @item -ac @var{channels} Set the number of audio channels. For input streams it is set by default to 1, for output streams it is set by default to the same -number of audio channels in input. If the input file has audio streams -with different channel count, the behaviour is undefined. +number of audio channels in input. @item -an Disable audio recording. @item -acodec @var{codec} From d5708923c2882b704db48f8a2f6b6afbb9cc7f34 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Thu, 16 Jun 2011 23:20:29 +0200 Subject: [PATCH 029/109] Move do_exit() and stream_close() up. --- ffplay.c | 102 +++++++++++++++++++++++++++---------------------------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/ffplay.c b/ffplay.c index 4145f9c24b..fa23884ed9 100644 --- a/ffplay.c +++ b/ffplay.c @@ -856,6 +856,57 @@ static void video_audio_display(VideoState *s) } } +static void stream_close(VideoState *is) +{ + VideoPicture *vp; + int i; + /* XXX: use a special url_shutdown call to abort parse cleanly */ + is->abort_request = 1; + SDL_WaitThread(is->read_tid, NULL); + SDL_WaitThread(is->refresh_tid, NULL); + + /* free all pictures */ + for(i=0;ipictq[i]; +#if CONFIG_AVFILTER + if (vp->picref) { + avfilter_unref_buffer(vp->picref); + vp->picref = NULL; + } +#endif + if (vp->bmp) { + SDL_FreeYUVOverlay(vp->bmp); + vp->bmp = NULL; + } + } + SDL_DestroyMutex(is->pictq_mutex); + SDL_DestroyCond(is->pictq_cond); + SDL_DestroyMutex(is->subpq_mutex); + SDL_DestroyCond(is->subpq_cond); +#if !CONFIG_AVFILTER + if (is->img_convert_ctx) + sws_freeContext(is->img_convert_ctx); +#endif + av_free(is); +} + +static void do_exit(void) +{ + if (cur_stream) { + stream_close(cur_stream); + cur_stream = NULL; + } + uninit_opts(); +#if CONFIG_AVFILTER + avfilter_uninit(); +#endif + if (show_status) + printf("\n"); + SDL_Quit(); + av_log(NULL, AV_LOG_QUIET, ""); + exit(0); +} + static int video_open(VideoState *is){ int flags = SDL_HWSURFACE|SDL_ASYNCBLIT|SDL_HWACCEL; int w,h; @@ -1204,57 +1255,6 @@ retry: } } -static void stream_close(VideoState *is) -{ - VideoPicture *vp; - int i; - /* XXX: use a special url_shutdown call to abort parse cleanly */ - is->abort_request = 1; - SDL_WaitThread(is->read_tid, NULL); - SDL_WaitThread(is->refresh_tid, NULL); - - /* free all pictures */ - for(i=0;ipictq[i]; -#if CONFIG_AVFILTER - if (vp->picref) { - avfilter_unref_buffer(vp->picref); - vp->picref = NULL; - } -#endif - if (vp->bmp) { - SDL_FreeYUVOverlay(vp->bmp); - vp->bmp = NULL; - } - } - SDL_DestroyMutex(is->pictq_mutex); - SDL_DestroyCond(is->pictq_cond); - SDL_DestroyMutex(is->subpq_mutex); - SDL_DestroyCond(is->subpq_cond); -#if !CONFIG_AVFILTER - if (is->img_convert_ctx) - sws_freeContext(is->img_convert_ctx); -#endif - av_free(is); -} - -static void do_exit(void) -{ - if (cur_stream) { - stream_close(cur_stream); - cur_stream = NULL; - } - uninit_opts(); -#if CONFIG_AVFILTER - avfilter_uninit(); -#endif - if (show_status) - printf("\n"); - SDL_Quit(); - av_log(NULL, AV_LOG_QUIET, ""); - exit(0); -} - /* allocate a picture (needs to do that in main thread to avoid potential locking problems */ static void alloc_picture(void *opaque) From d8ee777021ac251c48274e7fd9864acb9e19a5cb Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Thu, 16 Jun 2011 23:21:19 +0200 Subject: [PATCH 030/109] Do not crash if SDL_SetVideoMode() fails. --- ffplay.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ffplay.c b/ffplay.c index fa23884ed9..31a683216f 100644 --- a/ffplay.c +++ b/ffplay.c @@ -945,7 +945,7 @@ static int video_open(VideoState *is){ #endif if (!screen) { fprintf(stderr, "SDL: could not set video mode - exiting\n"); - return -1; + do_exit(); } if (!window_title) window_title = input_filename; From 78440c007cd310bb27ac2af5fb7ea5b7555efc84 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 17 Jun 2011 06:39:42 +0200 Subject: [PATCH 031/109] lavc: add opt_find to AVCodecContext class. Fixes encoder private options, which are broken now in ffmpeg, because opt_default2() can't find them, thus making opt_default() to fail. --- libavcodec/options.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/libavcodec/options.c b/libavcodec/options.c index 8f9aec4ac2..ae9e0c902d 100644 --- a/libavcodec/options.c +++ b/libavcodec/options.c @@ -37,6 +37,25 @@ static const char* context_to_name(void* ptr) { return "NULL"; } +static const AVOption *opt_find(void *obj, const char *name, const char *unit, int opt_flags, int search_flags) +{ + AVCodecContext *s = obj; + AVCodec *c = NULL; + + if (s->priv_data) { + if (s->codec->priv_class) + return av_opt_find(s->priv_data, name, unit, opt_flags, search_flags); + return NULL; + } + + while ((c = av_codec_next(c))) { + const AVOption *o; + if (c->priv_class && (o = av_opt_find(&c->priv_class, name, unit, opt_flags, search_flags))) + return o; + } + return NULL; +} + #define OFFSET(x) offsetof(AVCodecContext,x) #define DEFAULT 0 //should be NAN but it does not work as it is not a constant in glibc as required by ANSI/ISO C //these names are too long to be readable @@ -457,7 +476,7 @@ static const AVOption options[]={ #undef D #undef DEFAULT -static const AVClass av_codec_context_class = { "AVCodecContext", context_to_name, options, LIBAVUTIL_VERSION_INT, OFFSET(log_level_offset) }; +static const AVClass av_codec_context_class = { "AVCodecContext", context_to_name, options, LIBAVUTIL_VERSION_INT, OFFSET(log_level_offset), .opt_find = opt_find}; void avcodec_get_context_defaults2(AVCodecContext *s, enum AVMediaType codec_type){ int flags=0; From 369c68c4e121d9f883e240604050daf7fac1b870 Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Thu, 16 Jun 2011 23:45:38 +0200 Subject: [PATCH 032/109] Support DTS in mp4/mov. --- libavformat/isom.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavformat/isom.c b/libavformat/isom.c index dcc3b74af3..33a448da34 100644 --- a/libavformat/isom.c +++ b/libavformat/isom.c @@ -57,6 +57,7 @@ const AVCodecTag ff_mp4_obj_type[] = { { CODEC_ID_VC1 , 0xA3 }, { CODEC_ID_DIRAC , 0xA4 }, { CODEC_ID_AC3 , 0xA5 }, + { CODEC_ID_DTS , 0xA9 }, /* mp4ra.org */ { CODEC_ID_VORBIS , 0xDD }, /* non standard, gpac uses it */ { CODEC_ID_DVD_SUBTITLE, 0xE0 }, /* non standard, see unsupported-embedded-subs-2.mp4 */ { CODEC_ID_QCELP , 0xE1 }, @@ -244,6 +245,8 @@ const AVCodecTag codec_movaudio_tags[] = { { CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') }, /* MPEG-4 AAC */ { CODEC_ID_AC3, MKTAG('a', 'c', '-', '3') }, /* ETSI TS 102 366 Annex F */ { CODEC_ID_AC3, MKTAG('s', 'a', 'c', '3') }, /* Nero Recode */ + { CODEC_ID_DTS, MKTAG('d', 't', 's', 'c') }, /* mp4ra.org */ + { CODEC_ID_DTS, MKTAG('D', 'T', 'S', ' ') }, /* non standard */ { CODEC_ID_AMR_NB, MKTAG('s', 'a', 'm', 'r') }, /* AMR-NB 3gp */ { CODEC_ID_AMR_WB, MKTAG('s', 'a', 'w', 'b') }, /* AMR-WB 3gp */ From 8055433b492fe971a145a07470119ef8c2c71571 Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Sat, 18 Jun 2011 02:02:31 +0200 Subject: [PATCH 033/109] graphparser: add missing NULL check in avfilter_graph_parse() Fix a crash occurring when open_inputs is NULL and *open_inputs is checked, the crash was introduced by the recent avfilter_graph_parse() syntax change. In particular, fix graph2dot crash. --- libavfilter/graphparser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/graphparser.c b/libavfilter/graphparser.c index d62ba8d205..5178eea4c6 100644 --- a/libavfilter/graphparser.c +++ b/libavfilter/graphparser.c @@ -387,7 +387,7 @@ int avfilter_graph_parse(AVFilterGraph *graph, const char *filters, goto fail; } - if (*open_inputs && !strcmp((*open_inputs)->name, "out") && curr_inputs) { + if (open_inputs && *open_inputs && !strcmp((*open_inputs)->name, "out") && curr_inputs) { /* Last output can be omitted if it is "[out]" */ const char *tmp = "[out]"; if ((ret = parse_outputs(&tmp, &curr_inputs, open_inputs, open_outputs, From bb3a2b723ab2f94d24cac86b692c52c781338e7d Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Sat, 18 Jun 2011 01:46:27 +0200 Subject: [PATCH 034/109] vsrc_color: add @file doxy Also remove outdated reference to color in vf_pad.c. --- libavfilter/vf_pad.c | 2 +- libavfilter/vsrc_color.c | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c index e41ebe8964..93d613d035 100644 --- a/libavfilter/vf_pad.c +++ b/libavfilter/vf_pad.c @@ -21,7 +21,7 @@ /** * @file - * video padding filter and color source + * video padding filter */ #include "avfilter.h" diff --git a/libavfilter/vsrc_color.c b/libavfilter/vsrc_color.c index dc73e1bafa..43f01e3f4d 100644 --- a/libavfilter/vsrc_color.c +++ b/libavfilter/vsrc_color.c @@ -18,6 +18,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +/** + * @file + * color source + */ + #include "avfilter.h" #include "libavutil/pixdesc.h" #include "libavutil/colorspace.h" From 0c6cf3fa7cc7a9e01a5b78fd11f10f81c4b49b77 Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Sat, 18 Jun 2011 01:47:37 +0200 Subject: [PATCH 035/109] vsrc_color: set output pos values to -1 -1 is more correct than 0, as the position in the file is undefined. --- libavfilter/vsrc_color.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/vsrc_color.c b/libavfilter/vsrc_color.c index 43f01e3f4d..6d8b5e9f1a 100644 --- a/libavfilter/vsrc_color.c +++ b/libavfilter/vsrc_color.c @@ -139,7 +139,7 @@ static int color_request_frame(AVFilterLink *link) AVFilterBufferRef *picref = avfilter_get_video_buffer(link, AV_PERM_WRITE, color->w, color->h); picref->video->sample_aspect_ratio = (AVRational) {1, 1}; picref->pts = av_rescale_q(color->pts++, color->time_base, AV_TIME_BASE_Q); - picref->pos = 0; + picref->pos = -1; avfilter_start_frame(link, avfilter_ref_buffer(picref, ~0)); ff_draw_rectangle(picref->data, picref->linesize, From 44d1b4088f2959912a27ffbffc5884db1b35a645 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 18 Jun 2011 02:44:17 +0200 Subject: [PATCH 036/109] qdm2: Fix alignment of local array. Fixes ticket270 Signed-off-by: Michael Niedermayer --- libavcodec/qdm2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c index b9252bab40..6eb836456c 100644 --- a/libavcodec/qdm2.c +++ b/libavcodec/qdm2.c @@ -175,6 +175,7 @@ typedef struct { DECLARE_ALIGNED(32, float, synth_buf)[MPA_MAX_CHANNELS][512*2]; int synth_buf_offset[MPA_MAX_CHANNELS]; DECLARE_ALIGNED(32, float, sb_samples)[MPA_MAX_CHANNELS][128][SBLIMIT]; + DECLARE_ALIGNED(32, float, samples)[MPA_MAX_CHANNELS * MPA_FRAME_SIZE]; /// Mixed temporary data used in decoding float tone_level[MPA_MAX_CHANNELS][30][64]; @@ -1598,7 +1599,6 @@ static void qdm2_calculate_fft (QDM2Context *q, int channel, int sub_packet) */ static void qdm2_synthesis_filter (QDM2Context *q, int index) { - float samples[MPA_MAX_CHANNELS * MPA_FRAME_SIZE]; int i, k, ch, sb_used, sub_sampling, dither_state = 0; /* copy sb_samples */ @@ -1610,7 +1610,7 @@ static void qdm2_synthesis_filter (QDM2Context *q, int index) q->sb_samples[ch][(8 * index) + i][k] = 0; for (ch = 0; ch < q->nb_channels; ch++) { - float *samples_ptr = samples + ch; + float *samples_ptr = q->samples + ch; for (i = 0; i < 8; i++) { ff_mpa_synth_filter_float(&q->mpadsp, @@ -1627,7 +1627,7 @@ static void qdm2_synthesis_filter (QDM2Context *q, int index) for (ch = 0; ch < q->channels; ch++) for (i = 0; i < q->frame_size; i++) - q->output_buffer[q->channels * i + ch] += (1 << 23) * samples[q->nb_channels * sub_sampling * i + ch]; + q->output_buffer[q->channels * i + ch] += (1 << 23) * q->samples[q->nb_channels * sub_sampling * i + ch]; } From 47a8243c0db3fe497c490dfe2727a7a8422596cb Mon Sep 17 00:00:00 2001 From: Carl Eugen Hoyos Date: Sat, 18 Jun 2011 09:36:07 +0200 Subject: [PATCH 037/109] Fix -s documentation. --- doc/ffmpeg.texi | 1 - 1 file changed, 1 deletion(-) diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index 4c02677437..6f21451219 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -169,7 +169,6 @@ Set frame rate (Hz value, fraction or abbreviation), (default = 25). Set frame size. The format is @samp{wxh} (ffserver default = 160x128). There is no default for input streams, for output streams it is set by default to the size of the source stream. -If the input file has video streams with different resolutions, the behaviour is undefined. The following abbreviations are recognized: @table @samp @item sqcif From bde8055963ff3831091bf58a7b866e9eaaf7b3f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20B=C5=93sch?= Date: Wed, 15 Jun 2011 20:26:57 +0200 Subject: [PATCH 038/109] dcaenc: small quantization simplification. --- libavcodec/dcaenc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libavcodec/dcaenc.c b/libavcodec/dcaenc.c index 2b61bec98c..eccff08c03 100644 --- a/libavcodec/dcaenc.c +++ b/libavcodec/dcaenc.c @@ -365,8 +365,7 @@ static inline uint32_t quantize(int32_t sample, int bits) { av_assert0(sample < 1 << (bits - 1)); av_assert0(sample >= -(1 << (bits - 1))); - sample &= sample & ((1 << bits) - 1); - return sample; + return sample & ((1 << bits) - 1); } static inline int find_scale_factor7(int64_t max_value, int bits) From f188a1e0ca12822fd6c607924169d678c7254838 Mon Sep 17 00:00:00 2001 From: Daniel Kang Date: Sun, 5 Jun 2011 18:33:23 -0400 Subject: [PATCH 039/109] H.264: Add x86 assembly for 10-bit MC Chroma H.264 functions. Mainly ported from 8-bit H.264 MC Chroma. Signed-off-by: Ronald S. Bultje --- libavcodec/x86/Makefile | 1 + libavcodec/x86/dsputil_mmx.c | 32 +++ libavcodec/x86/h264_chromamc_10bit.asm | 273 +++++++++++++++++++++++++ 3 files changed, 306 insertions(+) create mode 100644 libavcodec/x86/h264_chromamc_10bit.asm diff --git a/libavcodec/x86/Makefile b/libavcodec/x86/Makefile index 1c451c8352..ea57bd1db6 100644 --- a/libavcodec/x86/Makefile +++ b/libavcodec/x86/Makefile @@ -44,6 +44,7 @@ MMX-OBJS-$(HAVE_YASM) += x86/dsputil_yasm.o \ x86/deinterlace.o \ x86/fmtconvert.o \ x86/h264_chromamc.o \ + x86/h264_chromamc_10bit.o \ $(YASM-OBJS-yes) MMX-OBJS-$(CONFIG_FFT) += x86/fft.o diff --git a/libavcodec/x86/dsputil_mmx.c b/libavcodec/x86/dsputil_mmx.c index 214c6a3945..b174b8393f 100644 --- a/libavcodec/x86/dsputil_mmx.c +++ b/libavcodec/x86/dsputil_mmx.c @@ -1938,6 +1938,19 @@ void ff_avg_h264_chroma_mc8_ssse3_rnd (uint8_t *dst, uint8_t *src, void ff_avg_h264_chroma_mc4_ssse3 (uint8_t *dst, uint8_t *src, int stride, int h, int x, int y); +#define CHROMA_MC(OP, NUM, DEPTH, OPT) \ +void ff_ ## OP ## _h264_chroma_mc ## NUM ## _ ## DEPTH ## _ ## OPT \ + (uint8_t *dst, uint8_t *src,\ + int stride, int h, int x, int y); + +CHROMA_MC(put, 2, 10, mmxext) +CHROMA_MC(avg, 2, 10, mmxext) +CHROMA_MC(put, 4, 10, mmxext) +CHROMA_MC(avg, 4, 10, mmxext) +CHROMA_MC(put, 8, 10, sse2) +CHROMA_MC(avg, 8, 10, sse2) +CHROMA_MC(put, 8, 10, avx) +CHROMA_MC(avg, 8, 10, avx) /* CAVS specific */ void ff_put_cavs_qpel8_mc00_mmx2(uint8_t *dst, uint8_t *src, int stride) { @@ -2420,6 +2433,7 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) { int mm_flags = av_get_cpu_flags(); const int high_bit_depth = avctx->codec_id == CODEC_ID_H264 && avctx->bits_per_raw_sample > 8; + const int bit_depth = avctx->bits_per_raw_sample; if (avctx->dsp_mask) { if (avctx->dsp_mask & AV_CPU_FLAG_FORCE) @@ -2651,6 +2665,12 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) c->avg_h264_chroma_pixels_tab[2]= ff_avg_h264_chroma_mc2_mmx2; c->put_h264_chroma_pixels_tab[2]= ff_put_h264_chroma_mc2_mmx2; } + if (bit_depth == 10) { + c->put_h264_chroma_pixels_tab[2]= ff_put_h264_chroma_mc2_10_mmxext; + c->avg_h264_chroma_pixels_tab[2]= ff_avg_h264_chroma_mc2_10_mmxext; + c->put_h264_chroma_pixels_tab[1]= ff_put_h264_chroma_mc4_10_mmxext; + c->avg_h264_chroma_pixels_tab[1]= ff_avg_h264_chroma_mc4_10_mmxext; + } c->add_hfyu_median_prediction = ff_add_hfyu_median_prediction_mmx2; #endif @@ -2756,6 +2776,10 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) H264_QPEL_FUNCS(3, 2, sse2); H264_QPEL_FUNCS(3, 3, sse2); } + if (bit_depth == 10) { + c->put_h264_chroma_pixels_tab[0]= ff_put_h264_chroma_mc8_10_sse2; + c->avg_h264_chroma_pixels_tab[0]= ff_avg_h264_chroma_mc8_10_sse2; + } } #if HAVE_SSSE3 if(mm_flags & AV_CPU_FLAG_SSSE3){ @@ -2854,6 +2878,14 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) } #endif } +#if HAVE_AVX + if (mm_flags & AV_CPU_FLAG_AVX) { + if (bit_depth == 10) { + c->put_h264_chroma_pixels_tab[0]= ff_put_h264_chroma_mc8_10_avx; + c->avg_h264_chroma_pixels_tab[0]= ff_avg_h264_chroma_mc8_10_avx; + } + } +#endif } if (CONFIG_ENCODERS) diff --git a/libavcodec/x86/h264_chromamc_10bit.asm b/libavcodec/x86/h264_chromamc_10bit.asm new file mode 100644 index 0000000000..9d075434fe --- /dev/null +++ b/libavcodec/x86/h264_chromamc_10bit.asm @@ -0,0 +1,273 @@ +;***************************************************************************** +;* MMX/SSE2/AVX-optimized 10-bit H.264 chroma MC code +;***************************************************************************** +;* Copyright (C) 2005-2011 x264 project +;* +;* Authors: Daniel Kang +;* +;* This file is part of Libav. +;* +;* Libav 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. +;* +;* Libav 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 Libav; if not, write to the Free Software +;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +;****************************************************************************** + +%include "x86inc.asm" +%include "x86util.asm" + +SECTION_RODATA + +cextern pw_4 +cextern pw_8 +cextern pw_32 +cextern pw_64 + +SECTION .text + + +%macro MV0_PIXELS_MC8 0 + lea r4, [r2*3 ] + lea r5, [r2*4 ] +.next4rows + movu m0, [r1 ] + movu m1, [r1+r2 ] + CHROMAMC_AVG m0, [r0 ] + CHROMAMC_AVG m1, [r0+r2 ] + mova [r0 ], m0 + mova [r0+r2 ], m1 + movu m0, [r1+r2*2] + movu m1, [r1+r4 ] + CHROMAMC_AVG m0, [r0+r2*2] + CHROMAMC_AVG m1, [r0+r4 ] + mova [r0+r2*2], m0 + mova [r0+r4 ], m1 + add r1, r5 + add r0, r5 + sub r3d, 4 + jne .next4rows +%endmacro + +;----------------------------------------------------------------------------- +; void put/avg_h264_chroma_mc8(pixel *dst, pixel *src, int stride, int h, int mx, int my) +;----------------------------------------------------------------------------- +%macro CHROMA_MC8 2 +; put/avg_h264_chroma_mc8_*(uint8_t *dst /*align 8*/, uint8_t *src /*align 1*/, +; int stride, int h, int mx, int my) +cglobal %1_h264_chroma_mc8_10_%2, 6,7,8 + movsxdifnidn r2, r2d + mov r6d, r5d + or r6d, r4d + jne .at_least_one_non_zero + ; mx == 0 AND my == 0 - no filter needed + MV0_PIXELS_MC8 + REP_RET + +.at_least_one_non_zero + mov r6d, 2 + test r5d, r5d + je .x_interpolation + mov r6, r2 ; dxy = x ? 1 : stride + test r4d, r4d + jne .xy_interpolation +.x_interpolation + ; mx == 0 XOR my == 0 - 1 dimensional filter only + or r4d, r5d ; x + y + movd m5, r4d + mova m4, [pw_8] + mova m6, [pw_4] ; mm6 = rnd >> 3 + SPLATW m5, m5 ; mm5 = B = x + psubw m4, m5 ; mm4 = A = 8-x + +.next1drow + movu m0, [r1 ] ; mm0 = src[0..7] + movu m2, [r1+r6] ; mm2 = src[1..8] + + pmullw m0, m4 ; mm0 = A * src[0..7] + pmullw m2, m5 ; mm2 = B * src[1..8] + + paddw m0, m6 + paddw m0, m2 + psrlw m0, 3 + CHROMAMC_AVG m0, [r0] + mova [r0], m0 ; dst[0..7] = (A * src[0..7] + B * src[1..8] + (rnd >> 3)) >> 3 + + add r0, r2 + add r1, r2 + dec r3d + jne .next1drow + REP_RET + +.xy_interpolation ; general case, bilinear + movd m4, r4m ; x + movd m6, r5m ; y + + SPLATW m4, m4 ; mm4 = x words + SPLATW m6, m6 ; mm6 = y words + psllw m5, m4, 3 ; mm5 = 8x + pmullw m4, m6 ; mm4 = x * y + psllw m6, 3 ; mm6 = 8y + paddw m1, m5, m6 ; mm7 = 8x+8y + mova m7, m4 ; DD = x * y + psubw m5, m4 ; mm5 = B = 8x - xy + psubw m6, m4 ; mm6 = C = 8y - xy + paddw m4, [pw_64] + psubw m4, m1 ; mm4 = A = xy - (8x+8y) + 64 + + movu m0, [r1 ] ; mm0 = src[0..7] + movu m1, [r1+2] ; mm1 = src[1..8] +.next2drow + add r1, r2 + + pmullw m2, m0, m4 + pmullw m1, m5 + paddw m2, m1 ; mm2 = A * src[0..7] + B * src[1..8] + + movu m0, [r1] + movu m1, [r1+2] + pmullw m3, m0, m6 + paddw m2, m3 ; mm2 += C * src[0..7+strde] + pmullw m3, m1, m7 + paddw m2, m3 ; mm2 += D * src[1..8+strde] + + paddw m2, [pw_32] + psrlw m2, 6 + CHROMAMC_AVG m2, [r0] + mova [r0], m2 ; dst[0..7] = (mm2 + 32) >> 6 + + add r0, r2 + dec r3d + jne .next2drow + REP_RET +%endmacro + +;----------------------------------------------------------------------------- +; void put/avg_h264_chroma_mc4(pixel *dst, pixel *src, int stride, int h, int mx, int my) +;----------------------------------------------------------------------------- +;TODO: xmm mc4 +%macro MC4_OP 2 + movq %1, [r1 ] + movq m1, [r1+2] + add r1, r2 + pmullw %1, m4 + pmullw m1, m2 + paddw m1, %1 + mova %1, m1 + + pmullw %2, m5 + pmullw m1, m3 + paddw %2, [pw_32] + paddw m1, %2 + psrlw m1, 6 + CHROMAMC_AVG m1, %2, [r0] + movq [r0], m1 + add r0, r2 +%endmacro + +%macro CHROMA_MC4 2 +cglobal %1_h264_chroma_mc4_10_%2, 6,6,7 + movsxdifnidn r2, r2d + movd m2, r4m ; x + movd m3, r5m ; y + mova m4, [pw_8] + mova m5, m4 + SPLATW m2, m2 + SPLATW m3, m3 + psubw m4, m2 + psubw m5, m3 + + movq m0, [r1 ] + movq m6, [r1+2] + add r1, r2 + pmullw m0, m4 + pmullw m6, m2 + paddw m6, m0 + +.next2rows + MC4_OP m0, m6 + MC4_OP m6, m0 + sub r3d, 2 + jnz .next2rows + REP_RET +%endmacro + +;----------------------------------------------------------------------------- +; void put/avg_h264_chroma_mc2(pixel *dst, pixel *src, int stride, int h, int mx, int my) +;----------------------------------------------------------------------------- +%macro CHROMA_MC2 2 +cglobal %1_h264_chroma_mc2_10_%2, 6,7 + movsxdifnidn r2, r2d + mov r6d, r4d + shl r4d, 16 + sub r4d, r6d + add r4d, 8 + imul r5d, r4d ; x*y<<16 | y*(8-x) + shl r4d, 3 + sub r4d, r5d ; x*(8-y)<<16 | (8-x)*(8-y) + + movd m5, r4d + movd m6, r5d + punpckldq m5, m5 ; mm5 = {A,B,A,B} + punpckldq m6, m6 ; mm6 = {C,D,C,D} + pxor m7, m7 + pshufw m2, [r1], 0x94 ; mm0 = src[0,1,1,2] + +.nextrow + add r1, r2 + movq m1, m2 + pmaddwd m1, m5 ; mm1 = A * src[0,1] + B * src[1,2] + pshufw m0, [r1], 0x94 ; mm0 = src[0,1,1,2] + movq m2, m0 + pmaddwd m0, m6 + paddw m1, [pw_32] + paddw m1, m0 ; mm1 += C * src[0,1] + D * src[1,2] + psrlw m1, 6 + packssdw m1, m7 + CHROMAMC_AVG m1, m3, [r0] + movd [r0], m1 + add r0, r2 + dec r3d + jnz .nextrow + REP_RET +%endmacro + +%macro NOTHING 2-3 +%endmacro +%macro AVG 2-3 +%if %0==3 + movq %2, %3 +%endif + PAVG %1, %2 +%endmacro + +%define CHROMAMC_AVG NOTHING +INIT_XMM +CHROMA_MC8 put, sse2 +%ifdef HAVE_AVX +INIT_AVX +CHROMA_MC8 put, avx +%endif +INIT_MMX +CHROMA_MC4 put, mmxext +CHROMA_MC2 put, mmxext + +%define CHROMAMC_AVG AVG +%define PAVG pavgw +INIT_XMM +CHROMA_MC8 avg, sse2 +%ifdef HAVE_AVX +INIT_AVX +CHROMA_MC8 avg, avx +%endif +INIT_MMX +CHROMA_MC4 avg, mmxext +CHROMA_MC2 avg, mmxext From ed63f527f28d1d73589a9e0bac3aed2197f14887 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Sat, 18 Jun 2011 08:34:14 -0400 Subject: [PATCH 040/109] Fix build if yasm is not available. --- libavcodec/x86/dsputil_mmx.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libavcodec/x86/dsputil_mmx.c b/libavcodec/x86/dsputil_mmx.c index b174b8393f..5c5ecb2d65 100644 --- a/libavcodec/x86/dsputil_mmx.c +++ b/libavcodec/x86/dsputil_mmx.c @@ -2776,10 +2776,12 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) H264_QPEL_FUNCS(3, 2, sse2); H264_QPEL_FUNCS(3, 3, sse2); } +#if HAVE_YASM if (bit_depth == 10) { c->put_h264_chroma_pixels_tab[0]= ff_put_h264_chroma_mc8_10_sse2; c->avg_h264_chroma_pixels_tab[0]= ff_avg_h264_chroma_mc8_10_sse2; } +#endif } #if HAVE_SSSE3 if(mm_flags & AV_CPU_FLAG_SSSE3){ @@ -2878,7 +2880,7 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) } #endif } -#if HAVE_AVX +#if HAVE_AVX && HAVE_YASM if (mm_flags & AV_CPU_FLAG_AVX) { if (bit_depth == 10) { c->put_h264_chroma_pixels_tab[0]= ff_put_h264_chroma_mc8_10_avx; From 84bd2b4bf5ca544e29c48634ac8b2899c58b0d9d Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 18 Jun 2011 17:26:40 +0200 Subject: [PATCH 041/109] lavf: add a forgotten NULL check in convert_format_parameters(). --- libavformat/utils.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavformat/utils.c b/libavformat/utils.c index e3485e6ffa..81bc9b70c3 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -395,6 +395,9 @@ static AVDictionary *convert_format_parameters(AVFormatParameters *ap) char buf[1024]; AVDictionary *opts = NULL; + if (!ap) + return NULL; + if (ap->time_base.num) { snprintf(buf, sizeof(buf), "%d/%d", ap->time_base.den, ap->time_base.num); av_dict_set(&opts, "framerate", buf, 0); From bed31c7e3c530f9237bbb9fb96507be5977d9f65 Mon Sep 17 00:00:00 2001 From: Reinhard Tartler Date: Thu, 16 Jun 2011 19:59:47 +0200 Subject: [PATCH 042/109] more Changelog additions --- Changelog | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Changelog b/Changelog index 38f07b1440..a5044498a5 100644 --- a/Changelog +++ b/Changelog @@ -2,23 +2,27 @@ Entries are sorted chronologically from oldest to youngest within each release, releases are sorted from youngest to oldest. -version : +version 0.7: - E-AC-3 audio encoder - ac3enc: add channel coupling support - floating-point sample format support to the ac3, eac3, dca, aac, and vorbis decoders. - H264/MPEG frame-level multi-threading - All av_metadata_* functions renamed to av_dict_* and moved to libavutil +- 4:4:4 H.264 decoding support +- 10-bit H.264 optimizations for x86 version 0.7_beta2: +- VP8 frame-multithreading +- NEON optimizations for VP8 - Lots of deprecated API cruft removed - fft and imdct optimizations for AVX (Sandy Bridge) processors - DPX image encoder - SMPTE 302M AES3 audio decoder - Remove support for quitting ffmpeg with 'q', ctrl+c should be used. -- 9bit and 10bit per sample support in the h264 decoder +- 9bit and 10bit per sample support in the H.264 decoder version 0.7_beta1: From dbafb0e06faa092f60e53d845957fbab7f2a3f2d Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Sat, 18 Jun 2011 15:33:49 -0400 Subject: [PATCH 043/109] lavf: prevent crash in av_open_input_file() if ap == NULL. Needed for proper behaviour in our old API compatibility code. --- libavformat/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/utils.c b/libavformat/utils.c index 81bc9b70c3..7370c60bdf 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -549,7 +549,7 @@ int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, int err; AVDictionary *opts = convert_format_parameters(ap); - if (!ap->prealloced_context) + if (!ap || !ap->prealloced_context) *ic_ptr = NULL; err = avformat_open_input(ic_ptr, filename, fmt, &opts); From 34dc7aa82b3dcd95048b89a59730fbadf3ab3175 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 18 Jun 2011 21:53:20 +0200 Subject: [PATCH 044/109] libavcodec: add CODEC_CAP_LOSSLESS Signed-off-by: Michael Niedermayer --- libavcodec/avcodec.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index ef539a2a36..90c389b8c5 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -688,6 +688,10 @@ typedef struct RcOverride{ * Codec supports slice-based (or partition-based) multithreading. */ #define CODEC_CAP_SLICE_THREADS 0x2000 +/** + * Codec is lossless. + */ +#define CODEC_CAP_LOSSLESS 0x80000000 //The following defines may change, don't expect compatibility if you use them. #define MB_TYPE_INTRA4x4 0x0001 From 7ba262527fa87b3e6556b905a1b3cb0ad6ac2043 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 18 Jun 2011 21:53:54 +0200 Subject: [PATCH 045/109] flacenc: mark as lossless codec Signed-off-by: Michael Niedermayer --- libavcodec/flacenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c index b8d0e10631..a80f0f9fe3 100644 --- a/libavcodec/flacenc.c +++ b/libavcodec/flacenc.c @@ -1387,7 +1387,7 @@ AVCodec ff_flac_encoder = { flac_encode_frame, flac_encode_close, NULL, - .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY, + .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY | CODEC_CAP_LOSSLESS, .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE}, .long_name = NULL_IF_CONFIG_SMALL("FLAC (Free Lossless Audio Codec)"), .priv_class = &flac_encoder_class, From 035c13e307daeb2a250b86f0ddef3b783a6393e5 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 18 Jun 2011 21:54:11 +0200 Subject: [PATCH 046/109] ffmpeg: warn if samples need to be converted in a lossy way for lossless encoders. Signed-off-by: Michael Niedermayer --- ffmpeg.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ffmpeg.c b/ffmpeg.c index 4e8ac200da..2921a06ddf 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -617,6 +617,8 @@ static void choose_sample_fmt(AVStream *st, AVCodec *codec) break; } if (*p == -1) { + if((codec->capabilities & CODEC_CAP_LOSSLESS) && av_get_sample_fmt_name(st->codec->sample_fmt) > av_get_sample_fmt_name(codec->sample_fmts[0])) + av_log(NULL, AV_LOG_ERROR, "Convertion will not be lossless'\n"); av_log(NULL, AV_LOG_WARNING, "Incompatible sample format '%s' for codec '%s', auto-selecting format '%s'\n", av_get_sample_fmt_name(st->codec->sample_fmt), From 0aed4f81fe5b9b15ab9b35baa4300f29ab03d65f Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 18 Jun 2011 21:59:11 +0200 Subject: [PATCH 047/109] w32threads: with only 1 thread there cant be a active threading mode. Fixes ticket284 Signed-off-by: Michael Niedermayer --- libavcodec/w32thread.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/w32thread.c b/libavcodec/w32thread.c index 7c4c760e6c..501f0cebf3 100644 --- a/libavcodec/w32thread.c +++ b/libavcodec/w32thread.c @@ -135,11 +135,11 @@ int ff_thread_init(AVCodecContext *s){ return 0; } - s->active_thread_type= FF_THREAD_SLICE; - if (s->thread_count <= 1) return 0; + s->active_thread_type= FF_THREAD_SLICE; + assert(!s->thread_opaque); c= av_mallocz(sizeof(ThreadContext)*s->thread_count); s->thread_opaque= c; From a09a3e8213c74be18855bab8aee4a7c44a05bdfe Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 18 Jun 2011 23:59:27 +0200 Subject: [PATCH 048/109] jpegdec: fix CJPG decoding. Fixes ticket133 Signed-off-by: Michael Niedermayer --- libavcodec/mjpegdec.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 4e58feffad..d80dad78b7 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -993,8 +993,11 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, predictor= get_bits(&s->gb, 8); /* JPEG Ss / lossless JPEG predictor /JPEG-LS NEAR */ ilv= get_bits(&s->gb, 8); /* JPEG Se / JPEG-LS ILV */ - prev_shift = get_bits(&s->gb, 4); /* Ah */ - point_transform= get_bits(&s->gb, 4); /* Al */ + if(s->avctx->codec_tag != AV_RL32("CJPG")){ + prev_shift = get_bits(&s->gb, 4); /* Ah */ + point_transform= get_bits(&s->gb, 4); /* Al */ + }else + prev_shift= point_transform= 0; for(i=0;ilast_dc[i] = 1024; From 9291faeb6754787cd7f32feb8560219726a4da11 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 19 Jun 2011 00:00:52 +0200 Subject: [PATCH 049/109] jpegdec: include mjpb_skiptosod in debug output Signed-off-by: Michael Niedermayer --- libavcodec/mjpegdec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index d80dad78b7..02c66f504b 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -1017,8 +1017,8 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, } if(s->avctx->debug & FF_DEBUG_PICT_INFO) - av_log(s->avctx, AV_LOG_DEBUG, "%s %s p:%d >>:%d ilv:%d bits:%d %s\n", s->lossless ? "lossless" : "sequential DCT", s->rgb ? "RGB" : "", - predictor, point_transform, ilv, s->bits, + av_log(s->avctx, AV_LOG_DEBUG, "%s %s p:%d >>:%d ilv:%d bits:%d skip:%d %s\n", s->lossless ? "lossless" : "sequential DCT", s->rgb ? "RGB" : "", + predictor, point_transform, ilv, s->bits, s->mjpb_skiptosod, s->pegasus_rct ? "PRCT" : (s->rct ? "RCT" : "")); From a4233d1f95bfc5b9b0fd08f0aaafdd20b1c4dae0 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 19 Jun 2011 00:02:55 +0200 Subject: [PATCH 050/109] h264: print actual slice number in "Too many slices" warning Signed-off-by: Michael Niedermayer --- libavcodec/h264.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/h264.c b/libavcodec/h264.c index b88622d432..ca7867e11c 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -2984,7 +2984,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ h0->last_slice_type = slice_type; h->slice_num = ++h0->current_slice; if(h->slice_num >= MAX_SLICES){ - av_log(s->avctx, AV_LOG_ERROR, "Too many slices, increase MAX_SLICES and recompile\n"); + av_log(s->avctx, AV_LOG_ERROR, "Too many slices (%d >= %d), increase MAX_SLICES and recompile\n", h->slice_num, MAX_SLICES); } for(j=0; j<2; j++){ From 799a87d749b473a2ab2494daef905e5129c5c056 Mon Sep 17 00:00:00 2001 From: ami_stuff Date: Sun, 19 Jun 2011 01:47:25 +0200 Subject: [PATCH 051/109] avidec: Ignore unknown stream types Improves ticket131 Signed-off-by: Michael Niedermayer --- libavformat/avidec.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 0bcdd3fdec..72ea9e2944 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -554,8 +554,7 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) codec_type = AVMEDIA_TYPE_DATA; break; default: - av_log(s, AV_LOG_ERROR, "unknown stream type %X\n", tag1); - goto fail; + av_log(s, AV_LOG_INFO, "unknown stream type %X\n", tag1); } if(ast->sample_size == 0) st->duration = st->nb_frames; From 15b4f6449ddb1f52ae82dee3f94a5b56b636cbea Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 19 Jun 2011 03:33:15 +0200 Subject: [PATCH 052/109] swscale: fix mono input for width%8 Fixes ticket193 Signed-off-by: Michael Niedermayer --- libswscale/swscale.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libswscale/swscale.c b/libswscale/swscale.c index 4318e0bf15..abbe375685 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -1677,6 +1677,11 @@ static void monowhite2Y_c(int16_t *dst, const uint8_t *src, int width, uint32_t for(j=0; j<8; j++) dst[8*i+j]= ((d>>(7-j))&1)*16383; } + if(width&7){ + int d= ~src[i]; + for(j=0; j<(width&7); j++) + dst[8*i+j]= ((d>>(7-j))&1)*16383; + } } static void monoblack2Y_c(int16_t *dst, const uint8_t *src, int width, uint32_t *unused) @@ -1687,6 +1692,11 @@ static void monoblack2Y_c(int16_t *dst, const uint8_t *src, int width, uint32_t for(j=0; j<8; j++) dst[8*i+j]= ((d>>(7-j))&1)*16383; } + if(width&7){ + int d= src[i]; + for(j=0; j<(width&7); j++) + dst[8*i+j]= ((d>>(7-j))&1)*16383; + } } //FIXME yuy2* can read up to 7 samples too much From 0c17beba97c600b38926f98e11f0436e20445261 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Fri, 17 Jun 2011 22:03:24 -0700 Subject: [PATCH 053/109] h264: drop some ugly casts --- libavcodec/h264.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/h264.c b/libavcodec/h264.c index ad591269c6..b42468a781 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -1014,7 +1014,7 @@ int ff_h264_decode_extradata(H264Context *h) { AVCodecContext *avctx = h->s.avctx; - if(*(char *)avctx->extradata == 1){ + if(avctx->extradata[0] == 1){ int i, cnt, nalsize; unsigned char *p = avctx->extradata; @@ -1049,7 +1049,7 @@ int ff_h264_decode_extradata(H264Context *h) p += nalsize; } // Now store right nal length size, that will be use to parse all other nals - h->nal_length_size = ((*(((char*)(avctx->extradata))+4))&0x03)+1; + h->nal_length_size = (avctx->extradata[4] & 0x03) + 1; } else { h->is_avc = 0; if(decode_nal_units(h, avctx->extradata, avctx->extradata_size) < 0) From cb372931ff3e55e47965db7b02c01df1e1b6a043 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Sat, 18 Jun 2011 15:42:57 -0700 Subject: [PATCH 054/109] sipr: Use memmove() to copy overlapped buffers. --- libavcodec/sipr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/sipr.c b/libavcodec/sipr.c index 17e7e855ed..f4f12d8c4d 100644 --- a/libavcodec/sipr.c +++ b/libavcodec/sipr.c @@ -461,7 +461,7 @@ static void decode_frame(SiprContext *ctx, SiprParameters *params, memcpy(ctx->postfilter_syn5k0, ctx->postfilter_syn5k0 + frame_size, LP_FILTER_ORDER*sizeof(float)); } - memcpy(ctx->excitation, excitation - PITCH_DELAY_MAX - L_INTERPOL, + memmove(ctx->excitation, excitation - PITCH_DELAY_MAX - L_INTERPOL, (PITCH_DELAY_MAX + L_INTERPOL) * sizeof(float)); ff_acelp_apply_order_2_transfer_function(out_data, synth, From 1e3d5eec8e758cfdd76370c80b9d0cc76c2c7b84 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Sat, 18 Jun 2011 15:44:31 -0700 Subject: [PATCH 055/109] sipr: include string.h for mem*() --- libavcodec/sipr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/sipr.c b/libavcodec/sipr.c index f4f12d8c4d..85d1419ef9 100644 --- a/libavcodec/sipr.c +++ b/libavcodec/sipr.c @@ -23,6 +23,7 @@ #include #include +#include #include "libavutil/mathematics.h" #include "avcodec.h" From 4b84d5114d760627a990e66724e3a1e9e1d1286f Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Sat, 18 Jun 2011 15:45:45 -0700 Subject: [PATCH 056/109] sipr: Drop unused DSPContext --- libavcodec/sipr.c | 2 -- libavcodec/sipr.h | 1 - 2 files changed, 3 deletions(-) diff --git a/libavcodec/sipr.c b/libavcodec/sipr.c index 85d1419ef9..2e86861706 100644 --- a/libavcodec/sipr.c +++ b/libavcodec/sipr.c @@ -496,8 +496,6 @@ static av_cold int sipr_decoder_init(AVCodecContext * avctx) avctx->sample_fmt = AV_SAMPLE_FMT_FLT; - dsputil_init(&ctx->dsp, avctx); - return 0; } diff --git a/libavcodec/sipr.h b/libavcodec/sipr.h index 33984b1baf..5b2198ea87 100644 --- a/libavcodec/sipr.h +++ b/libavcodec/sipr.h @@ -55,7 +55,6 @@ typedef enum { typedef struct { AVCodecContext *avctx; - DSPContext dsp; SiprMode mode; From dd2793c880ea72c9aacda8245596694d9b4f378c Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Sat, 28 May 2011 21:51:03 +0200 Subject: [PATCH 057/109] lavfi: add LUT (LookUp Table) generic filters --- Changelog | 1 + doc/filters.texi | 112 ++++++++++++ libavfilter/Makefile | 3 + libavfilter/allfilters.c | 3 + libavfilter/avfilter.h | 2 +- libavfilter/vf_lut.c | 368 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 488 insertions(+), 1 deletion(-) create mode 100644 libavfilter/vf_lut.c diff --git a/Changelog b/Changelog index 975c3d4c88..7745fa0938 100644 --- a/Changelog +++ b/Changelog @@ -16,6 +16,7 @@ version 0.7: - All av_metadata_* functions renamed to av_dict_* and moved to libavutil - 4:4:4 H.264 decoding support - 10-bit H.264 optimizations for x86 +- lut, lutrgb, and lutyuv filters added version 0.7_beta2: diff --git a/doc/filters.texi b/doc/filters.texi index 719d94f45a..80a60835a5 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -701,6 +701,118 @@ a float number which specifies chroma temporal strength, defaults to @var{luma_tmp}*@var{chroma_spatial}/@var{luma_spatial} @end table +@section lut, lutrgb, lutyuv + +Compute a look-up table for binding each pixel component input value +to an output value, and apply it to input video. + +@var{lutyuv} applies a lookup table to a YUV input video, @var{lutrgb} +to an RGB input video. + +These filters accept in input a ":"-separated list of options, which +specify the expressions used for computing the lookup table for the +corresponding pixel component values. + +The @var{lut} filter requires either YUV or RGB pixel formats in +input, and accepts the options: +@table @option +@var{c0} (first pixel component) +@var{c1} (second pixel component) +@var{c2} (third pixel component) +@var{c3} (fourth pixel component, corresponds to the alpha component) +@end table + +The exact component associated to each option depends on the format in +input. + +The @var{lutrgb} filter requires RGB pixel formats in input, and +accepts the options: +@table @option +@var{r} (red component) +@var{g} (green component) +@var{b} (blue component) +@var{a} (alpha component) +@end table + +The @var{lutyuv} filter requires YUV pixel formats in input, and +accepts the options: +@table @option +@var{y} (Y/luminance component) +@var{u} (U/Cb component) +@var{v} (V/Cr component) +@var{a} (alpha component) +@end table + +The expressions can contain the following constants and functions: + +@table @option +@item E, PI, PHI +the corresponding mathematical approximated values for e +(euler number), pi (greek PI), PHI (golden ratio) + +@item w, h +the input width and heigth + +@item val +input value for the pixel component + +@item clipval +the input value clipped in the @var{minval}-@var{maxval} range + +@item maxval +maximum value for the pixel component + +@item minval +minimum value for the pixel component + +@item negval +the negated value for the pixel component value clipped in the +@var{minval}-@var{maxval} range , it corresponds to the expression +"maxval-clipval+minval" + +@item clip(val) +the computed value in @var{val} clipped in the +@var{minval}-@var{maxval} range + +@item gammaval(gamma) +the computed gamma correction value of the pixel component value +clipped in the @var{minval}-@var{maxval} range, corresponds to the +expression +"pow((clipval-minval)/(maxval-minval)\,@var{gamma})*(maxval-minval)+minval" + +@end table + +All expressions default to "val". + +Some examples follow: +@example +# negate input video +lutrgb="r=maxval+minval-val:g=maxval+minval-val:b=maxval+minval-val" +lutyuv="y=maxval+minval-val:u=maxval+minval-val:v=maxval+minval-val" + +# the above is the same as +lutrgb="r=negval:g=negval:b=negval" +lutyuv="y=negval:u=negval:v=negval" + +# negate luminance +lutyuv=negval + +# remove chroma components, turns the video into a graytone image +lutyuv="u=128:v=128" + +# apply a luma burning effect +lutyuv="y=2*val" + +# remove green and blue components +lutrgb="g=0:b=0" + +# set a constant alpha channel value on input +format=rgba,lutrgb=a="maxval-minval/2" + +# correct luminance gamma by a 0.5 factor +lutyuv=y=gammaval(0.5) +@end example + @section mp Apply an MPlayer filter to the input video. diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 2324fb999e..8f8abe729e 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -38,6 +38,9 @@ OBJS-$(CONFIG_FREI0R_FILTER) += vf_frei0r.o OBJS-$(CONFIG_GRADFUN_FILTER) += vf_gradfun.o OBJS-$(CONFIG_HFLIP_FILTER) += vf_hflip.o OBJS-$(CONFIG_HQDN3D_FILTER) += vf_hqdn3d.o +OBJS-$(CONFIG_LUT_FILTER) += vf_lut.o +OBJS-$(CONFIG_LUTRGB_FILTER) += vf_lut.o +OBJS-$(CONFIG_LUTYUV_FILTER) += vf_lut.o OBJS-$(CONFIG_MP_FILTER) += vf_mp.o OBJS-$(CONFIG_NOFORMAT_FILTER) += vf_format.o OBJS-$(CONFIG_NULL_FILTER) += vf_null.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 5f1065f23f..3c4a6e17b4 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -54,6 +54,9 @@ void avfilter_register_all(void) REGISTER_FILTER (GRADFUN, gradfun, vf); REGISTER_FILTER (HFLIP, hflip, vf); REGISTER_FILTER (HQDN3D, hqdn3d, vf); + REGISTER_FILTER (LUT, lut, vf); + REGISTER_FILTER (LUTRGB, lutrgb, vf); + REGISTER_FILTER (LUTYUV, lutyuv, vf); REGISTER_FILTER (MP, mp, vf); REGISTER_FILTER (NOFORMAT, noformat, vf); REGISTER_FILTER (NULL, null, vf); diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index 7628cd51ec..6dd5020ecf 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -26,7 +26,7 @@ #include "libavutil/samplefmt.h" #define LIBAVFILTER_VERSION_MAJOR 2 -#define LIBAVFILTER_VERSION_MINOR 18 +#define LIBAVFILTER_VERSION_MINOR 19 #define LIBAVFILTER_VERSION_MICRO 0 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavfilter/vf_lut.c b/libavfilter/vf_lut.c new file mode 100644 index 0000000000..895293d12d --- /dev/null +++ b/libavfilter/vf_lut.c @@ -0,0 +1,368 @@ +/* + * Copyright (c) 2011 Stefano Sabatini + * + * 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 + */ + +/** + * @file + * Compute a look-up table for binding the input value to the output + * value, and apply it to input video. + */ + +#include "libavutil/eval.h" +#include "libavutil/opt.h" +#include "libavutil/pixdesc.h" +#include "avfilter.h" + +static const char *var_names[] = { + "E", + "PHI", + "PI", + "w", ///< width of the input video + "h", ///< height of the input video + "val", ///< input value for the pixel + "maxval", ///< max value for the pixel + "minval", ///< min value for the pixel + "negval", ///< negated value + "clipval", + NULL +}; + +enum var_name { + VAR_E, + VAR_PHI, + VAR_PI, + VAR_W, + VAR_H, + VAR_VAL, + VAR_MAXVAL, + VAR_MINVAL, + VAR_NEGVAL, + VAR_CLIPVAL, + VAR_VARS_NB +}; + +typedef struct { + const AVClass *class; + uint8_t lut[4][256]; ///< lookup table for each component + char *comp_expr_str[4]; + AVExpr *comp_expr[4]; + int hsub, vsub; + double var_values[VAR_VARS_NB]; + int is_rgb, is_yuv; + int rgba_map[4]; + int step; +} LutContext; + +#define Y 0 +#define U 1 +#define V 2 +#define R 0 +#define G 1 +#define B 2 +#define A 3 + +#define OFFSET(x) offsetof(LutContext, x) + +static const AVOption lut_options[] = { + {"c0", "set component #0 expression", OFFSET(comp_expr_str[0]), FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX}, + {"c1", "set component #1 expression", OFFSET(comp_expr_str[1]), FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX}, + {"c2", "set component #2 expression", OFFSET(comp_expr_str[2]), FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX}, + {"c3", "set component #3 expression", OFFSET(comp_expr_str[3]), FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX}, + {"y", "set Y expression", OFFSET(comp_expr_str[Y]), FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX}, + {"u", "set U expression", OFFSET(comp_expr_str[U]), FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX}, + {"v", "set V expression", OFFSET(comp_expr_str[V]), FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX}, + {"r", "set R expression", OFFSET(comp_expr_str[R]), FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX}, + {"g", "set G expression", OFFSET(comp_expr_str[G]), FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX}, + {"b", "set B expression", OFFSET(comp_expr_str[B]), FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX}, + {"a", "set A expression", OFFSET(comp_expr_str[A]), FF_OPT_TYPE_STRING, {.str="val"}, CHAR_MIN, CHAR_MAX}, + {NULL}, +}; + +static const char *lut_get_name(void *ctx) +{ + return "lut"; +} + +static const AVClass lut_class = { + "LutContext", + lut_get_name, + lut_options +}; + +static int init(AVFilterContext *ctx, const char *args, void *opaque) +{ + LutContext *lut = ctx->priv; + int ret; + + lut->class = &lut_class; + av_opt_set_defaults2(lut, 0, 0); + + lut->var_values[VAR_PHI] = M_PHI; + lut->var_values[VAR_PI] = M_PI; + lut->var_values[VAR_E ] = M_E; + + lut->is_rgb = !strcmp(ctx->filter->name, "lutrgb"); + lut->is_yuv = !strcmp(ctx->filter->name, "lutyuv"); + if (args && (ret = av_set_options_string(lut, args, "=", ":")) < 0) + return ret; + + return 0; +} + +static av_cold void uninit(AVFilterContext *ctx) +{ + LutContext *lut = ctx->priv; + int i; + + for (i = 0; i < 4; i++) { + av_expr_free(lut->comp_expr[i]); + lut->comp_expr[i] = NULL; + av_freep(&lut->comp_expr_str[i]); + } +} + +#define YUV_FORMATS \ + PIX_FMT_YUV444P, PIX_FMT_YUV422P, PIX_FMT_YUV420P, \ + PIX_FMT_YUV411P, PIX_FMT_YUV410P, PIX_FMT_YUV440P, \ + PIX_FMT_YUVA420P, \ + PIX_FMT_YUVJ444P, PIX_FMT_YUVJ422P, PIX_FMT_YUVJ420P, \ + PIX_FMT_YUVJ440P + +#define RGB_FORMATS \ + PIX_FMT_ARGB, PIX_FMT_RGBA, \ + PIX_FMT_ABGR, PIX_FMT_BGRA, \ + PIX_FMT_RGB24, PIX_FMT_BGR24 + +static enum PixelFormat yuv_pix_fmts[] = { YUV_FORMATS, PIX_FMT_NONE }; +static enum PixelFormat rgb_pix_fmts[] = { RGB_FORMATS, PIX_FMT_NONE }; +static enum PixelFormat all_pix_fmts[] = { RGB_FORMATS, YUV_FORMATS, PIX_FMT_NONE }; + +static int query_formats(AVFilterContext *ctx) +{ + LutContext *lut = ctx->priv; + + enum PixelFormat *pix_fmts = lut->is_rgb ? rgb_pix_fmts : + lut->is_yuv ? yuv_pix_fmts : all_pix_fmts; + + avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + return 0; +} + +static int pix_fmt_is_in(enum PixelFormat pix_fmt, enum PixelFormat *pix_fmts) +{ + enum PixelFormat *p; + for (p = pix_fmts; *p != PIX_FMT_NONE; p++) { + if (pix_fmt == *p) + return 1; + } + return 0; +} + +/** + * Clip value val in the minval - maxval range. + */ +static double clip(void *opaque, double val) +{ + LutContext *lut = opaque; + double minval = lut->var_values[VAR_MINVAL]; + double maxval = lut->var_values[VAR_MAXVAL]; + + return av_clip(val, minval, maxval); +} + +/** + * Compute gamma correction for value val, assuming the minval-maxval + * range, val is clipped to a value contained in the same interval. + */ +static double compute_gammaval(void *opaque, double gamma) +{ + LutContext *lut = opaque; + double val = lut->var_values[VAR_CLIPVAL]; + double minval = lut->var_values[VAR_MINVAL]; + double maxval = lut->var_values[VAR_MAXVAL]; + + return pow((val-minval)/(maxval-minval), gamma) * (maxval-minval)+minval; +} + +static double (* const funcs1[])(void *, double) = { + (void *)clip, + (void *)compute_gammaval, + NULL +}; + +static const char * const funcs1_names[] = { + "clip", + "gammaval", + NULL +}; + +static int config_props(AVFilterLink *inlink) +{ + AVFilterContext *ctx = inlink->dst; + LutContext *lut = ctx->priv; + const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[inlink->format]; + int min[4], max[4]; + int val, comp, ret; + + lut->hsub = desc->log2_chroma_w; + lut->vsub = desc->log2_chroma_h; + + lut->var_values[VAR_W] = inlink->w; + lut->var_values[VAR_H] = inlink->h; + + switch (inlink->format) { + case PIX_FMT_YUV410P: + case PIX_FMT_YUV411P: + case PIX_FMT_YUV420P: + case PIX_FMT_YUV422P: + case PIX_FMT_YUV440P: + case PIX_FMT_YUV444P: + case PIX_FMT_YUVA420P: + min[Y] = min[U] = min[V] = 16; + max[Y] = 235; + max[U] = max[V] = 240; + break; + default: + min[0] = min[1] = min[2] = min[3] = 0; + max[0] = max[1] = max[2] = max[3] = 255; + } + + lut->is_yuv = lut->is_rgb = 0; + if (pix_fmt_is_in(inlink->format, yuv_pix_fmts)) lut->is_yuv = 1; + else if (pix_fmt_is_in(inlink->format, rgb_pix_fmts)) lut->is_rgb = 1; + + if (lut->is_rgb) { + switch (inlink->format) { + case PIX_FMT_ARGB: lut->rgba_map[A] = 0; lut->rgba_map[R] = 1; lut->rgba_map[G] = 2; lut->rgba_map[B] = 3; break; + case PIX_FMT_ABGR: lut->rgba_map[A] = 0; lut->rgba_map[B] = 1; lut->rgba_map[G] = 2; lut->rgba_map[R] = 3; break; + case PIX_FMT_RGBA: + case PIX_FMT_RGB24: lut->rgba_map[R] = 0; lut->rgba_map[G] = 1; lut->rgba_map[B] = 2; lut->rgba_map[A] = 3; break; + case PIX_FMT_BGRA: + case PIX_FMT_BGR24: lut->rgba_map[B] = 0; lut->rgba_map[G] = 1; lut->rgba_map[R] = 2; lut->rgba_map[A] = 3; break; + } + lut->step = av_get_bits_per_pixel(desc) >> 3; + } + + for (comp = 0; comp < desc->nb_components; comp++) { + double res; + + /* create the parsed expression */ + ret = av_expr_parse(&lut->comp_expr[comp], lut->comp_expr_str[comp], + var_names, funcs1_names, funcs1, NULL, NULL, 0, ctx); + if (ret < 0) { + av_log(ctx, AV_LOG_ERROR, + "Error when parsing the expression '%s' for the component %d.\n", + lut->comp_expr_str[comp], comp); + return AVERROR(EINVAL); + } + + /* compute the lut */ + lut->var_values[VAR_MAXVAL] = max[comp]; + lut->var_values[VAR_MINVAL] = min[comp]; + + for (val = 0; val < 256; val++) { + lut->var_values[VAR_VAL] = val; + lut->var_values[VAR_CLIPVAL] = av_clip(val, min[comp], max[comp]); + lut->var_values[VAR_NEGVAL] = + av_clip(min[comp] + max[comp] - lut->var_values[VAR_VAL], + min[comp], max[comp]); + + res = av_expr_eval(lut->comp_expr[comp], lut->var_values, lut); + if (isnan(res)) { + av_log(ctx, AV_LOG_ERROR, + "Error when evaluating the expression '%s' for the value %d for the component #%d.\n", + lut->comp_expr_str[comp], val, comp); + return AVERROR(EINVAL); + } + lut->lut[comp][val] = av_clip((int)res, min[comp], max[comp]); + av_log(ctx, AV_LOG_DEBUG, "val[%d][%d] = %d\n", comp, val, lut->lut[comp][val]); + } + } + + return 0; +} + +static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) +{ + AVFilterContext *ctx = inlink->dst; + LutContext *lut = ctx->priv; + AVFilterLink *outlink = ctx->outputs[0]; + AVFilterBufferRef *inpic = inlink ->cur_buf; + AVFilterBufferRef *outpic = outlink->out_buf; + uint8_t *inrow, *outrow; + int i, j, k, plane; + + if (lut->is_rgb) { + /* packed */ + inrow = inpic ->data[0] + y * inpic ->linesize[0]; + outrow = outpic->data[0] + y * outpic->linesize[0]; + + for (i = 0; i < h; i ++) { + for (j = 0; j < inlink->w; j++) { + for (k = 0; k < lut->step; k++) + outrow[k] = lut->lut[lut->rgba_map[k]][inrow[k]]; + outrow += lut->step; + inrow += lut->step; + } + } + } else { + /* planar */ + for (plane = 0; inpic->data[plane]; plane++) { + int vsub = plane == 1 || plane == 2 ? lut->vsub : 0; + int hsub = plane == 1 || plane == 2 ? lut->hsub : 0; + + inrow = inpic ->data[plane] + (y>>vsub) * inpic ->linesize[plane]; + outrow = outpic->data[plane] + (y>>vsub) * outpic->linesize[plane]; + + for (i = 0; i < h>>vsub; i ++) { + for (j = 0; j < inlink->w>>hsub; j++) + outrow[j] = lut->lut[plane][inrow[j]]; + inrow += inpic ->linesize[plane]; + outrow += outpic->linesize[plane]; + } + } + } + + avfilter_draw_slice(outlink, y, h, slice_dir); +} + +#define DEFINE_LUT_FILTER(name_, description_, init_) \ + AVFilter avfilter_vf_##name_ = { \ + .name = NULL_IF_CONFIG_SMALL(#name_), \ + .description = description_, \ + .priv_size = sizeof(LutContext), \ + \ + .init = init_, \ + .uninit = uninit, \ + .query_formats = query_formats, \ + \ + .inputs = (AVFilterPad[]) {{ .name = "default", \ + .type = AVMEDIA_TYPE_VIDEO, \ + .draw_slice = draw_slice, \ + .config_props = config_props, \ + .min_perms = AV_PERM_READ, }, \ + { .name = NULL}}, \ + .outputs = (AVFilterPad[]) {{ .name = "default", \ + .type = AVMEDIA_TYPE_VIDEO, }, \ + { .name = NULL}}, \ + } + +DEFINE_LUT_FILTER(lut, "Compute and apply a lookup table to the RGB/YUV input video.", init); +DEFINE_LUT_FILTER(lutyuv, "Compute and apply a lookup table to the YUV input video.", init); +DEFINE_LUT_FILTER(lutrgb, "Compute and apply a lookup table to the RGB input video.", init); From 15f03725ced37e3b99e76f63f52cb92e10f134e2 Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Sat, 28 May 2011 22:00:26 +0200 Subject: [PATCH 058/109] lavfi: add negate filter This filter is a simple wrapper around the LUT filter. --- configure | 1 + doc/filters.texi | 7 +++++++ libavfilter/Makefile | 1 + libavfilter/allfilters.c | 1 + libavfilter/avfilter.h | 2 +- libavfilter/vf_lut.c | 23 +++++++++++++++++++++++ 6 files changed, 34 insertions(+), 1 deletion(-) diff --git a/configure b/configure index 1f1b75e088..552c8e0a82 100755 --- a/configure +++ b/configure @@ -1500,6 +1500,7 @@ frei0r_src_filter_deps="frei0r dlopen strtok_r" hqdn3d_filter_deps="gpl" movie_filter_deps="avcodec avformat" mp_filter_deps="gpl avcodec" +negate_filter_deps="lut_filter" ocv_filter_deps="libopencv" scale_filter_deps="swscale" yadif_filter_deps="gpl" diff --git a/doc/filters.texi b/doc/filters.texi index 80a60835a5..7a0b2693ee 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -911,6 +911,13 @@ mp=hue=100:-10 See also mplayer(1), @url{http://www.mplayerhq.hu/}. +@section negate + +Negate input video. + +This filter accepts an integer in input, if non-zero it negates the +alpha component (if available). The default value in input is 0. + @section noformat Force libavfilter not to use any of the specified pixel formats for the diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 8f8abe729e..c594573798 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -42,6 +42,7 @@ OBJS-$(CONFIG_LUT_FILTER) += vf_lut.o OBJS-$(CONFIG_LUTRGB_FILTER) += vf_lut.o OBJS-$(CONFIG_LUTYUV_FILTER) += vf_lut.o OBJS-$(CONFIG_MP_FILTER) += vf_mp.o +OBJS-$(CONFIG_NEGATE_FILTER) += vf_lut.o OBJS-$(CONFIG_NOFORMAT_FILTER) += vf_format.o OBJS-$(CONFIG_NULL_FILTER) += vf_null.o OBJS-$(CONFIG_OCV_FILTER) += vf_libopencv.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 3c4a6e17b4..2983f6bd8c 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -58,6 +58,7 @@ void avfilter_register_all(void) REGISTER_FILTER (LUTRGB, lutrgb, vf); REGISTER_FILTER (LUTYUV, lutyuv, vf); REGISTER_FILTER (MP, mp, vf); + REGISTER_FILTER (NEGATE, negate, vf); REGISTER_FILTER (NOFORMAT, noformat, vf); REGISTER_FILTER (NULL, null, vf); REGISTER_FILTER (OCV, ocv, vf); diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index 6dd5020ecf..bcfc4c6df9 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -26,7 +26,7 @@ #include "libavutil/samplefmt.h" #define LIBAVFILTER_VERSION_MAJOR 2 -#define LIBAVFILTER_VERSION_MINOR 19 +#define LIBAVFILTER_VERSION_MINOR 20 #define LIBAVFILTER_VERSION_MICRO 0 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavfilter/vf_lut.c b/libavfilter/vf_lut.c index 895293d12d..792e274c33 100644 --- a/libavfilter/vf_lut.c +++ b/libavfilter/vf_lut.c @@ -67,6 +67,7 @@ typedef struct { int is_rgb, is_yuv; int rgba_map[4]; int step; + int negate_alpha; /* only used by negate */ } LutContext; #define Y 0 @@ -366,3 +367,25 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir) DEFINE_LUT_FILTER(lut, "Compute and apply a lookup table to the RGB/YUV input video.", init); DEFINE_LUT_FILTER(lutyuv, "Compute and apply a lookup table to the YUV input video.", init); DEFINE_LUT_FILTER(lutrgb, "Compute and apply a lookup table to the RGB input video.", init); + +#if CONFIG_NEGATE_FILTER + +static int negate_init(AVFilterContext *ctx, const char *args, void *opaque) +{ + LutContext *lut = ctx->priv; + char lut_params[1024]; + + if (args) + sscanf(args, "%d", &lut->negate_alpha); + + av_log(ctx, AV_LOG_INFO, "negate_alpha:%d\n", lut->negate_alpha); + + snprintf(lut_params, sizeof(lut_params), "c0=negval:c1=negval:c2=negval:a=%s", + lut->negate_alpha ? "negval" : "val"); + + return init(ctx, lut_params, opaque); +} + +DEFINE_LUT_FILTER(negate, "Negate input video.", negate_init); + +#endif From 141f03541b39e131a5e8aa776a88abe77b70618e Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Sun, 19 Jun 2011 02:49:04 +0200 Subject: [PATCH 059/109] opt: do not crash in av_set_options_string() if opts == NULL Add missing NULL check, and update documentation accordingly. --- libavutil/avutil.h | 2 +- libavutil/opt.c | 2 ++ libavutil/opt.h | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libavutil/avutil.h b/libavutil/avutil.h index 36dcf8f718..4d6ef66003 100644 --- a/libavutil/avutil.h +++ b/libavutil/avutil.h @@ -41,7 +41,7 @@ #define LIBAVUTIL_VERSION_MAJOR 51 #define LIBAVUTIL_VERSION_MINOR 9 -#define LIBAVUTIL_VERSION_MICRO 0 +#define LIBAVUTIL_VERSION_MICRO 1 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ LIBAVUTIL_VERSION_MINOR, \ diff --git a/libavutil/opt.c b/libavutil/opt.c index 8c351488a8..c0b529b8ea 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -521,6 +521,8 @@ int av_set_options_string(void *ctx, const char *opts, { int ret, count = 0; + if (!opts) + return 0; while (*opts) { if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0) return ret; diff --git a/libavutil/opt.h b/libavutil/opt.h index 97a1cb5774..68873de563 100644 --- a/libavutil/opt.h +++ b/libavutil/opt.h @@ -169,6 +169,7 @@ void av_opt_set_defaults2(void *s, int mask, int flags); * key. ctx must be an AVClass context, storing is done using * AVOptions. * + * @param opts options string to parse, may be NULL * @param key_val_sep a 0-terminated list of characters used to * separate key from value * @param pairs_sep a 0-terminated list of characters used to separate From e89ba76a59ce31320083b74f41e26bf4f64df8dd Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Sat, 18 Jun 2011 01:52:40 +0200 Subject: [PATCH 060/109] vsrc_color: use internal timebase Avoid timescale conversion, simplify. --- libavfilter/vsrc_color.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavfilter/vsrc_color.c b/libavfilter/vsrc_color.c index 6d8b5e9f1a..62c7f80945 100644 --- a/libavfilter/vsrc_color.c +++ b/libavfilter/vsrc_color.c @@ -129,6 +129,7 @@ static int color_config_props(AVFilterLink *inlink) is_packed_rgba ? "rgba" : "yuva"); inlink->w = color->w; inlink->h = color->h; + inlink->time_base = color->time_base; return 0; } @@ -138,7 +139,7 @@ static int color_request_frame(AVFilterLink *link) ColorContext *color = link->src->priv; AVFilterBufferRef *picref = avfilter_get_video_buffer(link, AV_PERM_WRITE, color->w, color->h); picref->video->sample_aspect_ratio = (AVRational) {1, 1}; - picref->pts = av_rescale_q(color->pts++, color->time_base, AV_TIME_BASE_Q); + picref->pts = color->pts++; picref->pos = -1; avfilter_start_frame(link, avfilter_ref_buffer(picref, ~0)); From 44f669e7bc4f7f064e3f81d3596637a0e043b501 Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Sat, 11 Jun 2011 18:43:11 +0200 Subject: [PATCH 061/109] lavfi: add vsink_buffer, and use it in ff* tools Also add the public interface libavfilter/vsink_buffer.h. --- Changelog | 1 + cmdutils.c | 68 ----------------------- cmdutils.h | 15 ----- doc/APIchanges | 3 + doc/filters.texi | 13 +++++ ffmpeg.c | 20 ++++--- ffplay.c | 14 +++-- libavfilter/Makefile | 3 +- libavfilter/allfilters.c | 1 + libavfilter/avfilter.h | 2 +- libavfilter/vsink_buffer.c | 111 +++++++++++++++++++++++++++++++++++++ libavfilter/vsink_buffer.h | 47 ++++++++++++++++ 12 files changed, 199 insertions(+), 99 deletions(-) create mode 100644 libavfilter/vsink_buffer.c create mode 100644 libavfilter/vsink_buffer.h diff --git a/Changelog b/Changelog index 7745fa0938..80ed401ab9 100644 --- a/Changelog +++ b/Changelog @@ -17,6 +17,7 @@ version 0.7: - 4:4:4 H.264 decoding support - 10-bit H.264 optimizations for x86 - lut, lutrgb, and lutyuv filters added +- buffersink libavfilter sink added version 0.7_beta2: diff --git a/cmdutils.c b/cmdutils.c index 3b9cfaa3d9..c3c5c0efa9 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -962,71 +962,3 @@ FILE *get_preset_file(char *filename, size_t filename_size, return f; } - -#if CONFIG_AVFILTER - -static int ffsink_init(AVFilterContext *ctx, const char *args, void *opaque) -{ - FFSinkContext *priv = ctx->priv; - - if (!opaque) - return AVERROR(EINVAL); - *priv = *(FFSinkContext *)opaque; - - return 0; -} - -static void null_end_frame(AVFilterLink *inlink) { } - -static int ffsink_query_formats(AVFilterContext *ctx) -{ - FFSinkContext *priv = ctx->priv; - enum PixelFormat pix_fmts[] = { priv->pix_fmt, PIX_FMT_NONE }; - - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); - return 0; -} - -AVFilter ffsink = { - .name = "ffsink", - .priv_size = sizeof(FFSinkContext), - .init = ffsink_init, - - .query_formats = ffsink_query_formats, - - .inputs = (AVFilterPad[]) {{ .name = "default", - .type = AVMEDIA_TYPE_VIDEO, - .end_frame = null_end_frame, - .min_perms = AV_PERM_READ, }, - { .name = NULL }}, - .outputs = (AVFilterPad[]) {{ .name = NULL }}, -}; - -int get_filtered_video_frame(AVFilterContext *ctx, AVFrame *frame, - AVFilterBufferRef **picref_ptr, AVRational *tb) -{ - int ret; - AVFilterBufferRef *picref; - *picref_ptr = NULL; - - if ((ret = avfilter_request_frame(ctx->inputs[0])) < 0) - return ret; - if (!(picref = ctx->inputs[0]->cur_buf)) - return AVERROR(ENOENT); - *picref_ptr = picref; - ctx->inputs[0]->cur_buf = NULL; - *tb = ctx->inputs[0]->time_base; - - memcpy(frame->data, picref->data, sizeof(frame->data)); - memcpy(frame->linesize, picref->linesize, sizeof(frame->linesize)); - frame->pkt_pos = picref->pos; - frame->interlaced_frame = picref->video->interlaced; - frame->top_field_first = picref->video->top_field_first; - frame->key_frame = picref->video->key_frame; - frame->pict_type = picref->video->pict_type; - frame->sample_aspect_ratio = picref->video->sample_aspect_ratio; - - return 1; -} - -#endif /* CONFIG_AVFILTER */ diff --git a/cmdutils.h b/cmdutils.h index c0c3ce07d9..e001ab9201 100644 --- a/cmdutils.h +++ b/cmdutils.h @@ -260,19 +260,4 @@ int read_file(const char *filename, char **bufptr, size_t *size); FILE *get_preset_file(char *filename, size_t filename_size, const char *preset_name, int is_path, const char *codec_name); -typedef struct { - enum PixelFormat pix_fmt; -} FFSinkContext; - -extern AVFilter ffsink; - -/** - * Extract a frame from sink. - * - * @return a negative error in case of failure, 1 if one frame has - * been extracted successfully. - */ -int get_filtered_video_frame(AVFilterContext *sink, AVFrame *frame, - AVFilterBufferRef **picref, AVRational *pts_tb); - #endif /* FFMPEG_CMDUTILS_H */ diff --git a/doc/APIchanges b/doc/APIchanges index e07951fe05..4db7ffeddf 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2011-04-18 API changes, most recent first: +2011-06-19 - xxxxxxx - lavfi 2.21.0 - vsink_buffer.h + Add video sink buffer and vsink_buffer.h public header. + 2011-06-12 - xxxxxxx - lavfi 2.18.0 - avcodec.h Add avfilter_get_video_buffer_ref_from_frame() function in libavfilter/avcodec.h. diff --git a/doc/filters.texi b/doc/filters.texi index 7a0b2693ee..eb31714486 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -1977,6 +1977,19 @@ frei0r_src=200x200:10:partik0l=1234 [overlay]; [in][overlay] overlay Below is a description of the currently available video sinks. +@section buffersink + +Buffer video frames, and make them available to the end of the filter +graph. + +This sink is mainly intended for a programmatic use, in particular +through the interface defined in @file{libavfilter/vsink_buffer.h}. + +It does not require a string parameter in input, but you need to +specify a pointer to a list of supported pixel formats terminated by +-1 in the opaque parameter provided to @code{avfilter_init_filter} +when initializing this sink. + @section nullsink Null video sink, do absolutely nothing with the input video. It is diff --git a/ffmpeg.c b/ffmpeg.c index 2921a06ddf..0b1b1bee8d 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -51,6 +51,7 @@ # include "libavfilter/avcodec.h" # include "libavfilter/avfilter.h" # include "libavfilter/avfiltergraph.h" +# include "libavfilter/vsink_buffer.h" # include "libavfilter/vsrc_buffer.h" #endif @@ -363,7 +364,7 @@ static int configure_video_filters(AVInputStream *ist, AVOutputStream *ost) /** filter graph containing all filters including input & output */ AVCodecContext *codec = ost->st->codec; AVCodecContext *icodec = ist->st->codec; - FFSinkContext ffsink_ctx = { .pix_fmt = codec->pix_fmt }; + enum PixelFormat pix_fmts[] = { codec->pix_fmt, PIX_FMT_NONE }; AVRational sample_aspect_ratio; char args[255]; int ret; @@ -383,8 +384,8 @@ static int configure_video_filters(AVInputStream *ist, AVOutputStream *ost) "src", args, NULL, ost->graph); if (ret < 0) return ret; - ret = avfilter_graph_create_filter(&ost->output_video_filter, &ffsink, - "out", NULL, &ffsink_ctx, ost->graph); + ret = avfilter_graph_create_filter(&ost->output_video_filter, avfilter_get_by_name("buffersink"), + "out", NULL, pix_fmts, ost->graph); if (ret < 0) return ret; last_filter = ost->input_video_filter; @@ -1708,12 +1709,15 @@ static int output_packet(AVInputStream *ist, int ist_index, frame_available = ist->st->codec->codec_type != AVMEDIA_TYPE_VIDEO || !ost->output_video_filter || avfilter_poll_frame(ost->output_video_filter->inputs[0]); while (frame_available) { - AVRational ist_pts_tb; - if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ost->output_video_filter) - if (get_filtered_video_frame(ost->output_video_filter, &picture, &ost->picref, &ist_pts_tb) < 0) + if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && ost->output_video_filter) { + AVRational ist_pts_tb = ost->output_video_filter->inputs[0]->time_base; + if (av_vsink_buffer_get_video_buffer_ref(ost->output_video_filter, &ost->picref, 0) < 0) goto cont; - if (ost->picref) - ist->pts = av_rescale_q(ost->picref->pts, ist_pts_tb, AV_TIME_BASE_Q); + if (ost->picref) { + avfilter_fill_frame_from_video_buffer_ref(&picture, ost->picref); + ist->pts = av_rescale_q(ost->picref->pts, ist_pts_tb, AV_TIME_BASE_Q); + } + } #endif os = output_files[ost->file_index]; diff --git a/ffplay.c b/ffplay.c index 31a683216f..548fda627a 100644 --- a/ffplay.c +++ b/ffplay.c @@ -41,6 +41,7 @@ # include "libavfilter/avcodec.h" # include "libavfilter/avfilter.h" # include "libavfilter/avfiltergraph.h" +# include "libavfilter/vsink_buffer.h" #endif #include @@ -1682,7 +1683,7 @@ static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c { char sws_flags_str[128]; int ret; - FFSinkContext ffsink_ctx = { .pix_fmt = PIX_FMT_YUV420P }; + enum PixelFormat pix_fmts[] = { PIX_FMT_YUV420P, PIX_FMT_NONE }; AVFilterContext *filt_src = NULL, *filt_out = NULL; snprintf(sws_flags_str, sizeof(sws_flags_str), "flags=%d", sws_flags); graph->scale_sws_opts = av_strdup(sws_flags_str); @@ -1690,8 +1691,8 @@ static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c if ((ret = avfilter_graph_create_filter(&filt_src, &input_filter, "src", NULL, is, graph)) < 0) goto the_end; - if ((ret = avfilter_graph_create_filter(&filt_out, &ffsink, "out", - NULL, &ffsink_ctx, graph)) < 0) + if ((ret = avfilter_graph_create_filter(&filt_out, avfilter_get_by_name("buffersink"), "out", + NULL, pix_fmts, graph)) < 0) goto the_end; if(vfilters) { @@ -1748,13 +1749,14 @@ static int video_thread(void *arg) AVPacket pkt; #else AVFilterBufferRef *picref; - AVRational tb; + AVRational tb = filt_out->inputs[0]->time_base; #endif while (is->paused && !is->videoq.abort_request) SDL_Delay(10); #if CONFIG_AVFILTER - ret = get_filtered_video_frame(filt_out, frame, &picref, &tb); + ret = av_vsink_buffer_get_video_buffer_ref(filt_out, &picref, 0); if (picref) { + avfilter_fill_frame_from_video_buffer_ref(frame, picref); pts_int = picref->pts; pos = picref->pos; frame->opaque = picref; @@ -1776,7 +1778,7 @@ static int video_thread(void *arg) if (ret < 0) goto the_end; - if (!ret) + if (!picref) continue; pts = pts_int*av_q2d(is->video_st->time_base); diff --git a/libavfilter/Makefile b/libavfilter/Makefile index c594573798..84a7ac3394 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -6,7 +6,7 @@ FFLIBS-$(CONFIG_MOVIE_FILTER) += avformat avcodec FFLIBS-$(CONFIG_SCALE_FILTER) += swscale FFLIBS-$(CONFIG_MP_FILTER) += avcodec -HEADERS = avcodec.h avfilter.h avfiltergraph.h vsrc_buffer.h +HEADERS = avcodec.h avfilter.h avfiltergraph.h vsink_buffer.hvsrc_buffer.h OBJS = allfilters.o \ avfilter.o \ @@ -69,6 +69,7 @@ OBJS-$(CONFIG_FREI0R_SRC_FILTER) += vf_frei0r.o OBJS-$(CONFIG_MOVIE_FILTER) += vsrc_movie.o OBJS-$(CONFIG_NULLSRC_FILTER) += vsrc_nullsrc.o +OBJS-$(CONFIG_BUFFERSINK_FILTER) += vsink_buffer.o OBJS-$(CONFIG_NULLSINK_FILTER) += vsink_nullsink.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 2983f6bd8c..42047ecbe8 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -85,5 +85,6 @@ void avfilter_register_all(void) REGISTER_FILTER (MOVIE, movie, vsrc); REGISTER_FILTER (NULLSRC, nullsrc, vsrc); + REGISTER_FILTER (BUFFER, buffersink, vsink); REGISTER_FILTER (NULLSINK, nullsink, vsink); } diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index bcfc4c6df9..5ac70399ac 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -26,7 +26,7 @@ #include "libavutil/samplefmt.h" #define LIBAVFILTER_VERSION_MAJOR 2 -#define LIBAVFILTER_VERSION_MINOR 20 +#define LIBAVFILTER_VERSION_MINOR 21 #define LIBAVFILTER_VERSION_MICRO 0 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavfilter/vsink_buffer.c b/libavfilter/vsink_buffer.c new file mode 100644 index 0000000000..c0824606a9 --- /dev/null +++ b/libavfilter/vsink_buffer.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2011 Stefano Sabatini + * + * 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 + */ + +/** + * @file + * buffer video sink + */ + +#include "avfilter.h" +#include "vsink_buffer.h" + +typedef struct { + AVFilterBufferRef *picref; ///< cached picref + enum PixelFormat *pix_fmts; ///< accepted pixel formats, must be terminated with -1 +} BufferSinkContext; + +static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) +{ + BufferSinkContext *buf = ctx->priv; + + if (!opaque) { + av_log(ctx, AV_LOG_ERROR, "No opaque field provided, which is required.\n"); + return AVERROR(EINVAL); + } + + buf->pix_fmts = opaque; + return 0; +} + +static av_cold void uninit(AVFilterContext *ctx) +{ + BufferSinkContext *buf = ctx->priv; + + if (buf->picref) + avfilter_unref_buffer(buf->picref); + buf->picref = NULL; +} + +static void end_frame(AVFilterLink *inlink) +{ + BufferSinkContext *buf = inlink->dst->priv; + + if (buf->picref) /* drop the last cached frame */ + avfilter_unref_buffer(buf->picref); + buf->picref = inlink->cur_buf; +} + +static int query_formats(AVFilterContext *ctx) +{ + BufferSinkContext *buf = ctx->priv; + + avfilter_set_common_formats(ctx, avfilter_make_format_list(buf->pix_fmts)); + return 0; +} + +int av_vsink_buffer_get_video_buffer_ref(AVFilterContext *ctx, + AVFilterBufferRef **picref, int flags) +{ + BufferSinkContext *buf = ctx->priv; + AVFilterLink *inlink = ctx->inputs[0]; + int ret; + *picref = NULL; + + /* no picref available, fetch it from the filterchain */ + if (!buf->picref) { + if ((ret = avfilter_request_frame(inlink)) < 0) + return ret; + } + + if (!buf->picref) + return AVERROR(EINVAL); + + *picref = buf->picref; + if (!(flags & AV_VSINK_BUF_FLAG_PEEK)) + buf->picref = NULL; + + return 0; +} + +AVFilter avfilter_vsink_buffersink = { + .name = "buffersink", + .priv_size = sizeof(BufferSinkContext), + .init = init, + .uninit = uninit, + + .query_formats = query_formats, + + .inputs = (AVFilterPad[]) {{ .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .end_frame = end_frame, + .min_perms = AV_PERM_READ, }, + { .name = NULL }}, + .outputs = (AVFilterPad[]) {{ .name = NULL }}, +}; diff --git a/libavfilter/vsink_buffer.h b/libavfilter/vsink_buffer.h new file mode 100644 index 0000000000..88b4c1d258 --- /dev/null +++ b/libavfilter/vsink_buffer.h @@ -0,0 +1,47 @@ +/* + * 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 AVFILTER_VSINK_BUFFER_H +#define AVFILTER_VSINK_BUFFER_H + +/** + * @file + * memory buffer sink API for video + */ + +#include "avfilter.h" + +/** + * Tell av_vsink_buffer_get_video_buffer_ref() to read the picref, but not + * remove it from the buffer. This is useful if you need only to read + * the picref, without to fetch it. + */ +#define AV_VSINK_BUF_FLAG_PEEK 1 + +/** + * Get a video buffer data from buffer_sink and put it in picref. + * + * @param buffer_sink pointer to a buffer sink context + * @param flags a combination of AV_VSINK_BUF_FLAG_* flags + * @return >= 0 in case of success, a negative AVERROR code in case of + * failure + */ +int av_vsink_buffer_get_video_buffer_ref(AVFilterContext *buffer_sink, + AVFilterBufferRef **picref, int flags); + +#endif /* AVFILTER_VSINK_BUFFER_H */ From 72da9888b0f1c0f6a74f6fdfa5f5f31d20bb0099 Mon Sep 17 00:00:00 2001 From: Reinhard Tartler Date: Sun, 19 Jun 2011 19:45:36 +0200 Subject: [PATCH 062/109] Add Release Notes --- doc/RELEASE_NOTES | 52 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 doc/RELEASE_NOTES diff --git a/doc/RELEASE_NOTES b/doc/RELEASE_NOTES new file mode 100644 index 0000000000..97875e9360 --- /dev/null +++ b/doc/RELEASE_NOTES @@ -0,0 +1,52 @@ +Release Notes +============= + +* 0.7 "The Big Bump" June, 2011 + +General notes +------------- + +This release enables frame-based multithreaded decoding for a number of codecs, +including VP8, H.263 and H.264. Additionally, there has been a major cleanup of +both internal and external APIs. For this reason, the major versions of all +libraries have been bumped. On the one hand, this means that 0.7 can be installed +side-by-side with previous releases, on the other hand, in order to benefit +from the new features, applications need to be recompiled. + +Other important changes are additions of decoders including, but not limited to, +AMR-WB, single stream LATM/LOAS, G.722 ADPCM, a native VP8 decoder +and HE-AACv2. Additionally, many new de/muxers such as WebM in Matroska, Apple +HTTP Live Streaming, SAP, IEC 61937 (S/PDIF) have been added. + +See the Changelog file for a list of significant changes. + +Please note that our policy on bug reports has not changed. We still only accept +bug reports against HEAD of the Libav trunk repository. If you are experiencing +issues with any formally released version of Libav, please try a current version +of the development code to check if the issue still exists. If it does, make your +report against the development code following the usual bug reporting guidelines. + + +API changes +----------- + +Please see the file doc/APIchanges for programmer-centric information. Note that a +lot of long-time deprecated APIs have been removed. Also, a number of additional +APIs have been deprecated and are scheduled for removal in the next release. + + +Other notable changes +--------------------- + +- many ARM NEON optimizations +- libswscale cleanup started, optimizations should become easier in the future +- nonfree libfaad support for AAC decoding removed +- 4:4:4 H.264 decoding +- 9/10bit H.264 decoding +- Win64 Assembler support +- native MMSH/MMST support +- Windows TV demuxing +- native AMR-WB decoding +- native GSM-MS decoding +- SMPTE 302M decoding +- AVS encoding From 7b2d219045330494a2391beb6571ee1b25fc422d Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sun, 19 Jun 2011 18:03:21 +0100 Subject: [PATCH 063/109] path64/open64: filter out unsupported flags These flags are accepted without error but produce an annoying warning. Filtering them out makes the build less noisy. Signed-off-by: Mans Rullgard --- configure | 2 ++ 1 file changed, 2 insertions(+) diff --git a/configure b/configure index 2a1883bfa0..31e82fc6db 100755 --- a/configure +++ b/configure @@ -2069,6 +2069,7 @@ elif $cc -v 2>&1 | grep -q 'PathScale\|Path64'; then AS_DEPFLAGS='-MMD -MF $(@:.o=.d) -MT $@' speed_cflags='-O2' size_cflags='-Os' + filter_cflags='filter_out -Wdisabled-optimization' elif $cc -v 2>&1 | grep -q Open64; then cc_type=open64 cc_version=__OPEN64__ @@ -2077,6 +2078,7 @@ elif $cc -v 2>&1 | grep -q Open64; then AS_DEPFLAGS='-MMD -MF $(@:.o=.d) -MT $@' speed_cflags='-O2' size_cflags='-Os' + filter_cflags='filter_out -Wdisabled-optimization|-Wtype-limits|-fno-signed-zeros' fi test -n "$cc_type" && enable $cc_type || From 8fab4007c83349e5dbaacca735ce698cf94bf8e4 Mon Sep 17 00:00:00 2001 From: Reinhard Tartler Date: Sun, 19 Jun 2011 19:51:20 +0200 Subject: [PATCH 064/109] Use the contents of RELEASE as version fallback instead of 'UNKNOWN' This makes binaries produced by source tarballs identify themselves with the version number of the corresponding release series, unless overriden by a 'VERSION' file. --- RELEASE | 1 + version.sh | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 RELEASE diff --git a/RELEASE b/RELEASE new file mode 100644 index 0000000000..eb49d7c7fd --- /dev/null +++ b/RELEASE @@ -0,0 +1 @@ +0.7 diff --git a/version.sh b/version.sh index 6ec2b2567e..7911e46166 100755 --- a/version.sh +++ b/version.sh @@ -5,7 +5,7 @@ revision=$(cd "$1" && git describe --always 2> /dev/null) test "$revision" && revision=git-$revision # no revision number found -test "$revision" || revision=UNKNOWN +test "$revision" || revision=$(cd "$1" && cat RELEASE 2> /dev/null) # releases extract the version number from the VERSION file version=$(cd "$1" && cat VERSION 2> /dev/null) From 8d3d3436e2596e27571b86eb97c66971a1a7431b Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sun, 19 Jun 2011 19:31:56 +0100 Subject: [PATCH 065/109] Drop git- prefix from version labels Signed-off-by: Mans Rullgard --- version.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/version.sh b/version.sh index 7911e46166..6f72b2c2e6 100755 --- a/version.sh +++ b/version.sh @@ -2,7 +2,6 @@ # check for git short hash revision=$(cd "$1" && git describe --always 2> /dev/null) -test "$revision" && revision=git-$revision # no revision number found test "$revision" || revision=$(cd "$1" && cat RELEASE 2> /dev/null) From c6e288a7cd3f92d09a59671f81119c9643d8589c Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Sun, 19 Jun 2011 22:42:09 +0200 Subject: [PATCH 066/109] lavfi: fix Makefile HEADERS Add a missing space between vsink_buffer.h and vsrc_buffer.h. 1000l. --- libavfilter/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 84a7ac3394..461df37a10 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -6,7 +6,7 @@ FFLIBS-$(CONFIG_MOVIE_FILTER) += avformat avcodec FFLIBS-$(CONFIG_SCALE_FILTER) += swscale FFLIBS-$(CONFIG_MP_FILTER) += avcodec -HEADERS = avcodec.h avfilter.h avfiltergraph.h vsink_buffer.hvsrc_buffer.h +HEADERS = avcodec.h avfilter.h avfiltergraph.h vsink_buffer.h vsrc_buffer.h OBJS = allfilters.o \ avfilter.o \ From 8f349b64813b348634042d96b9d104ada94dc538 Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Sun, 19 Jun 2011 22:07:18 +0200 Subject: [PATCH 067/109] lavfi: fix realloc size computation in avfilter_add_format() Replace sizeof((*avff)->formats) with sizeof(*(*avff)->formats) as the size of the array element is given by the pointed element rather than by its pointer. In particular fix computation with the pending patch when sizeof(int64_t) != sizeof(int64_t *). --- libavfilter/formats.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/formats.c b/libavfilter/formats.c index 58593fcce0..4a23c2f1b3 100644 --- a/libavfilter/formats.c +++ b/libavfilter/formats.c @@ -99,7 +99,7 @@ int avfilter_add_format(AVFilterFormats **avff, int fmt) return AVERROR(ENOMEM); fmts = av_realloc((*avff)->formats, - sizeof((*avff)->formats) * ((*avff)->format_count+1)); + sizeof(*(*avff)->formats) * ((*avff)->format_count+1)); if (!fmts) return AVERROR(ENOMEM); From 527ca3985c736ffe077a82fdf3616f0fd571b923 Mon Sep 17 00:00:00 2001 From: Mina Nagy Zaki Date: Tue, 7 Jun 2011 21:17:23 +0300 Subject: [PATCH 068/109] lavfi: use int64_t lists in AVFilteFormats The list type was changed to int64_t to be able to hold channel layouts. avfilter_make_format_list() still takes a int32_t array and converts it to int64_t. A new function, avfilter_make_format64_list, that takes int64_t arrays has been added. --- doc/APIchanges | 8 ++++++++ libavfilter/avfilter.h | 7 ++++--- libavfilter/formats.c | 46 ++++++++++++++++++++++++++++-------------- 3 files changed, 43 insertions(+), 18 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index 4db7ffeddf..dc352e72c1 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,14 @@ libavutil: 2011-04-18 API changes, most recent first: +2011-06-19 - xxxxxxx - lavfi 2.22.0 - AVFilterFormats + Change type of AVFilterFormats.formats from int * to int64_t *, + and update formats handling API accordingly. + + avfilter_make_format_list() still takes a int32_t array and converts + it to int64_t. A new function, avfilter_make_format64_list(), that + takes int64_t arrays has been added. + 2011-06-19 - xxxxxxx - lavfi 2.21.0 - vsink_buffer.h Add video sink buffer and vsink_buffer.h public header. diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index 5ac70399ac..1a3a69de57 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -26,7 +26,7 @@ #include "libavutil/samplefmt.h" #define LIBAVFILTER_VERSION_MAJOR 2 -#define LIBAVFILTER_VERSION_MINOR 21 +#define LIBAVFILTER_VERSION_MINOR 22 #define LIBAVFILTER_VERSION_MICRO 0 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ @@ -223,7 +223,7 @@ void avfilter_unref_buffer(AVFilterBufferRef *ref); */ typedef struct AVFilterFormats { unsigned format_count; ///< number of formats - int *formats; ///< list of media formats + int64_t *formats; ///< list of media formats unsigned refcount; ///< number of references to this list struct AVFilterFormats ***refs; ///< references to this list @@ -238,6 +238,7 @@ typedef struct AVFilterFormats { * @return the format list, with no existing references */ AVFilterFormats *avfilter_make_format_list(const int *fmts); +AVFilterFormats *avfilter_make_format64_list(const int64_t *fmts); /** * Add fmt to the list of media formats contained in *avff. @@ -247,7 +248,7 @@ AVFilterFormats *avfilter_make_format_list(const int *fmts); * @return a non negative value in case of success, or a negative * value corresponding to an AVERROR code in case of error */ -int avfilter_add_format(AVFilterFormats **avff, int fmt); +int avfilter_add_format(AVFilterFormats **avff, int64_t fmt); /** * Return a list of all formats supported by FFmpeg for the given media type. diff --git a/libavfilter/formats.c b/libavfilter/formats.c index 4a23c2f1b3..4e101c570c 100644 --- a/libavfilter/formats.c +++ b/libavfilter/formats.c @@ -72,28 +72,44 @@ AVFilterFormats *avfilter_merge_formats(AVFilterFormats *a, AVFilterFormats *b) return ret; } +#define MAKE_FORMAT_LIST() \ + AVFilterFormats *formats; \ + int count = 0; \ + if (fmts) \ + for (count = 0; fmts[count] != -1; count++) \ + ; \ + formats = av_mallocz(sizeof(AVFilterFormats)); \ + if (!formats) return NULL; \ + formats->format_count = count; \ + if (count) { \ + formats->formats = av_malloc(sizeof(*formats->formats)*count); \ + if (!formats->formats) { \ + av_free(formats); \ + return NULL; \ + } \ + } + AVFilterFormats *avfilter_make_format_list(const int *fmts) { - AVFilterFormats *formats; - int count = 0; - - if (fmts) - for (count = 0; fmts[count] != -1; count++) - ; - - formats = av_mallocz(sizeof(AVFilterFormats)); - formats->format_count = count; - if (count) { - formats->formats = av_malloc(sizeof(*formats->formats) * count); - memcpy(formats->formats, fmts, sizeof(*formats->formats) * count); - } + MAKE_FORMAT_LIST(); + while (count--) + formats->formats[count] = fmts[count]; return formats; } -int avfilter_add_format(AVFilterFormats **avff, int fmt) +AVFilterFormats *avfilter_make_format64_list(const int64_t *fmts) { - int *fmts; + MAKE_FORMAT_LIST(); + if (count) + memcpy(formats->formats, fmts, sizeof(*formats->formats) * count); + + return formats; +} + +int avfilter_add_format(AVFilterFormats **avff, int64_t fmt) +{ + int64_t *fmts; if (!(*avff) && !(*avff = av_mallocz(sizeof(AVFilterFormats)))) return AVERROR(ENOMEM); From fd2c0a5db242a3c89a89f1dd2ae9e3155e48f9e2 Mon Sep 17 00:00:00 2001 From: Mina Nagy Zaki Date: Sun, 19 Jun 2011 20:31:24 +0200 Subject: [PATCH 069/109] lavfi: add layout negotiation fields and helper functions. --- doc/APIchanges | 9 +++++ ffplay.c | 2 +- libavfilter/avfilter.c | 3 ++ libavfilter/avfilter.h | 34 ++++++++++++------ libavfilter/avfiltergraph.c | 9 ++++- libavfilter/defaults.c | 69 +++++++++++++++++++++---------------- libavfilter/formats.c | 22 ++++++++++++ libavfilter/vf_blackframe.c | 2 +- libavfilter/vf_crop.c | 2 +- libavfilter/vf_cropdetect.c | 2 +- libavfilter/vf_drawbox.c | 2 +- libavfilter/vf_drawtext.c | 2 +- libavfilter/vf_fade.c | 2 +- libavfilter/vf_format.c | 4 +-- libavfilter/vf_frei0r.c | 2 +- libavfilter/vf_gradfun.c | 2 +- libavfilter/vf_hflip.c | 2 +- libavfilter/vf_hqdn3d.c | 2 +- libavfilter/vf_libopencv.c | 2 +- libavfilter/vf_lut.c | 2 +- libavfilter/vf_mp.c | 2 +- libavfilter/vf_pad.c | 2 +- libavfilter/vf_transpose.c | 2 +- libavfilter/vf_unsharp.c | 2 +- libavfilter/vf_yadif.c | 2 +- libavfilter/vsink_buffer.c | 2 +- libavfilter/vsrc_buffer.c | 2 +- libavfilter/vsrc_color.c | 2 +- libavfilter/vsrc_movie.c | 2 +- 29 files changed, 128 insertions(+), 66 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index dc352e72c1..3a3fca9438 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,15 @@ libavutil: 2011-04-18 API changes, most recent first: +2011-06-19 - xxxxxxx - lavfi 2.23.0 - avfilter.h + Add layout negotiation fields and helper functions. + + In particular, add in_chlayouts and out_chlayouts to AVFilterLink, + and the functions: + avfilter_set_common_sample_formats() + avfilter_set_common_channel_layouts() + avfilter_all_channel_layouts() + 2011-06-19 - xxxxxxx - lavfi 2.22.0 - AVFilterFormats Change type of AVFilterFormats.formats from int * to int64_t *, and update formats handling API accordingly. diff --git a/ffplay.c b/ffplay.c index 548fda627a..b88387691d 100644 --- a/ffplay.c +++ b/ffplay.c @@ -1644,7 +1644,7 @@ static int input_query_formats(AVFilterContext *ctx) priv->is->video_st->codec->pix_fmt, PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 3b2e3ca2be..44dd515518 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -217,6 +217,9 @@ int avfilter_insert_filter(AVFilterLink *link, AVFilterContext *filt, if (link->out_formats) avfilter_formats_changeref(&link->out_formats, &filt->outputs[filt_dstpad_idx]->out_formats); + if (link->out_chlayouts) + avfilter_formats_changeref(&link->out_chlayouts, + &filt->outputs[filt_dstpad_idx]->out_chlayouts); return 0; } diff --git a/libavfilter/avfilter.h b/libavfilter/avfilter.h index 1a3a69de57..c276f3037e 100644 --- a/libavfilter/avfilter.h +++ b/libavfilter/avfilter.h @@ -26,7 +26,7 @@ #include "libavutil/samplefmt.h" #define LIBAVFILTER_VERSION_MAJOR 2 -#define LIBAVFILTER_VERSION_MINOR 22 +#define LIBAVFILTER_VERSION_MINOR 23 #define LIBAVFILTER_VERSION_MICRO 0 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ @@ -255,6 +255,11 @@ int avfilter_add_format(AVFilterFormats **avff, int64_t fmt); */ AVFilterFormats *avfilter_all_formats(enum AVMediaType type); +/** + * Return a list of all channel layouts supported by FFmpeg. + */ +AVFilterFormats *avfilter_all_channel_layouts(void); + /** * Return a format list which contains the intersection of the formats of * a and b. Also, all the references of a, all the references of b, and @@ -466,11 +471,13 @@ AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int per int64_t channel_layout, int planar); /** - * A helper for query_formats() which sets all links to the same list of - * formats. If there are no links hooked to this filter, the list of formats is - * freed. + * Helpers for query_formats() which set all links to the same list of + * formats/layouts. If there are no links hooked to this filter, the list + * of formats is freed. */ -void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats); +void avfilter_set_common_pixel_formats(AVFilterContext *ctx, AVFilterFormats *formats); +void avfilter_set_common_sample_formats(AVFilterContext *ctx, AVFilterFormats *formats); +void avfilter_set_common_channel_layouts(AVFilterContext *ctx, AVFilterFormats *formats); /** Default handler for query_formats() */ int avfilter_default_query_formats(AVFilterContext *ctx); @@ -521,9 +528,9 @@ typedef struct AVFilter { void (*uninit)(AVFilterContext *ctx); /** - * Queries formats supported by the filter and its pads, and sets the - * in_formats for links connected to its output pads, and out_formats - * for links connected to its input pads. + * Queries formats/layouts supported by the filter and its pads, and sets + * the in_formats/in_chlayouts for links connected to its output pads, + * and out_formats/out_chlayouts for links connected to its input pads. * * @return zero on success, a negative value corresponding to an * AVERROR code otherwise @@ -593,13 +600,18 @@ struct AVFilterLink { int format; ///< agreed upon media format /** - * Lists of formats supported by the input and output filters respectively. - * These lists are used for negotiating the format to actually be used, - * which will be loaded into the format member, above, when chosen. + * Lists of formats and channel layouts supported by the input and output + * filters respectively. These lists are used for negotiating the format + * to actually be used, which will be loaded into the format and + * channel_layout members, above, when chosen. + * */ AVFilterFormats *in_formats; AVFilterFormats *out_formats; + AVFilterFormats *in_chlayouts; + AVFilterFormats *out_chlayouts; + /** * The buffer reference currently being sent across the link by the source * filter. This is used internally by the filter system to allow diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index 60d529ba73..04768617de 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -195,9 +195,16 @@ static void pick_format(AVFilterLink *link) link->in_formats->format_count = 1; link->format = link->in_formats->formats[0]; - avfilter_formats_unref(&link->in_formats); avfilter_formats_unref(&link->out_formats); + + if (link->type == AVMEDIA_TYPE_AUDIO) { + link->in_chlayouts->format_count = 1; + link->channel_layout = link->in_chlayouts->formats[0]; + avfilter_formats_unref(&link->in_chlayouts); + avfilter_formats_unref(&link->out_chlayouts); + } + } static void pick_formats(AVFilterGraph *graph) diff --git a/libavfilter/defaults.c b/libavfilter/defaults.c index c39ed64048..b03816dd24 100644 --- a/libavfilter/defaults.c +++ b/libavfilter/defaults.c @@ -197,45 +197,54 @@ int avfilter_default_config_output_link(AVFilterLink *link) return 0; } -/** - * A helper for query_formats() which sets all links to the same list of - * formats. If there are no links hooked to this filter, the list of formats is - * freed. - * - * FIXME: this will need changed for filters with a mix of pad types - * (video + audio, etc) - */ -void avfilter_set_common_formats(AVFilterContext *ctx, AVFilterFormats *formats) +static void set_common_formats(AVFilterContext *ctx, AVFilterFormats *fmts, + enum AVMediaType type, int offin, int offout) { - int count = 0, i; + int i; + for (i = 0; i < ctx->input_count; i++) + if (ctx->inputs[i] && ctx->inputs[i]->type == type) + avfilter_formats_ref(fmts, + (AVFilterFormats**)((void*)ctx->inputs[i]+offout)); - for (i = 0; i < ctx->input_count; i++) { - if (ctx->inputs[i]) { - avfilter_formats_ref(formats, &ctx->inputs[i]->out_formats); - count++; - } - } - for (i = 0; i < ctx->output_count; i++) { - if (ctx->outputs[i]) { - avfilter_formats_ref(formats, &ctx->outputs[i]->in_formats); - count++; - } - } + for (i = 0; i < ctx->output_count; i++) + if (ctx->outputs[i] && ctx->outputs[i]->type == type) + avfilter_formats_ref(fmts, + (AVFilterFormats**)((void*)ctx->outputs[i]+offin)); - if (!count) { - av_free(formats->formats); - av_free(formats->refs); - av_free(formats); + if (!fmts->refcount) { + av_free(fmts->formats); + av_free(fmts->refs); + av_free(fmts); } } +void avfilter_set_common_pixel_formats(AVFilterContext *ctx, AVFilterFormats *formats) +{ + set_common_formats(ctx, formats, AVMEDIA_TYPE_VIDEO, + offsetof(AVFilterLink, in_formats), + offsetof(AVFilterLink, out_formats)); +} + +void avfilter_set_common_sample_formats(AVFilterContext *ctx, AVFilterFormats *formats) +{ + set_common_formats(ctx, formats, AVMEDIA_TYPE_AUDIO, + offsetof(AVFilterLink, in_formats), + offsetof(AVFilterLink, out_formats)); +} + +void avfilter_set_common_channel_layouts(AVFilterContext *ctx, AVFilterFormats *formats) +{ + set_common_formats(ctx, formats, AVMEDIA_TYPE_AUDIO, + offsetof(AVFilterLink, in_chlayouts), + offsetof(AVFilterLink, out_chlayouts)); +} + int avfilter_default_query_formats(AVFilterContext *ctx) { - enum AVMediaType type = ctx->inputs && ctx->inputs [0] ? ctx->inputs [0]->type : - ctx->outputs && ctx->outputs[0] ? ctx->outputs[0]->type : - AVMEDIA_TYPE_VIDEO; + avfilter_set_common_pixel_formats(ctx, avfilter_all_formats(AVMEDIA_TYPE_VIDEO)); + avfilter_set_common_sample_formats(ctx, avfilter_all_formats(AVMEDIA_TYPE_AUDIO)); + avfilter_set_common_channel_layouts(ctx, avfilter_all_channel_layouts()); - avfilter_set_common_formats(ctx, avfilter_all_formats(type)); return 0; } diff --git a/libavfilter/formats.c b/libavfilter/formats.c index 4e101c570c..49977c51fd 100644 --- a/libavfilter/formats.c +++ b/libavfilter/formats.c @@ -20,6 +20,7 @@ */ #include "libavutil/pixdesc.h" +#include "libavutil/audioconvert.h" #include "avfilter.h" /** @@ -139,6 +140,27 @@ AVFilterFormats *avfilter_all_formats(enum AVMediaType type) return ret; } +AVFilterFormats *avfilter_all_channel_layouts(void) +{ + static int64_t chlayouts[] = { + AV_CH_LAYOUT_MONO, + AV_CH_LAYOUT_STEREO, + AV_CH_LAYOUT_4POINT0, + AV_CH_LAYOUT_QUAD, + AV_CH_LAYOUT_5POINT0, + AV_CH_LAYOUT_5POINT0_BACK, + AV_CH_LAYOUT_5POINT1, + AV_CH_LAYOUT_5POINT1_BACK, + AV_CH_LAYOUT_5POINT1|AV_CH_LAYOUT_STEREO_DOWNMIX, + AV_CH_LAYOUT_7POINT1, + AV_CH_LAYOUT_7POINT1_WIDE, + AV_CH_LAYOUT_7POINT1|AV_CH_LAYOUT_STEREO_DOWNMIX, + -1, + }; + + return avfilter_make_format64_list(chlayouts); +} + void avfilter_formats_ref(AVFilterFormats *f, AVFilterFormats **ref) { *ref = f; diff --git a/libavfilter/vf_blackframe.c b/libavfilter/vf_blackframe.c index 658c30fd22..41b4a92ce5 100644 --- a/libavfilter/vf_blackframe.c +++ b/libavfilter/vf_blackframe.c @@ -44,7 +44,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_crop.c b/libavfilter/vf_crop.c index 8182a36531..531b8de658 100644 --- a/libavfilter/vf_crop.c +++ b/libavfilter/vf_crop.c @@ -104,7 +104,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_cropdetect.c b/libavfilter/vf_cropdetect.c index 000c8bb2c2..a997cbede8 100644 --- a/libavfilter/vf_cropdetect.c +++ b/libavfilter/vf_cropdetect.c @@ -46,7 +46,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_drawbox.c b/libavfilter/vf_drawbox.c index 3785072920..1ad8e94de2 100644 --- a/libavfilter/vf_drawbox.c +++ b/libavfilter/vf_drawbox.c @@ -70,7 +70,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index cf0eb43344..f495f68424 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -334,7 +334,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_fade.c b/libavfilter/vf_fade.c index 28179a3da4..6c2a23dac3 100644 --- a/libavfilter/vf_fade.c +++ b/libavfilter/vf_fade.c @@ -78,7 +78,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_format.c b/libavfilter/vf_format.c index c42e0bb373..9ecb0269ce 100644 --- a/libavfilter/vf_format.c +++ b/libavfilter/vf_format.c @@ -88,7 +88,7 @@ static AVFilterFormats *make_format_list(FormatContext *format, int flag) #if CONFIG_FORMAT_FILTER static int query_formats_format(AVFilterContext *ctx) { - avfilter_set_common_formats(ctx, make_format_list(ctx->priv, 1)); + avfilter_set_common_pixel_formats(ctx, make_format_list(ctx->priv, 1)); return 0; } @@ -118,7 +118,7 @@ AVFilter avfilter_vf_format = { #if CONFIG_NOFORMAT_FILTER static int query_formats_noformat(AVFilterContext *ctx) { - avfilter_set_common_formats(ctx, make_format_list(ctx->priv, 0)); + avfilter_set_common_pixel_formats(ctx, make_format_list(ctx->priv, 0)); return 0; } diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c index 0cb5fd30b5..ab1957089e 100644 --- a/libavfilter/vf_frei0r.c +++ b/libavfilter/vf_frei0r.c @@ -332,7 +332,7 @@ static int query_formats(AVFilterContext *ctx) if (!formats) return AVERROR(ENOMEM); - avfilter_set_common_formats(ctx, formats); + avfilter_set_common_pixel_formats(ctx, formats); return 0; } diff --git a/libavfilter/vf_gradfun.c b/libavfilter/vf_gradfun.c index 32dd3c1072..084dcc5c3c 100644 --- a/libavfilter/vf_gradfun.c +++ b/libavfilter/vf_gradfun.c @@ -160,7 +160,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_hflip.c b/libavfilter/vf_hflip.c index f1a37e7f5e..9b995a9894 100644 --- a/libavfilter/vf_hflip.c +++ b/libavfilter/vf_hflip.c @@ -62,7 +62,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_hqdn3d.c b/libavfilter/vf_hqdn3d.c index 78a7bf71c7..993ce7623d 100644 --- a/libavfilter/vf_hqdn3d.c +++ b/libavfilter/vf_hqdn3d.c @@ -268,7 +268,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_YUV420P, PIX_FMT_YUV422P, PIX_FMT_YUV411P, PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_libopencv.c b/libavfilter/vf_libopencv.c index b789c8e19c..e1b51c52c2 100644 --- a/libavfilter/vf_libopencv.c +++ b/libavfilter/vf_libopencv.c @@ -61,7 +61,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_BGR24, PIX_FMT_BGRA, PIX_FMT_GRAY8, PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_lut.c b/libavfilter/vf_lut.c index 792e274c33..c457972474 100644 --- a/libavfilter/vf_lut.c +++ b/libavfilter/vf_lut.c @@ -161,7 +161,7 @@ static int query_formats(AVFilterContext *ctx) enum PixelFormat *pix_fmts = lut->is_rgb ? rgb_pix_fmts : lut->is_yuv ? yuv_pix_fmts : all_pix_fmts; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_mp.c b/libavfilter/vf_mp.c index 0642b44f00..36616b9c94 100644 --- a/libavfilter/vf_mp.c +++ b/libavfilter/vf_mp.c @@ -796,7 +796,7 @@ static int query_formats(AVFilterContext *ctx) } //We assume all allowed input formats are also allowed output formats - avfilter_set_common_formats(ctx, avfmts); + avfilter_set_common_pixel_formats(ctx, avfmts); return 0; } diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c index 93d613d035..0ca5bd08fc 100644 --- a/libavfilter/vf_pad.c +++ b/libavfilter/vf_pad.c @@ -83,7 +83,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c index a5247c9753..8b11ae8d53 100644 --- a/libavfilter/vf_transpose.c +++ b/libavfilter/vf_transpose.c @@ -83,7 +83,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_unsharp.c b/libavfilter/vf_unsharp.c index fa75de5d94..3542ca3eac 100644 --- a/libavfilter/vf_unsharp.c +++ b/libavfilter/vf_unsharp.c @@ -155,7 +155,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_YUVJ444P, PIX_FMT_YUVJ440P, PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c index d608c65242..296328b71a 100644 --- a/libavfilter/vf_yadif.c +++ b/libavfilter/vf_yadif.c @@ -332,7 +332,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vsink_buffer.c b/libavfilter/vsink_buffer.c index c0824606a9..b5627b4f82 100644 --- a/libavfilter/vsink_buffer.c +++ b/libavfilter/vsink_buffer.c @@ -66,7 +66,7 @@ static int query_formats(AVFilterContext *ctx) { BufferSinkContext *buf = ctx->priv; - avfilter_set_common_formats(ctx, avfilter_make_format_list(buf->pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(buf->pix_fmts)); return 0; } diff --git a/libavfilter/vsrc_buffer.c b/libavfilter/vsrc_buffer.c index 246444b3ac..54867f7766 100644 --- a/libavfilter/vsrc_buffer.c +++ b/libavfilter/vsrc_buffer.c @@ -166,7 +166,7 @@ static int query_formats(AVFilterContext *ctx) BufferSourceContext *c = ctx->priv; enum PixelFormat pix_fmts[] = { c->pix_fmt, PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vsrc_color.c b/libavfilter/vsrc_color.c index 62c7f80945..00bfb66dee 100644 --- a/libavfilter/vsrc_color.c +++ b/libavfilter/vsrc_color.c @@ -99,7 +99,7 @@ static int query_formats(AVFilterContext *ctx) PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } diff --git a/libavfilter/vsrc_movie.c b/libavfilter/vsrc_movie.c index 7a3babbec8..eea2660cea 100644 --- a/libavfilter/vsrc_movie.c +++ b/libavfilter/vsrc_movie.c @@ -203,7 +203,7 @@ static int query_formats(AVFilterContext *ctx) MovieContext *movie = ctx->priv; enum PixelFormat pix_fmts[] = { movie->codec_ctx->pix_fmt, PIX_FMT_NONE }; - avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts)); + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); return 0; } From 6c0f5172f6735c0b185721ff0f456f53ef7ac677 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 19 Jun 2011 05:55:12 +0200 Subject: [PATCH 070/109] ffplay: dont drop frames by default when there is no audio stream Signed-off-by: Michael Niedermayer --- ffplay.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ffplay.c b/ffplay.c index b88387691d..ccb6045175 100644 --- a/ffplay.c +++ b/ffplay.c @@ -254,7 +254,7 @@ static int autoexit; static int exit_on_keydown; static int exit_on_mousedown; static int loop=1; -static int framedrop=1; +static int framedrop=-1; static enum ShowMode show_mode = SHOW_MODE_NONE; static int rdftspeed=20; @@ -1139,7 +1139,7 @@ retry: }else{ next_target= vp->target_clock + is->video_clock - vp->pts; //FIXME pass durations cleanly } - if(framedrop && time > next_target){ + if((framedrop>0 || (framedrop && is->audio_st)) && time > next_target){ is->skip_frames *= 1.0 + FRAME_SKIP_FACTOR; if(is->pictq_size > 1 || time > next_target + 0.5){ /* update queue size and signal for next picture */ From a7e4342fc1a0e962b829a9a194d034fa38590951 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 19 Jun 2011 13:09:16 +0200 Subject: [PATCH 071/109] avidec: consider non video to contain only keyframes when seeking. Fixes Ticket271 Signed-off-by: Michael Niedermayer --- libavformat/avidec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 72ea9e2944..80620dadba 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -1355,7 +1355,7 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp index = av_index_search_timestamp( st2, av_rescale_q(timestamp, st->time_base, st2->time_base) * FFMAX(ast2->sample_size, 1), - flags | AVSEEK_FLAG_BACKWARD); + flags | AVSEEK_FLAG_BACKWARD | (st2->codec->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0)); if(index<0) index=0; ast2->seek_pos= st2->index_entries[index].pos; @@ -1371,7 +1371,7 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp index = av_index_search_timestamp( st2, av_rescale_q(timestamp, st->time_base, st2->time_base) * FFMAX(ast2->sample_size, 1), - flags | AVSEEK_FLAG_BACKWARD); + flags | AVSEEK_FLAG_BACKWARD | (st2->codec->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0)); if(index<0) index=0; while(index>0 && st2->index_entries[index-1].pos >= pos_min) From 940a55ccf4898c641d0b3b7138d679943611e1d6 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 19 Jun 2011 17:57:51 +0200 Subject: [PATCH 072/109] eval: Fix 32bit unsigned parsing Fixes ticket264 Signed-off-by: Michael Niedermayer --- libavutil/eval.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavutil/eval.c b/libavutil/eval.c index 36cc76d3bf..fa2999b84c 100644 --- a/libavutil/eval.c +++ b/libavutil/eval.c @@ -76,7 +76,7 @@ double av_strtod(const char *numstr, char **tail) double d; char *next; if(numstr[0]=='0' && (numstr[1]|0x20)=='x') { - d = strtol(numstr, &next, 16); + d = strtoul(numstr, &next, 16); } else d = strtod(numstr, &next); /* if parsing succeeded, check for and interpret postfixes */ From 867b10679c0ea761ce423c104d8b1b8792d92fb9 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 19 Jun 2011 20:02:30 +0200 Subject: [PATCH 073/109] Attempt to fix ticket266 Signed-off-by: Michael Niedermayer --- libavcodec/mpegvideo.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index ec9a04a7ae..a0ff354a08 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -209,6 +209,7 @@ typedef struct MpegEncContext { /* the following codec id fields are deprecated in favor of codec_id */ int h263_plus; ///< h263 plus headers + int h263_msmpeg4; ///< generate MSMPEG4 compatible stream (deprecated, use msmpeg4_version instead) int h263_flv; ///< use flv h263 header enum CodecID codec_id; /* see CODEC_ID_xxx */ From 4aeb7769136ae60586d88d17fcce05be9669e72a Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 19 Jun 2011 20:32:37 +0200 Subject: [PATCH 074/109] dump_metadata: Fix 0xd in metadata Fixed ticket245 Signed-off-by: Michael Niedermayer --- libavformat/utils.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libavformat/utils.c b/libavformat/utils.c index 4fc74fa605..cd90480be6 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -3329,8 +3329,13 @@ static void dump_metadata(void *ctx, AVDictionary *m, const char *indent) av_log(ctx, AV_LOG_INFO, "%sMetadata:\n", indent); while((tag=av_dict_get(m, "", tag, AV_DICT_IGNORE_SUFFIX))) { - if(strcmp("language", tag->key)) - av_log(ctx, AV_LOG_INFO, "%s %-16s: %s\n", indent, tag->key, tag->value); + if(strcmp("language", tag->key)){ + char tmp[256]; + int i; + av_strlcpy(tmp, tag->value, sizeof(tmp)); + for(i=0; ikey, tmp); + } } } } From ae88e9cf99837e5eec811c817a17b2cbc9724a01 Mon Sep 17 00:00:00 2001 From: Yusuke Nakamura Date: Sun, 5 Jun 2011 01:28:43 +0900 Subject: [PATCH 075/109] mov: Fix empty edit detection. --- libavformat/mov.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index ab5c4e2db9..c720440472 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -2193,7 +2193,7 @@ static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom) time = avio_rb64(pb); } else { duration = avio_rb32(pb); /* segment duration */ - time = avio_rb32(pb); /* media time */ + time = (int32_t)avio_rb32(pb); /* media time */ } avio_rb32(pb); /* Media rate */ if (i == 0 && time >= -1) { From 54dd50d14dc3a3952f7d85165142d02f6ea578d7 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 20 Jun 2011 13:22:23 +0200 Subject: [PATCH 076/109] cmdutils: remove outcommented merge trash Signed-off-by: Michael Niedermayer --- cmdutils.c | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/cmdutils.c b/cmdutils.c index c3c5c0efa9..cd6d13346d 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -388,44 +388,8 @@ int opt_default(const char *opt, const char *arg){ exit(1); } if (!o) { -//<<<<<<< HEAD fprintf(stderr, "Unrecognized option '%s'\n", opt); exit(1); -/*||||||| merged common ancestors - AVCodec *p = NULL; - AVOutputFormat *oformat = NULL; - while ((p=av_codec_next(p))){ - const AVClass *c = p->priv_class; - if(c && av_find_opt(&c, opt, NULL, 0, 0)) - break; - } - if (!p) { - while ((oformat = av_oformat_next(oformat))) { - const AVClass *c = oformat->priv_class; - if (c && av_find_opt(&c, opt, NULL, 0, 0)) - break; - } - } - if(!p && !oformat){ - fprintf(stderr, "Unrecognized option '%s'\n", opt); - exit(1); - } -======= - AVCodec *p = NULL; - AVOutputFormat *oformat = NULL; - while ((p=av_codec_next(p))){ - const AVClass *c = p->priv_class; - if(c && av_opt_find(&c, opt, NULL, 0, 0)) - break; - } - if (!p) { - while ((oformat = av_oformat_next(oformat))) { - const AVClass *c = oformat->priv_class; - if (c && av_opt_find(&c, opt, NULL, 0, 0)) - break; - } - } ->>>>>>> qatar/master*/ } out: From ea6331f8bbaf3343faec6ffe77a6218a016a3af5 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 20 Jun 2011 10:24:33 -0400 Subject: [PATCH 077/109] h264-mt: fix deadlock in packets with multiple slices (e.g. MP4). --- libavcodec/h264.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/h264.c b/libavcodec/h264.c index b42468a781..dc4acb8379 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -3685,6 +3685,8 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ switch (hx->nal_unit_type) { case NAL_SPS: case NAL_PPS: + case NAL_IDR_SLICE: + case NAL_SLICE: nals_needed = nal_index; } continue; From 07935318598722e6ffe0f9980010a96f076d7152 Mon Sep 17 00:00:00 2001 From: Reinhard Tartler Date: Mon, 20 Jun 2011 12:20:54 +0200 Subject: [PATCH 078/109] Bump major version for b8e893399ff8755721dc117695ec5ff183c1e07b On architectures such as x86 (both 32 bit and 64bit), the stack element size is fixed, which maintains alignment. Here, this change does not break anything. However, we also support also other architectures where this property is not maintained and therefore, applications will crash horribly. This change effectively forces all applications to be recompiled against libswscale. --- libswscale/swscale.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libswscale/swscale.h b/libswscale/swscale.h index b0ad912a08..2aa5e50ab2 100644 --- a/libswscale/swscale.h +++ b/libswscale/swscale.h @@ -29,8 +29,8 @@ #include "libavutil/avutil.h" -#define LIBSWSCALE_VERSION_MAJOR 1 -#define LIBSWSCALE_VERSION_MINOR 1 +#define LIBSWSCALE_VERSION_MAJOR 2 +#define LIBSWSCALE_VERSION_MINOR 0 #define LIBSWSCALE_VERSION_MICRO 0 #define LIBSWSCALE_VERSION_INT AV_VERSION_INT(LIBSWSCALE_VERSION_MAJOR, \ @@ -48,10 +48,10 @@ * They may change, break or disappear at any time. */ #ifndef FF_API_SWS_GETCONTEXT -#define FF_API_SWS_GETCONTEXT (LIBSWSCALE_VERSION_MAJOR < 2) +#define FF_API_SWS_GETCONTEXT (LIBSWSCALE_VERSION_MAJOR < 3) #endif #ifndef FF_API_SWS_CPU_CAPS -#define FF_API_SWS_CPU_CAPS (LIBSWSCALE_VERSION_MAJOR < 2) +#define FF_API_SWS_CPU_CAPS (LIBSWSCALE_VERSION_MAJOR < 3) #endif /** From cfbaeb311d906099bd9b8fbf0fa38cdb1b08f23e Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Mon, 20 Jun 2011 20:13:26 +0200 Subject: [PATCH 079/109] ffmpeg: print warning if encoding would duplicate massive amounts of frames Signed-off-by: Michael Niedermayer --- ffmpeg.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ffmpeg.c b/ffmpeg.c index 0b1b1bee8d..dcb49d0fce 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -2326,6 +2326,11 @@ static int transcode(AVFormatContext **output_files, ost->frame_rate = ost->enc->supported_framerates[idx]; } codec->time_base = (AVRational){ost->frame_rate.den, ost->frame_rate.num}; + if( av_q2d(codec->time_base) < 0.001 && video_sync_method + && (video_sync_method==1 || (video_sync_method<0 && !(os->oformat->flags & AVFMT_VARIABLE_FPS)))){ + av_log(os, AV_LOG_WARNING, "Frame rate very high for a muxer not effciciently supporting it.\n" + "Please consider specifiying a lower framerate, a different muxer or -vsync 2\n"); + } #if CONFIG_AVFILTER if (configure_video_filters(ist, ost)) { From 3fd53defaa64e1a9295e88767088542b148616bd Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Mon, 16 May 2011 20:11:50 +0200 Subject: [PATCH 080/109] drawtext: fix strftime() text expansion The feature was dropped after the filter was partially rewritten and recommitted. Signed-off-by: Anton Khirnov --- libavfilter/vf_drawtext.c | 45 +++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index 8b28be9d9c..f47461f932 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -49,9 +49,11 @@ typedef struct { const AVClass *class; uint8_t *fontfile; ///< font to be used uint8_t *text; ///< text to be drawn - uint8_t *text_priv; ///< used to detect whether text changed + uint8_t *expanded_text; ///< used to contain the strftime()-expanded text + size_t expanded_text_size; ///< size in bytes of the expanded_text buffer int ft_load_flags; ///< flags used for loading fonts, see FT_LOAD_* FT_Vector *positions; ///< positions for each element in the text + size_t nb_positions; ///< number of elements of positions array char *textfile; ///< file with text to be drawn unsigned int x; ///< x position to start drawing text unsigned int y; ///< y position to start drawing text @@ -349,6 +351,7 @@ static av_cold void uninit(AVFilterContext *ctx) av_freep(&dtext->fontfile); av_freep(&dtext->text); + av_freep(&dtext->expanded_text); av_freep(&dtext->fontcolor_string); av_freep(&dtext->boxcolor_string); av_freep(&dtext->positions); @@ -517,7 +520,7 @@ static inline int is_newline(uint32_t c) static int draw_glyphs(DrawTextContext *dtext, AVFilterBufferRef *picref, int width, int height, const uint8_t rgbcolor[4], const uint8_t yuvcolor[4], int x, int y) { - char *text = dtext->text; + char *text = HAVE_LOCALTIME_R ? dtext->expanded_text : dtext->text; uint32_t code = 0; int i; uint8_t *p; @@ -559,45 +562,51 @@ static int draw_text(AVFilterContext *ctx, AVFilterBufferRef *picref, uint32_t code = 0, prev_code = 0; int x = 0, y = 0, i = 0, ret; int text_height, baseline; + char *text = dtext->text; uint8_t *p; - int str_w = 0; + int str_w = 0, len; int y_min = 32000, y_max = -32000; FT_Vector delta; Glyph *glyph = NULL, *prev_glyph = NULL; Glyph dummy = { 0 }; - if (dtext->text != dtext->text_priv) { #if HAVE_LOCALTIME_R time_t now = time(0); struct tm ltime; - uint8_t *buf = NULL; - int buflen = 2*strlen(dtext->text) + 1, len; + uint8_t *buf = dtext->expanded_text; + int buf_size = dtext->expanded_text_size; + + if (!buf) { + buf_size = 2*strlen(dtext->text)+1; + buf = av_malloc(buf_size); + } localtime_r(&now, <ime); - while ((buf = av_realloc(buf, buflen))) { + do { *buf = 1; - if ((len = strftime(buf, buflen, dtext->text, <ime)) != 0 || *buf == 0) + if (strftime(buf, buf_size, dtext->text, <ime) != 0 || *buf == 0) break; - buflen *= 2; - } + buf_size *= 2; + } while ((buf = av_realloc(buf, buf_size))); + if (!buf) return AVERROR(ENOMEM); - av_freep(&dtext->text); - dtext->text = dtext->text_priv = buf; -#else - dtext->text_priv = dtext->text; + text = dtext->expanded_text = buf; + dtext->expanded_text_size = buf_size; #endif - if (!(dtext->positions = av_realloc(dtext->positions, - strlen(dtext->text)*sizeof(*dtext->positions)))) + if ((len = strlen(text)) > dtext->nb_positions) { + if (!(dtext->positions = + av_realloc(dtext->positions, len*sizeof(*dtext->positions)))) return AVERROR(ENOMEM); + dtext->nb_positions = len; } x = dtext->x; y = dtext->y; /* load and cache glyphs */ - for (i = 0, p = dtext->text; *p; i++) { + for (i = 0, p = text; *p; i++) { GET_UTF8(code, *p++, continue;); /* get glyph */ @@ -614,7 +623,7 @@ static int draw_text(AVFilterContext *ctx, AVFilterBufferRef *picref, /* compute and save position for each glyph */ glyph = NULL; - for (i = 0, p = dtext->text; *p; i++) { + for (i = 0, p = text; *p; i++) { GET_UTF8(code, *p++, continue;); /* skip the \n in the sequence \r\n */ From 53a715f576bb4618f91a2f6caba995c48239a5f5 Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Mon, 16 May 2011 23:48:00 +0200 Subject: [PATCH 081/109] drawtext: reindent after the previous commit Signed-off-by: Anton Khirnov --- libavfilter/vf_drawtext.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index f47461f932..7a77d4fa9e 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -571,29 +571,29 @@ static int draw_text(AVFilterContext *ctx, AVFilterBufferRef *picref, Glyph dummy = { 0 }; #if HAVE_LOCALTIME_R - time_t now = time(0); - struct tm ltime; - uint8_t *buf = dtext->expanded_text; - int buf_size = dtext->expanded_text_size; + time_t now = time(0); + struct tm ltime; + uint8_t *buf = dtext->expanded_text; + int buf_size = dtext->expanded_text_size; - if (!buf) { - buf_size = 2*strlen(dtext->text)+1; - buf = av_malloc(buf_size); - } + if (!buf) { + buf_size = 2*strlen(dtext->text)+1; + buf = av_malloc(buf_size); + } - localtime_r(&now, <ime); + localtime_r(&now, <ime); - do { - *buf = 1; - if (strftime(buf, buf_size, dtext->text, <ime) != 0 || *buf == 0) - break; - buf_size *= 2; - } while ((buf = av_realloc(buf, buf_size))); + do { + *buf = 1; + if (strftime(buf, buf_size, dtext->text, <ime) != 0 || *buf == 0) + break; + buf_size *= 2; + } while ((buf = av_realloc(buf, buf_size))); - if (!buf) - return AVERROR(ENOMEM); - text = dtext->expanded_text = buf; - dtext->expanded_text_size = buf_size; + if (!buf) + return AVERROR(ENOMEM); + text = dtext->expanded_text = buf; + dtext->expanded_text_size = buf_size; #endif if ((len = strlen(text)) > dtext->nb_positions) { if (!(dtext->positions = From 702a62a1c6b97a8befa114da4ab4aa2b541352af Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Mon, 16 May 2011 23:44:35 +0200 Subject: [PATCH 082/109] drawtext: add braces around initialisers for option defaults MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix warnings of the type: vf_drawtext.c:NNN: warning: missing braces around initializer vf_drawtext.c:NNN: warning: (near initialization for ‘drawtext_options[X].default_val’) Signed-off-by: Anton Khirnov --- libavfilter/vf_drawtext.c | 58 +++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index 7a77d4fa9e..a3adaa7dfc 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -86,37 +86,37 @@ typedef struct { #define OFFSET(x) offsetof(DrawTextContext, x) static const AVOption drawtext_options[]= { -{"fontfile", "set font file", OFFSET(fontfile), FF_OPT_TYPE_STRING, 0, CHAR_MIN, CHAR_MAX }, -{"text", "set text", OFFSET(text), FF_OPT_TYPE_STRING, 0, CHAR_MIN, CHAR_MAX }, -{"textfile", "set text file", OFFSET(textfile), FF_OPT_TYPE_STRING, 0, CHAR_MIN, CHAR_MAX }, -{"fontcolor","set foreground color", OFFSET(fontcolor_string), FF_OPT_TYPE_STRING, 0, CHAR_MIN, CHAR_MAX }, -{"boxcolor", "set box color", OFFSET(boxcolor_string), FF_OPT_TYPE_STRING, 0, CHAR_MIN, CHAR_MAX }, -{"shadowcolor", "set shadow color", OFFSET(shadowcolor_string), FF_OPT_TYPE_STRING, 0, CHAR_MIN, CHAR_MAX }, -{"box", "set box", OFFSET(draw_box), FF_OPT_TYPE_INT, 0, 0, 1 }, -{"fontsize", "set font size", OFFSET(fontsize), FF_OPT_TYPE_INT, 16, 1, 72 }, -{"x", "set x", OFFSET(x), FF_OPT_TYPE_INT, 0, 0, INT_MAX }, -{"y", "set y", OFFSET(y), FF_OPT_TYPE_INT, 0, 0, INT_MAX }, -{"shadowx", "set x", OFFSET(shadowx), FF_OPT_TYPE_INT, 0, INT_MIN, INT_MAX }, -{"shadowy", "set y", OFFSET(shadowy), FF_OPT_TYPE_INT, 0, INT_MIN, INT_MAX }, -{"tabsize", "set tab size", OFFSET(tabsize), FF_OPT_TYPE_INT, 4, 0, INT_MAX }, +{"fontfile", "set font file", OFFSET(fontfile), FF_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX }, +{"text", "set text", OFFSET(text), FF_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX }, +{"textfile", "set text file", OFFSET(textfile), FF_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX }, +{"fontcolor","set foreground color", OFFSET(fontcolor_string), FF_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX }, +{"boxcolor", "set box color", OFFSET(boxcolor_string), FF_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX }, +{"shadowcolor", "set shadow color", OFFSET(shadowcolor_string), FF_OPT_TYPE_STRING, {.str=NULL}, CHAR_MIN, CHAR_MAX }, +{"box", "set box", OFFSET(draw_box), FF_OPT_TYPE_INT, {.dbl=0}, 0, 1 }, +{"fontsize", "set font size", OFFSET(fontsize), FF_OPT_TYPE_INT, {.dbl=16}, 1, 72 }, +{"x", "set x", OFFSET(x), FF_OPT_TYPE_INT, {.dbl=0}, 0, INT_MAX }, +{"y", "set y", OFFSET(y), FF_OPT_TYPE_INT, {.dbl=0}, 0, INT_MAX }, +{"shadowx", "set x", OFFSET(shadowx), FF_OPT_TYPE_INT, {.dbl=0}, INT_MIN, INT_MAX }, +{"shadowy", "set y", OFFSET(shadowy), FF_OPT_TYPE_INT, {.dbl=0}, INT_MIN, INT_MAX }, +{"tabsize", "set tab size", OFFSET(tabsize), FF_OPT_TYPE_INT, {.dbl=4}, 0, INT_MAX }, /* FT_LOAD_* flags */ -{"ft_load_flags", "set font loading flags for libfreetype", OFFSET(ft_load_flags), FF_OPT_TYPE_FLAGS, FT_LOAD_DEFAULT|FT_LOAD_RENDER, 0, INT_MAX, 0, "ft_load_flags" }, -{"default", "set default", 0, FF_OPT_TYPE_CONST, FT_LOAD_DEFAULT, INT_MIN, INT_MAX, 0, "ft_load_flags" }, -{"no_scale", "set no_scale", 0, FF_OPT_TYPE_CONST, FT_LOAD_NO_SCALE, INT_MIN, INT_MAX, 0, "ft_load_flags" }, -{"no_hinting", "set no_hinting", 0, FF_OPT_TYPE_CONST, FT_LOAD_NO_HINTING, INT_MIN, INT_MAX, 0, "ft_load_flags" }, -{"render", "set render", 0, FF_OPT_TYPE_CONST, FT_LOAD_RENDER, INT_MIN, INT_MAX, 0, "ft_load_flags" }, -{"no_bitmap", "set no_bitmap", 0, FF_OPT_TYPE_CONST, FT_LOAD_NO_BITMAP, INT_MIN, INT_MAX, 0, "ft_load_flags" }, -{"vertical_layout", "set vertical_layout", 0, FF_OPT_TYPE_CONST, FT_LOAD_VERTICAL_LAYOUT, INT_MIN, INT_MAX, 0, "ft_load_flags" }, -{"force_autohint", "set force_autohint", 0, FF_OPT_TYPE_CONST, FT_LOAD_FORCE_AUTOHINT, INT_MIN, INT_MAX, 0, "ft_load_flags" }, -{"crop_bitmap", "set crop_bitmap", 0, FF_OPT_TYPE_CONST, FT_LOAD_CROP_BITMAP, INT_MIN, INT_MAX, 0, "ft_load_flags" }, -{"pedantic", "set pedantic", 0, FF_OPT_TYPE_CONST, FT_LOAD_PEDANTIC, INT_MIN, INT_MAX, 0, "ft_load_flags" }, -{"ignore_global_advance_width", "set ignore_global_advance_width", 0, FF_OPT_TYPE_CONST, FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH, INT_MIN, INT_MAX, 0, "ft_load_flags" }, -{"no_recurse", "set no_recurse", 0, FF_OPT_TYPE_CONST, FT_LOAD_NO_RECURSE, INT_MIN, INT_MAX, 0, "ft_load_flags" }, -{"ignore_transform", "set ignore_transform", 0, FF_OPT_TYPE_CONST, FT_LOAD_IGNORE_TRANSFORM, INT_MIN, INT_MAX, 0, "ft_load_flags" }, -{"monochrome", "set monochrome", 0, FF_OPT_TYPE_CONST, FT_LOAD_MONOCHROME, INT_MIN, INT_MAX, 0, "ft_load_flags" }, -{"linear_design", "set linear_design", 0, FF_OPT_TYPE_CONST, FT_LOAD_LINEAR_DESIGN, INT_MIN, INT_MAX, 0, "ft_load_flags" }, -{"no_autohint", "set no_autohint", 0, FF_OPT_TYPE_CONST, FT_LOAD_NO_AUTOHINT, INT_MIN, INT_MAX, 0, "ft_load_flags" }, +{"ft_load_flags", "set font loading flags for libfreetype", OFFSET(ft_load_flags), FF_OPT_TYPE_FLAGS, {.dbl=FT_LOAD_DEFAULT|FT_LOAD_RENDER}, 0, INT_MAX, 0, "ft_load_flags" }, +{"default", "set default", 0, FF_OPT_TYPE_CONST, {FT_LOAD_DEFAULT}, INT_MIN, INT_MAX, 0, "ft_load_flags" }, +{"no_scale", "set no_scale", 0, FF_OPT_TYPE_CONST, {FT_LOAD_NO_SCALE}, INT_MIN, INT_MAX, 0, "ft_load_flags" }, +{"no_hinting", "set no_hinting", 0, FF_OPT_TYPE_CONST, {FT_LOAD_NO_HINTING}, INT_MIN, INT_MAX, 0, "ft_load_flags" }, +{"render", "set render", 0, FF_OPT_TYPE_CONST, {FT_LOAD_RENDER}, INT_MIN, INT_MAX, 0, "ft_load_flags" }, +{"no_bitmap", "set no_bitmap", 0, FF_OPT_TYPE_CONST, {FT_LOAD_NO_BITMAP}, INT_MIN, INT_MAX, 0, "ft_load_flags" }, +{"vertical_layout", "set vertical_layout", 0, FF_OPT_TYPE_CONST, {FT_LOAD_VERTICAL_LAYOUT}, INT_MIN, INT_MAX, 0, "ft_load_flags" }, +{"force_autohint", "set force_autohint", 0, FF_OPT_TYPE_CONST, {FT_LOAD_FORCE_AUTOHINT}, INT_MIN, INT_MAX, 0, "ft_load_flags" }, +{"crop_bitmap", "set crop_bitmap", 0, FF_OPT_TYPE_CONST, {FT_LOAD_CROP_BITMAP}, INT_MIN, INT_MAX, 0, "ft_load_flags" }, +{"pedantic", "set pedantic", 0, FF_OPT_TYPE_CONST, {FT_LOAD_PEDANTIC}, INT_MIN, INT_MAX, 0, "ft_load_flags" }, +{"ignore_global_advance_width", "set ignore_global_advance_width", 0, FF_OPT_TYPE_CONST, {FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH}, INT_MIN, INT_MAX, 0, "ft_load_flags" }, +{"no_recurse", "set no_recurse", 0, FF_OPT_TYPE_CONST, {FT_LOAD_NO_RECURSE}, INT_MIN, INT_MAX, 0, "ft_load_flags" }, +{"ignore_transform", "set ignore_transform", 0, FF_OPT_TYPE_CONST, {FT_LOAD_IGNORE_TRANSFORM}, INT_MIN, INT_MAX, 0, "ft_load_flags" }, +{"monochrome", "set monochrome", 0, FF_OPT_TYPE_CONST, {FT_LOAD_MONOCHROME}, INT_MIN, INT_MAX, 0, "ft_load_flags" }, +{"linear_design", "set linear_design", 0, FF_OPT_TYPE_CONST, {FT_LOAD_LINEAR_DESIGN}, INT_MIN, INT_MAX, 0, "ft_load_flags" }, +{"no_autohint", "set no_autohint", 0, FF_OPT_TYPE_CONST, {FT_LOAD_NO_AUTOHINT}, INT_MIN, INT_MAX, 0, "ft_load_flags" }, {NULL}, }; From 5a0a6ae639ac791ddebce64e2c316186d1db575c Mon Sep 17 00:00:00 2001 From: Stefano Sabatini Date: Thu, 21 Apr 2011 10:31:48 +0200 Subject: [PATCH 083/109] ocv: replace FF_INTERNAL_MEM_TYPE_MAX_VALUE with SIZE_MAX Fix compilatin after removal of FF_INTERNAL_MEM_TYPE_MAX_VALUE. Signed-off-by: Stefano Sabatini Signed-off-by: Anton Khirnov --- libavfilter/vf_libopencv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavfilter/vf_libopencv.c b/libavfilter/vf_libopencv.c index 509b1d96dc..5a52f246ba 100644 --- a/libavfilter/vf_libopencv.c +++ b/libavfilter/vf_libopencv.c @@ -158,7 +158,7 @@ static int read_shape_from_file(int *cols, int *rows, int **values, const char * } w++; } - if (*rows > (FF_INTERNAL_MEM_TYPE_MAX_VALUE / (sizeof(int)) / *cols)) { + if (*rows > (SIZE_MAX / sizeof(int) / *cols)) { av_log(log_ctx, AV_LOG_ERROR, "File with size %dx%d is too big\n", *rows, *cols); return AVERROR_INVALIDDATA; From 3a07f5a47a16bef86faab99bc02d2fd0f396afe8 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 18 Jun 2011 02:44:17 +0200 Subject: [PATCH 084/109] qdm2: Fix alignment of local array. Fixes ticket270 Signed-off-by: Michael Niedermayer Signed-off-by: Anton Khirnov --- libavcodec/qdm2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c index 53ee304a28..86847adc10 100644 --- a/libavcodec/qdm2.c +++ b/libavcodec/qdm2.c @@ -175,6 +175,7 @@ typedef struct { DECLARE_ALIGNED(32, float, synth_buf)[MPA_MAX_CHANNELS][512*2]; int synth_buf_offset[MPA_MAX_CHANNELS]; DECLARE_ALIGNED(32, float, sb_samples)[MPA_MAX_CHANNELS][128][SBLIMIT]; + DECLARE_ALIGNED(32, float, samples)[MPA_MAX_CHANNELS * MPA_FRAME_SIZE]; /// Mixed temporary data used in decoding float tone_level[MPA_MAX_CHANNELS][30][64]; @@ -1598,7 +1599,6 @@ static void qdm2_calculate_fft (QDM2Context *q, int channel, int sub_packet) */ static void qdm2_synthesis_filter (QDM2Context *q, int index) { - float samples[MPA_MAX_CHANNELS * MPA_FRAME_SIZE]; int i, k, ch, sb_used, sub_sampling, dither_state = 0; /* copy sb_samples */ @@ -1610,7 +1610,7 @@ static void qdm2_synthesis_filter (QDM2Context *q, int index) q->sb_samples[ch][(8 * index) + i][k] = 0; for (ch = 0; ch < q->nb_channels; ch++) { - float *samples_ptr = samples + ch; + float *samples_ptr = q->samples + ch; for (i = 0; i < 8; i++) { ff_mpa_synth_filter_float(&q->mpadsp, @@ -1627,7 +1627,7 @@ static void qdm2_synthesis_filter (QDM2Context *q, int index) for (ch = 0; ch < q->channels; ch++) for (i = 0; i < q->frame_size; i++) - q->output_buffer[q->channels * i + ch] += (1 << 23) * samples[q->nb_channels * sub_sampling * i + ch]; + q->output_buffer[q->channels * i + ch] += (1 << 23) * q->samples[q->nb_channels * sub_sampling * i + ch]; } From d42aaa802e2b74dcb83d426001557f8229b1b484 Mon Sep 17 00:00:00 2001 From: Ronald Bultje Date: Mon, 20 Jun 2011 15:07:55 +0000 Subject: [PATCH 085/109] error_resilience: actually add counter when adding a MV predictor. Without, the predictor isn't actually used. --- libavcodec/error_resilience.c | 1 + tests/ref/vsynth1/error | 4 ++-- tests/ref/vsynth2/error | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c index aea0e15b34..ad7a7c6ac6 100644 --- a/libavcodec/error_resilience.c +++ b/libavcodec/error_resilience.c @@ -547,6 +547,7 @@ skip_mean_and_median: mv_predictor[pred_count][0]= prev_x; mv_predictor[pred_count][1]= prev_y; ref [pred_count] = prev_ref; + pred_count++; s->mv_dir = MV_DIR_FORWARD; s->mb_intra=0; diff --git a/tests/ref/vsynth1/error b/tests/ref/vsynth1/error index 7edef21c90..bc24d5b2af 100644 --- a/tests/ref/vsynth1/error +++ b/tests/ref/vsynth1/error @@ -1,4 +1,4 @@ 7416dfd319f04044d4575dc9d1b406e1 *./tests/data/vsynth1/error-mpeg4-adv.avi 756836 ./tests/data/vsynth1/error-mpeg4-adv.avi -54342963593ba08bcde95244a011efe5 *./tests/data/error.vsynth1.out.yuv -stddev: 17.59 PSNR: 23.22 MAXDIFF: 240 bytes: 7603200/ 7603200 +79e94ba32b37759397362cbcb479d4d3 *./tests/data/error.vsynth1.out.yuv +stddev: 18.36 PSNR: 22.85 MAXDIFF: 243 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth2/error b/tests/ref/vsynth2/error index 99363f5a42..424c54962b 100644 --- a/tests/ref/vsynth2/error +++ b/tests/ref/vsynth2/error @@ -1,4 +1,4 @@ 90e65096aa9ebafa3fe3f44a5a47cdc4 *./tests/data/vsynth2/error-mpeg4-adv.avi 176588 ./tests/data/vsynth2/error-mpeg4-adv.avi -ce12aa852126f2740838dd2da9e21a03 *./tests/data/error.vsynth2.out.yuv -stddev: 10.06 PSNR: 28.08 MAXDIFF: 193 bytes: 7603200/ 7603200 +96baa9e4c24c837a3ba5abd8dd2cdd30 *./tests/data/error.vsynth2.out.yuv +stddev: 8.98 PSNR: 29.06 MAXDIFF: 184 bytes: 7603200/ 7603200 From 20153fb8f6ce7f482298170d2700befe898fa1cd Mon Sep 17 00:00:00 2001 From: Ronald Bultje Date: Mon, 20 Jun 2011 15:07:56 +0000 Subject: [PATCH 086/109] error_resilience: skip last-MV predictor step if MVs are not available. Fixes crashes when playing broken MPEG2-TS streams. --- libavcodec/error_resilience.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c index ad7a7c6ac6..8906b49c80 100644 --- a/libavcodec/error_resilience.c +++ b/libavcodec/error_resilience.c @@ -534,6 +534,9 @@ skip_mean_and_median: ff_thread_await_progress((AVFrame *) s->last_picture_ptr, mb_y, 0); } + if (!s->last_picture.motion_val[0] || + !s->last_picture.ref_index[0]) + goto skip_last_mv; prev_x = s->last_picture.motion_val[0][mot_index][0]; prev_y = s->last_picture.motion_val[0][mot_index][1]; prev_ref = s->last_picture.ref_index[0][4*mb_xy]; @@ -548,6 +551,7 @@ skip_mean_and_median: mv_predictor[pred_count][1]= prev_y; ref [pred_count] = prev_ref; pred_count++; + skip_last_mv: s->mv_dir = MV_DIR_FORWARD; s->mb_intra=0; From dea22a1a912d5e6214db5c6a4addbc7b26881817 Mon Sep 17 00:00:00 2001 From: Reinhard Tartler Date: Mon, 20 Jun 2011 22:40:31 +0200 Subject: [PATCH 087/109] document libswscale bump --- Changelog | 1 + doc/APIchanges | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Changelog b/Changelog index a5044498a5..b785197083 100644 --- a/Changelog +++ b/Changelog @@ -11,6 +11,7 @@ version 0.7: - All av_metadata_* functions renamed to av_dict_* and moved to libavutil - 4:4:4 H.264 decoding support - 10-bit H.264 optimizations for x86 +- Bump libswscale for recently reported ABI break version 0.7_beta2: diff --git a/doc/APIchanges b/doc/APIchanges index 460e8dde83..79d9749373 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -7,7 +7,7 @@ libavdevice: 2011-04-18 libavfilter: 2011-04-18 libavformat: 2011-04-18 libpostproc: 2011-04-18 -libswscale: 2011-04-18 +libswscale: 2011-06-20 libavutil: 2011-04-18 From 093768c9a4855b82c13124f835b655dd70883012 Mon Sep 17 00:00:00 2001 From: Ivan Kalvachev Date: Thu, 16 Jun 2011 19:35:33 +0300 Subject: [PATCH 088/109] Fix bink audio playback outside of FFmpeg. There are 2 known Bink audio codecs. Additionally they have a different flavor if they are found inside Bink-b "BIKb" file. In order to guess the correct flavor, the demuxer sets the audio codec_tag to be the same as the file format tag. This causes problem because same tag is used for both audio codecs. The hack works in FFmpeg because audio codecs are identified by their codec_id, but other players rely on standard behavior. This fix removes the codec_tag hack and instead uses artificial extradata format to signal the codec flavor. This would also allow proper embedding of Bink audio in other containers. Signed-off-by: Ivan Kalvachev Signed-off-by: Michael Niedermayer --- libavcodec/binkaudio.c | 3 ++- libavformat/bink.c | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c index bf1d412ed1..ff36458c7e 100644 --- a/libavcodec/binkaudio.c +++ b/libavcodec/binkaudio.c @@ -90,7 +90,8 @@ static av_cold int decode_init(AVCodecContext *avctx) return -1; } - s->version_b = avctx->codec_tag == MKTAG('B','I','K','b'); + if (avctx->extradata && avctx->extradata_size > 0) + s->version_b = avctx->extradata[0]; if (avctx->codec->id == CODEC_ID_BINKAUDIO_RDFT) { // audio is already interleaved for the RDFT format variant diff --git a/libavformat/bink.c b/libavformat/bink.c index 3bcaff3c51..eed52cdb49 100644 --- a/libavformat/bink.c +++ b/libavformat/bink.c @@ -134,13 +134,15 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap) if (!ast) return AVERROR(ENOMEM); ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; - ast->codec->codec_tag = vst->codec->codec_tag; ast->codec->sample_rate = avio_rl16(pb); av_set_pts_info(ast, 64, 1, ast->codec->sample_rate); flags = avio_rl16(pb); ast->codec->codec_id = flags & BINK_AUD_USEDCT ? CODEC_ID_BINKAUDIO_DCT : CODEC_ID_BINKAUDIO_RDFT; ast->codec->channels = flags & BINK_AUD_STEREO ? 2 : 1; + ast->codec->extradata = av_mallocz(1 + FF_INPUT_BUFFER_PADDING_SIZE); + ast->codec->extradata_size = 1; + ast->codec->extradata[0] = vst->codec->codec_tag == MKTAG('B','I','K','b'); } for (i = 0; i < bink->num_audio_tracks; i++) From eaa2d5a90a208fff0662b62da67b7b090b9fff8c Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Mon, 20 Jun 2011 00:59:35 +0100 Subject: [PATCH 089/109] cabac: remove #if 0 cascade under never-set #ifdef ARCH_X86_DISABLED Signed-off-by: Mans Rullgard --- libavcodec/cabac.h | 62 ---------------------------------------------- 1 file changed, 62 deletions(-) diff --git a/libavcodec/cabac.h b/libavcodec/cabac.h index 4708563904..53e327d661 100644 --- a/libavcodec/cabac.h +++ b/libavcodec/cabac.h @@ -36,7 +36,6 @@ #define CABAC_BITS 16 #define CABAC_MASK ((1<63 for x86-64 - "shl %%cl, %0 \n\t" - "shl %%cl, %1 \n\t" - : "+r"(c->range), "+r"(c->low), "+c"(temp) - ); -#elif 0 - //P3:680 athlon:474 - __asm__( - "cmp $0x100, %0 \n\t" - "setb %%cl \n\t" //FIXME 31->63 for x86-64 - "shl %%cl, %0 \n\t" - "shl %%cl, %1 \n\t" - : "+r"(c->range), "+r"(c->low), "+c"(temp) - ); -#elif 1 - int temp2; - //P3:665 athlon:517 - __asm__( - "lea -0x100(%0), %%eax \n\t" - "cltd \n\t" - "mov %0, %%eax \n\t" - "and %%edx, %0 \n\t" - "and %1, %%edx \n\t" - "add %%eax, %0 \n\t" - "add %%edx, %1 \n\t" - : "+r"(c->range), "+r"(c->low), "+a"(temp), "+d"(temp2) - ); -#elif 0 - int temp2; - //P3:673 athlon:509 - __asm__( - "cmp $0x100, %0 \n\t" - "sbb %%edx, %%edx \n\t" - "mov %0, %%eax \n\t" - "and %%edx, %0 \n\t" - "and %1, %%edx \n\t" - "add %%eax, %0 \n\t" - "add %%edx, %1 \n\t" - : "+r"(c->range), "+r"(c->low), "+a"(temp), "+d"(temp2) - ); -#else - int temp2; - //P3:677 athlon:511 - __asm__( - "cmp $0x100, %0 \n\t" - "lea (%0, %0), %%eax \n\t" - "lea (%1, %1), %%edx \n\t" - "cmovb %%eax, %0 \n\t" - "cmovb %%edx, %1 \n\t" - : "+r"(c->range), "+r"(c->low), "+a"(temp), "+d"(temp2) - ); -#endif -#else - //P3:675 athlon:476 int shift= (uint32_t)(c->range - 0x100)>>31; c->range<<= shift; c->low <<= shift; -#endif if(!(c->low & CABAC_MASK)) refill(c); } From 8fcc0e7978e03cbf7e6d872d34ca1ea4a7d97b87 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Mon, 20 Jun 2011 01:49:38 +0100 Subject: [PATCH 090/109] cabac: remove BRANCHLESS_CABAC_DECODER switch The code does not compile without this set. Signed-off-by: Mans Rullgard --- libavcodec/cabac.c | 8 ---- libavcodec/cabac.h | 106 +-------------------------------------------- 2 files changed, 1 insertion(+), 113 deletions(-) diff --git a/libavcodec/cabac.c b/libavcodec/cabac.c index 098cd6fad9..691beb0ae3 100644 --- a/libavcodec/cabac.c +++ b/libavcodec/cabac.c @@ -161,19 +161,11 @@ void ff_init_cabac_states(CABACContext *c){ ff_h264_mps_state[2*i+1]= 2*mps_state[i]+1; if( i ){ -#ifdef BRANCHLESS_CABAC_DECODER ff_h264_mlps_state[128-2*i-1]= 2*lps_state[i]+0; ff_h264_mlps_state[128-2*i-2]= 2*lps_state[i]+1; }else{ ff_h264_mlps_state[128-2*i-1]= 1; ff_h264_mlps_state[128-2*i-2]= 0; -#else - ff_h264_lps_state[2*i+0]= 2*lps_state[i]+0; - ff_h264_lps_state[2*i+1]= 2*lps_state[i]+1; - }else{ - ff_h264_lps_state[2*i+0]= 1; - ff_h264_lps_state[2*i+1]= 0; -#endif } } } diff --git a/libavcodec/cabac.h b/libavcodec/cabac.h index 53e327d661..6b7ef4501c 100644 --- a/libavcodec/cabac.h +++ b/libavcodec/cabac.h @@ -35,7 +35,6 @@ #define CABAC_BITS 16 #define CABAC_MASK ((1<range&0xC0) + s]; - int bit, lps_mask av_unused; + int bit, lps_mask; c->range -= RangeLPS; -#ifndef BRANCHLESS_CABAC_DECODER - if(c->low < (c->range<<(CABAC_BITS+1))){ - bit= s&1; - *state= ff_h264_mps_state[s]; - renorm_cabac_decoder_once(c); - }else{ - bit= ff_h264_norm_shift[RangeLPS]; - c->low -= (c->range<<(CABAC_BITS+1)); - *state= ff_h264_lps_state[s]; - c->range = RangeLPS<low <<= bit; - bit= (s&1)^1; - - if(!(c->low & CABAC_MASK)){ - refill2(c); - } - } -#else /* BRANCHLESS_CABAC_DECODER */ lps_mask= ((c->range<<(CABAC_BITS+1)) - c->low)>>31; c->low -= (c->range<<(CABAC_BITS+1)) & lps_mask; @@ -513,7 +410,6 @@ static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const st c->low <<= lps_mask; if(!(c->low & CABAC_MASK)) refill2(c); -#endif /* BRANCHLESS_CABAC_DECODER */ #endif /* ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) */ return bit; } From 34ee43fc0fa7f40a280f4f93a3c6aa5bf7a2704b Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Mon, 20 Jun 2011 01:58:36 +0100 Subject: [PATCH 091/109] cabac: remove inline asm under #if 0 A comment says it's not faster than the C code. Signed-off-by: Mans Rullgard --- libavcodec/cabac.h | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/libavcodec/cabac.h b/libavcodec/cabac.h index 6b7ef4501c..0993eb80b3 100644 --- a/libavcodec/cabac.h +++ b/libavcodec/cabac.h @@ -423,36 +423,6 @@ static int av_unused get_cabac(CABACContext *c, uint8_t * const state){ } static int av_unused get_cabac_bypass(CABACContext *c){ -#if 0 //not faster - int bit; - __asm__ volatile( - "movl "RANGE "(%1), %%ebx \n\t" - "movl "LOW "(%1), %%eax \n\t" - "shl $17, %%ebx \n\t" - "add %%eax, %%eax \n\t" - "sub %%ebx, %%eax \n\t" - "cltd \n\t" - "and %%edx, %%ebx \n\t" - "add %%ebx, %%eax \n\t" - "test %%ax, %%ax \n\t" - " jnz 1f \n\t" - "movl "BYTE "(%1), %%"REG_b" \n\t" - "subl $0xFFFF, %%eax \n\t" - "movzwl (%%"REG_b"), %%ecx \n\t" - "bswap %%ecx \n\t" - "shrl $15, %%ecx \n\t" - "addl $2, %%"REG_b" \n\t" - "addl %%ecx, %%eax \n\t" - "movl %%"REG_b", "BYTE "(%1) \n\t" - "1: \n\t" - "movl %%eax, "LOW "(%1) \n\t" - - :"=&d"(bit) - :"r"(c) - : "%eax", "%"REG_b, "%ecx", "memory" - ); - return bit+1; -#else int range; c->low += c->low; @@ -466,7 +436,6 @@ static int av_unused get_cabac_bypass(CABACContext *c){ c->low -= range; return 1; } -#endif } From 6b712acc0e4face7e913fbffd03123fc24672654 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Mon, 20 Jun 2011 01:54:32 +0100 Subject: [PATCH 092/109] x86: cabac: remove hardcoded struct offsets from inline asm Signed-off-by: Mans Rullgard --- libavcodec/cabac.h | 47 +++++++++++++++++--------------------- libavcodec/x86/h264_i386.h | 34 +++++++++++++++------------ 2 files changed, 41 insertions(+), 40 deletions(-) diff --git a/libavcodec/cabac.h b/libavcodec/cabac.h index 0993eb80b3..67a332eba8 100644 --- a/libavcodec/cabac.h +++ b/libavcodec/cabac.h @@ -27,6 +27,8 @@ #ifndef AVCODEC_CABAC_H #define AVCODEC_CABAC_H +#include + #include "put_bits.h" //#undef NDEBUG @@ -307,17 +309,6 @@ static inline void renorm_cabac_decoder_once(CABACContext *c){ static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){ //FIXME gcc generates duplicate load/stores for c->low and c->range -#define LOW "0" -#define RANGE "4" -#if ARCH_X86_64 -#define BYTESTART "16" -#define BYTE "24" -#define BYTEEND "32" -#else -#define BYTESTART "12" -#define BYTE "16" -#define BYTEEND "20" -#endif #if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) int bit; @@ -347,7 +338,7 @@ static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const st #endif /* HAVE_FAST_CMOV */ -#define BRANCHLESS_GET_CABAC(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\ +#define BRANCHLESS_GET_CABAC(ret, cabac, statep, low, lowword, range, tmp, tmpbyte, byte) \ "movzbl "statep" , "ret" \n\t"\ "mov "range" , "tmp" \n\t"\ "and $0xC0 , "range" \n\t"\ @@ -361,13 +352,13 @@ static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const st "shl %%cl , "low" \n\t"\ "test "lowword" , "lowword" \n\t"\ " jnz 1f \n\t"\ - "mov "BYTE"("cabac"), %%"REG_c" \n\t"\ + "mov "byte"("cabac"), %%"REG_c" \n\t"\ "movzwl (%%"REG_c") , "tmp" \n\t"\ "bswap "tmp" \n\t"\ "shr $15 , "tmp" \n\t"\ "sub $0xFFFF , "tmp" \n\t"\ "add $2 , %%"REG_c" \n\t"\ - "mov %%"REG_c" , "BYTE "("cabac") \n\t"\ + "mov %%"REG_c" , "byte "("cabac") \n\t"\ "lea -1("low") , %%ecx \n\t"\ "xor "low" , %%ecx \n\t"\ "shr $15 , %%ecx \n\t"\ @@ -379,14 +370,16 @@ static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const st "1: \n\t" __asm__ volatile( - "movl "RANGE "(%2), %%esi \n\t" - "movl "LOW "(%2), %%ebx \n\t" - BRANCHLESS_GET_CABAC("%0", "%2", "(%1)", "%%ebx", "%%bx", "%%esi", "%%edx", "%%dl") - "movl %%esi, "RANGE "(%2) \n\t" - "movl %%ebx, "LOW "(%2) \n\t" + "movl %a3(%2), %%esi \n\t" + "movl %a4(%2), %%ebx \n\t" + BRANCHLESS_GET_CABAC("%0", "%2", "(%1)", "%%ebx", "%%bx", "%%esi", "%%edx", "%%dl", "%a5") + "movl %%esi, %a3(%2) \n\t" + "movl %%ebx, %a4(%2) \n\t" :"=&a"(bit) - :"r"(state), "r"(c) + :"r"(state), "r"(c), + "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), + "i"(offsetof(CABACContext, bytestream)) : "%"REG_c, "%ebx", "%edx", "%esi", "memory" ); bit&=1; @@ -442,8 +435,8 @@ static int av_unused get_cabac_bypass(CABACContext *c){ static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){ #if ARCH_X86 && HAVE_EBX_AVAILABLE __asm__ volatile( - "movl "RANGE "(%1), %%ebx \n\t" - "movl "LOW "(%1), %%eax \n\t" + "movl %a2(%1), %%ebx \n\t" + "movl %a3(%1), %%eax \n\t" "shl $17, %%ebx \n\t" "add %%eax, %%eax \n\t" "sub %%ebx, %%eax \n\t" @@ -454,19 +447,21 @@ static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){ "sub %%edx, %%ecx \n\t" "test %%ax, %%ax \n\t" " jnz 1f \n\t" - "mov "BYTE "(%1), %%"REG_b" \n\t" + "mov %a4(%1), %%"REG_b" \n\t" "subl $0xFFFF, %%eax \n\t" "movzwl (%%"REG_b"), %%edx \n\t" "bswap %%edx \n\t" "shrl $15, %%edx \n\t" "add $2, %%"REG_b" \n\t" "addl %%edx, %%eax \n\t" - "mov %%"REG_b", "BYTE "(%1) \n\t" + "mov %%"REG_b", %a4(%1) \n\t" "1: \n\t" - "movl %%eax, "LOW "(%1) \n\t" + "movl %%eax, %a3(%1) \n\t" :"+c"(val) - :"r"(c) + :"r"(c), + "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), + "i"(offsetof(CABACContext, bytestream)) : "%eax", "%"REG_b, "%edx", "memory" ); return val; diff --git a/libavcodec/x86/h264_i386.h b/libavcodec/x86/h264_i386.h index e2dffe1e46..b6c225a2f1 100644 --- a/libavcodec/x86/h264_i386.h +++ b/libavcodec/x86/h264_i386.h @@ -29,6 +29,8 @@ #ifndef AVCODEC_X86_H264_I386_H #define AVCODEC_X86_H264_I386_H +#include + #include "libavcodec/cabac.h" //FIXME use some macros to avoid duplicating get_cabac (cannot be done yet @@ -42,20 +44,20 @@ static int decode_significance_x86(CABACContext *c, int max_coeff, int minusindex= 4-(int)index; int coeff_count; __asm__ volatile( - "movl "RANGE "(%3), %%esi \n\t" - "movl "LOW "(%3), %%ebx \n\t" + "movl %a8(%3), %%esi \n\t" + "movl %a9(%3), %%ebx \n\t" "2: \n\t" BRANCHLESS_GET_CABAC("%%edx", "%3", "(%1)", "%%ebx", - "%%bx", "%%esi", "%%eax", "%%al") + "%%bx", "%%esi", "%%eax", "%%al", "%a10") "test $1, %%edx \n\t" " jz 3f \n\t" "add %7, %1 \n\t" BRANCHLESS_GET_CABAC("%%edx", "%3", "(%1)", "%%ebx", - "%%bx", "%%esi", "%%eax", "%%al") + "%%bx", "%%esi", "%%eax", "%%al", "%a10") "sub %7, %1 \n\t" "mov %2, %%"REG_a" \n\t" @@ -81,10 +83,12 @@ static int decode_significance_x86(CABACContext *c, int max_coeff, "add %6, %%eax \n\t" "shr $2, %%eax \n\t" - "movl %%esi, "RANGE "(%3) \n\t" - "movl %%ebx, "LOW "(%3) \n\t" + "movl %%esi, %a8(%3) \n\t" + "movl %%ebx, %a9(%3) \n\t" :"=&a"(coeff_count), "+r"(significant_coeff_ctx_base), "+m"(index) - :"r"(c), "m"(minusstart), "m"(end), "m"(minusindex), "m"(last_off) + :"r"(c), "m"(minusstart), "m"(end), "m"(minusindex), "m"(last_off), + "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), + "i"(offsetof(CABACContext, bytestream)) : "%"REG_c, "%ebx", "%edx", "%esi", "memory" ); return coeff_count; @@ -97,8 +101,8 @@ static int decode_significance_8x8_x86(CABACContext *c, int coeff_count; x86_reg last=0; __asm__ volatile( - "movl "RANGE "(%3), %%esi \n\t" - "movl "LOW "(%3), %%ebx \n\t" + "movl %a8(%3), %%esi \n\t" + "movl %a9(%3), %%ebx \n\t" "mov %1, %%"REG_D" \n\t" "2: \n\t" @@ -108,7 +112,7 @@ static int decode_significance_8x8_x86(CABACContext *c, "add %5, %%"REG_D" \n\t" BRANCHLESS_GET_CABAC("%%edx", "%3", "(%%"REG_D")", "%%ebx", - "%%bx", "%%esi", "%%eax", "%%al") + "%%bx", "%%esi", "%%eax", "%%al", "%a10") "mov %1, %%edi \n\t" "test $1, %%edx \n\t" @@ -119,7 +123,7 @@ static int decode_significance_8x8_x86(CABACContext *c, "add %7, %%"REG_D" \n\t" BRANCHLESS_GET_CABAC("%%edx", "%3", "(%%"REG_D")", "%%ebx", - "%%bx", "%%esi", "%%eax", "%%al") + "%%bx", "%%esi", "%%eax", "%%al", "%a10") "mov %2, %%"REG_a" \n\t" "mov %1, %%edi \n\t" @@ -142,10 +146,12 @@ static int decode_significance_8x8_x86(CABACContext *c, "addl %4, %%eax \n\t" "shr $2, %%eax \n\t" - "movl %%esi, "RANGE "(%3) \n\t" - "movl %%ebx, "LOW "(%3) \n\t" + "movl %%esi, %a8(%3) \n\t" + "movl %%ebx, %a9(%3) \n\t" :"=&a"(coeff_count),"+m"(last), "+m"(index) - :"r"(c), "m"(minusindex), "m"(significant_coeff_ctx_base), "m"(sig_off), "m"(last_off) + :"r"(c), "m"(minusindex), "m"(significant_coeff_ctx_base), "m"(sig_off), "m"(last_off), + "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), + "i"(offsetof(CABACContext, bytestream)) : "%"REG_c, "%ebx", "%edx", "%esi", "%"REG_D, "memory" ); return coeff_count; From 018c33838eeb41944af46287e7d8be82c5c427d8 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Mon, 20 Jun 2011 02:31:53 +0100 Subject: [PATCH 093/109] x86: cabac: remove hardcoded ebx in inline asm Signed-off-by: Mans Rullgard --- libavcodec/cabac.h | 53 +++++++++++++++-------------- libavcodec/x86/h264_i386.h | 70 ++++++++++++++++++++------------------ 2 files changed, 63 insertions(+), 60 deletions(-) diff --git a/libavcodec/cabac.h b/libavcodec/cabac.h index 67a332eba8..b868f77f78 100644 --- a/libavcodec/cabac.h +++ b/libavcodec/cabac.h @@ -270,7 +270,7 @@ static void refill(CABACContext *c){ c->bytestream+= CABAC_BITS/8; } -#if ! ( ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) ) +#if ! ( ARCH_X86 && HAVE_7REGS && !defined(BROKEN_RELOCATIONS) ) static void refill2(CABACContext *c){ int i, x; @@ -309,8 +309,8 @@ static inline void renorm_cabac_decoder_once(CABACContext *c){ static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){ //FIXME gcc generates duplicate load/stores for c->low and c->range -#if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) - int bit; +#if ARCH_X86 && HAVE_7REGS && !defined(BROKEN_RELOCATIONS) + int bit, low; #if HAVE_FAST_CMOV #define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\ @@ -370,20 +370,20 @@ static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const st "1: \n\t" __asm__ volatile( - "movl %a3(%2), %%esi \n\t" - "movl %a4(%2), %%ebx \n\t" - BRANCHLESS_GET_CABAC("%0", "%2", "(%1)", "%%ebx", "%%bx", "%%esi", "%%edx", "%%dl", "%a5") - "movl %%esi, %a3(%2) \n\t" - "movl %%ebx, %a4(%2) \n\t" + "movl %a4(%3), %%esi \n\t" + "movl %a5(%3), %1 \n\t" + BRANCHLESS_GET_CABAC("%0", "%3", "(%2)", "%1", "%w1", "%%esi", "%%edx", "%%dl", "%a6") + "movl %%esi, %a4(%3) \n\t" + "movl %1, %a5(%3) \n\t" - :"=&a"(bit) + :"=&a"(bit), "=&r"(low) :"r"(state), "r"(c), "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), "i"(offsetof(CABACContext, bytestream)) - : "%"REG_c, "%ebx", "%edx", "%esi", "memory" + : "%"REG_c, "%edx", "%esi", "memory" ); bit&=1; -#else /* ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) */ +#else /* ARCH_X86 && HAVE_7REGS && !defined(BROKEN_RELOCATIONS) */ int s = *state; int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + s]; int bit, lps_mask; @@ -403,7 +403,7 @@ static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const st c->low <<= lps_mask; if(!(c->low & CABAC_MASK)) refill2(c); -#endif /* ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) */ +#endif /* ARCH_X86 && HAVE_7REGS && !defined(BROKEN_RELOCATIONS) */ return bit; } @@ -433,36 +433,37 @@ static int av_unused get_cabac_bypass(CABACContext *c){ static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){ -#if ARCH_X86 && HAVE_EBX_AVAILABLE +#if ARCH_X86 + x86_reg tmp; __asm__ volatile( - "movl %a2(%1), %%ebx \n\t" - "movl %a3(%1), %%eax \n\t" - "shl $17, %%ebx \n\t" + "movl %a3(%2), %k1 \n\t" + "movl %a4(%2), %%eax \n\t" + "shl $17, %k1 \n\t" "add %%eax, %%eax \n\t" - "sub %%ebx, %%eax \n\t" + "sub %k1, %%eax \n\t" "cltd \n\t" - "and %%edx, %%ebx \n\t" - "add %%ebx, %%eax \n\t" + "and %%edx, %k1 \n\t" + "add %k1, %%eax \n\t" "xor %%edx, %%ecx \n\t" "sub %%edx, %%ecx \n\t" "test %%ax, %%ax \n\t" " jnz 1f \n\t" - "mov %a4(%1), %%"REG_b" \n\t" + "mov %a5(%2), %1 \n\t" "subl $0xFFFF, %%eax \n\t" - "movzwl (%%"REG_b"), %%edx \n\t" + "movzwl (%1), %%edx \n\t" "bswap %%edx \n\t" "shrl $15, %%edx \n\t" - "add $2, %%"REG_b" \n\t" + "add $2, %1 \n\t" "addl %%edx, %%eax \n\t" - "mov %%"REG_b", %a4(%1) \n\t" + "mov %1, %a5(%2) \n\t" "1: \n\t" - "movl %%eax, %a3(%1) \n\t" + "movl %%eax, %a4(%2) \n\t" - :"+c"(val) + :"+c"(val), "=&r"(tmp) :"r"(c), "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), "i"(offsetof(CABACContext, bytestream)) - : "%eax", "%"REG_b, "%edx", "memory" + : "%eax", "%edx", "memory" ); return val; #else diff --git a/libavcodec/x86/h264_i386.h b/libavcodec/x86/h264_i386.h index b6c225a2f1..ba3a5ddfad 100644 --- a/libavcodec/x86/h264_i386.h +++ b/libavcodec/x86/h264_i386.h @@ -35,7 +35,7 @@ //FIXME use some macros to avoid duplicating get_cabac (cannot be done yet //as that would make optimization work hard) -#if ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE && !defined(BROKEN_RELOCATIONS) +#if ARCH_X86 && HAVE_7REGS && !defined(BROKEN_RELOCATIONS) static int decode_significance_x86(CABACContext *c, int max_coeff, uint8_t *significant_coeff_ctx_base, int *index, x86_reg last_off){ @@ -43,25 +43,26 @@ static int decode_significance_x86(CABACContext *c, int max_coeff, int minusstart= -(int)significant_coeff_ctx_base; int minusindex= 4-(int)index; int coeff_count; + int low; __asm__ volatile( - "movl %a8(%3), %%esi \n\t" - "movl %a9(%3), %%ebx \n\t" + "movl %a9(%4), %%esi \n\t" + "movl %a10(%4), %3 \n\t" "2: \n\t" - BRANCHLESS_GET_CABAC("%%edx", "%3", "(%1)", "%%ebx", - "%%bx", "%%esi", "%%eax", "%%al", "%a10") + BRANCHLESS_GET_CABAC("%%edx", "%4", "(%1)", "%3", + "%w3", "%%esi", "%%eax", "%%al", "%a11") "test $1, %%edx \n\t" " jz 3f \n\t" - "add %7, %1 \n\t" + "add %8, %1 \n\t" - BRANCHLESS_GET_CABAC("%%edx", "%3", "(%1)", "%%ebx", - "%%bx", "%%esi", "%%eax", "%%al", "%a10") + BRANCHLESS_GET_CABAC("%%edx", "%4", "(%1)", "%3", + "%w3", "%%esi", "%%eax", "%%al", "%a11") - "sub %7, %1 \n\t" + "sub %8, %1 \n\t" "mov %2, %%"REG_a" \n\t" - "movl %4, %%ecx \n\t" + "movl %5, %%ecx \n\t" "add %1, %%"REG_c" \n\t" "movl %%ecx, (%%"REG_a") \n\t" @@ -73,23 +74,24 @@ static int decode_significance_x86(CABACContext *c, int max_coeff, "3: \n\t" "add $1, %1 \n\t" - "cmp %5, %1 \n\t" + "cmp %6, %1 \n\t" " jb 2b \n\t" "mov %2, %%"REG_a" \n\t" - "movl %4, %%ecx \n\t" + "movl %5, %%ecx \n\t" "add %1, %%"REG_c" \n\t" "movl %%ecx, (%%"REG_a") \n\t" "4: \n\t" - "add %6, %%eax \n\t" + "add %7, %%eax \n\t" "shr $2, %%eax \n\t" - "movl %%esi, %a8(%3) \n\t" - "movl %%ebx, %a9(%3) \n\t" - :"=&a"(coeff_count), "+r"(significant_coeff_ctx_base), "+m"(index) + "movl %%esi, %a9(%4) \n\t" + "movl %3, %a10(%4) \n\t" + :"=&a"(coeff_count), "+r"(significant_coeff_ctx_base), "+m"(index), + "=&r"(low) :"r"(c), "m"(minusstart), "m"(end), "m"(minusindex), "m"(last_off), "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), "i"(offsetof(CABACContext, bytestream)) - : "%"REG_c, "%ebx", "%edx", "%esi", "memory" + : "%"REG_c, "%edx", "%esi", "memory" ); return coeff_count; } @@ -99,31 +101,32 @@ static int decode_significance_8x8_x86(CABACContext *c, int *index, x86_reg last_off, const uint8_t *sig_off){ int minusindex= 4-(int)index; int coeff_count; + int low; x86_reg last=0; __asm__ volatile( - "movl %a8(%3), %%esi \n\t" - "movl %a9(%3), %%ebx \n\t" + "movl %a9(%4), %%esi \n\t" + "movl %a10(%4), %3 \n\t" "mov %1, %%"REG_D" \n\t" "2: \n\t" - "mov %6, %%"REG_a" \n\t" + "mov %7, %%"REG_a" \n\t" "movzbl (%%"REG_a", %%"REG_D"), %%edi \n\t" - "add %5, %%"REG_D" \n\t" + "add %6, %%"REG_D" \n\t" - BRANCHLESS_GET_CABAC("%%edx", "%3", "(%%"REG_D")", "%%ebx", - "%%bx", "%%esi", "%%eax", "%%al", "%a10") + BRANCHLESS_GET_CABAC("%%edx", "%4", "(%%"REG_D")", "%3", + "%w3", "%%esi", "%%eax", "%%al", "%a11") "mov %1, %%edi \n\t" "test $1, %%edx \n\t" " jz 3f \n\t" "movzbl "MANGLE(last_coeff_flag_offset_8x8)"(%%edi), %%edi\n\t" - "add %5, %%"REG_D" \n\t" - "add %7, %%"REG_D" \n\t" + "add %6, %%"REG_D" \n\t" + "add %8, %%"REG_D" \n\t" - BRANCHLESS_GET_CABAC("%%edx", "%3", "(%%"REG_D")", "%%ebx", - "%%bx", "%%esi", "%%eax", "%%al", "%a10") + BRANCHLESS_GET_CABAC("%%edx", "%4", "(%%"REG_D")", "%3", + "%w3", "%%esi", "%%eax", "%%al", "%a11") "mov %2, %%"REG_a" \n\t" "mov %1, %%edi \n\t" @@ -143,20 +146,19 @@ static int decode_significance_8x8_x86(CABACContext *c, "mov %2, %%"REG_a" \n\t" "movl %%edi, (%%"REG_a") \n\t" "4: \n\t" - "addl %4, %%eax \n\t" + "addl %5, %%eax \n\t" "shr $2, %%eax \n\t" - "movl %%esi, %a8(%3) \n\t" - "movl %%ebx, %a9(%3) \n\t" - :"=&a"(coeff_count),"+m"(last), "+m"(index) + "movl %%esi, %a9(%4) \n\t" + "movl %3, %a10(%4) \n\t" + :"=&a"(coeff_count),"+m"(last), "+m"(index), "=&r"(low) :"r"(c), "m"(minusindex), "m"(significant_coeff_ctx_base), "m"(sig_off), "m"(last_off), "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), "i"(offsetof(CABACContext, bytestream)) - : "%"REG_c, "%ebx", "%edx", "%esi", "%"REG_D, "memory" + : "%"REG_c, "%edx", "%esi", "%"REG_D, "memory" ); return coeff_count; } -#endif /* ARCH_X86 && HAVE_7REGS && HAVE_EBX_AVAILABLE */ - /* !defined(BROKEN_RELOCATIONS) */ +#endif /* ARCH_X86 && HAVE_7REGS && !defined(BROKEN_RELOCATIONS) */ #endif /* AVCODEC_X86_H264_I386_H */ From 51f16a9bf22ee81116df2a02d3107c6f3ad17402 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Mon, 20 Jun 2011 03:19:20 +0100 Subject: [PATCH 094/109] x86: cabac: remove unused macro parameter Signed-off-by: Mans Rullgard --- libavcodec/cabac.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/cabac.h b/libavcodec/cabac.h index b868f77f78..c80c259614 100644 --- a/libavcodec/cabac.h +++ b/libavcodec/cabac.h @@ -313,7 +313,7 @@ static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const st int bit, low; #if HAVE_FAST_CMOV -#define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\ +#define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp)\ "mov "tmp" , %%ecx \n\t"\ "shl $17 , "tmp" \n\t"\ "cmp "low" , "tmp" \n\t"\ @@ -323,7 +323,7 @@ static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const st "sub "tmp" , "low" \n\t"\ "xor %%ecx , "ret" \n\t" #else /* HAVE_FAST_CMOV */ -#define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\ +#define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp)\ "mov "tmp" , %%ecx \n\t"\ "shl $17 , "tmp" \n\t"\ "sub "low" , "tmp" \n\t"\ @@ -344,7 +344,7 @@ static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const st "and $0xC0 , "range" \n\t"\ "movzbl "MANGLE(ff_h264_lps_range)"("ret", "range", 2), "range" \n\t"\ "sub "range" , "tmp" \n\t"\ - BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\ + BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp)\ "movzbl " MANGLE(ff_h264_norm_shift) "("range"), %%ecx \n\t"\ "shl %%cl , "range" \n\t"\ "movzbl "MANGLE(ff_h264_mlps_state)"+128("ret"), "tmp" \n\t"\ From da3af4db6151775a851c181c8aba802db07ce033 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Mon, 20 Jun 2011 03:39:45 +0100 Subject: [PATCH 095/109] x86: cabac: remove hardcoded edx in get_cabac_inline() Signed-off-by: Mans Rullgard --- libavcodec/cabac.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libavcodec/cabac.h b/libavcodec/cabac.h index c80c259614..f2b07d6886 100644 --- a/libavcodec/cabac.h +++ b/libavcodec/cabac.h @@ -310,7 +310,7 @@ static inline void renorm_cabac_decoder_once(CABACContext *c){ static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){ //FIXME gcc generates duplicate load/stores for c->low and c->range #if ARCH_X86 && HAVE_7REGS && !defined(BROKEN_RELOCATIONS) - int bit, low; + int bit, low, tmp; #if HAVE_FAST_CMOV #define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp)\ @@ -370,17 +370,17 @@ static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const st "1: \n\t" __asm__ volatile( - "movl %a4(%3), %%esi \n\t" - "movl %a5(%3), %1 \n\t" - BRANCHLESS_GET_CABAC("%0", "%3", "(%2)", "%1", "%w1", "%%esi", "%%edx", "%%dl", "%a6") - "movl %%esi, %a4(%3) \n\t" - "movl %1, %a5(%3) \n\t" + "movl %a5(%4), %%esi \n\t" + "movl %a6(%4), %1 \n\t" + BRANCHLESS_GET_CABAC("%0", "%4", "(%3)", "%1", "%w1", "%%esi", "%2", "%b2", "%a7") + "movl %%esi, %a5(%4) \n\t" + "movl %1, %a6(%4) \n\t" - :"=&a"(bit), "=&r"(low) + :"=&a"(bit), "=&r"(low), "=&r"(tmp) :"r"(state), "r"(c), "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), "i"(offsetof(CABACContext, bytestream)) - : "%"REG_c, "%edx", "%esi", "memory" + : "%"REG_c, "%esi", "memory" ); bit&=1; #else /* ARCH_X86 && HAVE_7REGS && !defined(BROKEN_RELOCATIONS) */ From f743595e87aecc090cf6884fc681c0adf3a03cbb Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Mon, 20 Jun 2011 09:19:27 +0100 Subject: [PATCH 096/109] x86: cabac: remove hardcoded esi in get_cabac_inline() Signed-off-by: Mans Rullgard --- libavcodec/cabac.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libavcodec/cabac.h b/libavcodec/cabac.h index f2b07d6886..b967da5ab6 100644 --- a/libavcodec/cabac.h +++ b/libavcodec/cabac.h @@ -310,7 +310,7 @@ static inline void renorm_cabac_decoder_once(CABACContext *c){ static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){ //FIXME gcc generates duplicate load/stores for c->low and c->range #if ARCH_X86 && HAVE_7REGS && !defined(BROKEN_RELOCATIONS) - int bit, low, tmp; + int bit, low, range, tmp; #if HAVE_FAST_CMOV #define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp)\ @@ -370,17 +370,17 @@ static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const st "1: \n\t" __asm__ volatile( - "movl %a5(%4), %%esi \n\t" - "movl %a6(%4), %1 \n\t" - BRANCHLESS_GET_CABAC("%0", "%4", "(%3)", "%1", "%w1", "%%esi", "%2", "%b2", "%a7") - "movl %%esi, %a5(%4) \n\t" - "movl %1, %a6(%4) \n\t" + "movl %a6(%5), %2 \n\t" + "movl %a7(%5), %1 \n\t" + BRANCHLESS_GET_CABAC("%0", "%5", "(%4)", "%1", "%w1", "%2", "%3", "%b3", "%a8") + "movl %2, %a6(%5) \n\t" + "movl %1, %a7(%5) \n\t" - :"=&a"(bit), "=&r"(low), "=&r"(tmp) + :"=&a"(bit), "=&r"(low), "=&r"(range), "=&r"(tmp) :"r"(state), "r"(c), "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), "i"(offsetof(CABACContext, bytestream)) - : "%"REG_c, "%esi", "memory" + : "%"REG_c, "memory" ); bit&=1; #else /* ARCH_X86 && HAVE_7REGS && !defined(BROKEN_RELOCATIONS) */ From 3146a30e612729e4a70dd10361c8a38750fa6d53 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Mon, 20 Jun 2011 09:28:19 +0100 Subject: [PATCH 097/109] x86: cabac: change 'a' constraint to 'r' in get_cabac_inline() Nothing requires this value in %eax. Signed-off-by: Mans Rullgard --- libavcodec/cabac.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/cabac.h b/libavcodec/cabac.h index b967da5ab6..adccf54aab 100644 --- a/libavcodec/cabac.h +++ b/libavcodec/cabac.h @@ -376,7 +376,7 @@ static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const st "movl %2, %a6(%5) \n\t" "movl %1, %a7(%5) \n\t" - :"=&a"(bit), "=&r"(low), "=&r"(range), "=&r"(tmp) + :"=&r"(bit), "=&r"(low), "=&r"(range), "=&r"(tmp) :"r"(state), "r"(c), "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), "i"(offsetof(CABACContext, bytestream)) From e4b5a204aa2269cc249771fd49a89e7b4af32215 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Mon, 20 Jun 2011 09:23:26 +0100 Subject: [PATCH 098/109] x86: h264: remove hardcoded eax in decode_significance[_8x8]_x86() Signed-off-by: Mans Rullgard --- libavcodec/x86/h264_i386.h | 52 +++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/libavcodec/x86/h264_i386.h b/libavcodec/x86/h264_i386.h index ba3a5ddfad..a0dd7ea783 100644 --- a/libavcodec/x86/h264_i386.h +++ b/libavcodec/x86/h264_i386.h @@ -42,7 +42,7 @@ static int decode_significance_x86(CABACContext *c, int max_coeff, void *end= significant_coeff_ctx_base + max_coeff - 1; int minusstart= -(int)significant_coeff_ctx_base; int minusindex= 4-(int)index; - int coeff_count; + x86_reg coeff_count; int low; __asm__ volatile( "movl %a9(%4), %%esi \n\t" @@ -51,42 +51,42 @@ static int decode_significance_x86(CABACContext *c, int max_coeff, "2: \n\t" BRANCHLESS_GET_CABAC("%%edx", "%4", "(%1)", "%3", - "%w3", "%%esi", "%%eax", "%%al", "%a11") + "%w3", "%%esi", "%k0", "%b0", "%a11") "test $1, %%edx \n\t" " jz 3f \n\t" "add %8, %1 \n\t" BRANCHLESS_GET_CABAC("%%edx", "%4", "(%1)", "%3", - "%w3", "%%esi", "%%eax", "%%al", "%a11") + "%w3", "%%esi", "%k0", "%b0", "%a11") "sub %8, %1 \n\t" - "mov %2, %%"REG_a" \n\t" + "mov %2, %0 \n\t" "movl %5, %%ecx \n\t" "add %1, %%"REG_c" \n\t" - "movl %%ecx, (%%"REG_a") \n\t" + "movl %%ecx, (%0) \n\t" "test $1, %%edx \n\t" " jnz 4f \n\t" - "add $4, %%"REG_a" \n\t" - "mov %%"REG_a", %2 \n\t" + "add $4, %0 \n\t" + "mov %0, %2 \n\t" "3: \n\t" "add $1, %1 \n\t" "cmp %6, %1 \n\t" " jb 2b \n\t" - "mov %2, %%"REG_a" \n\t" + "mov %2, %0 \n\t" "movl %5, %%ecx \n\t" "add %1, %%"REG_c" \n\t" - "movl %%ecx, (%%"REG_a") \n\t" + "movl %%ecx, (%0) \n\t" "4: \n\t" - "add %7, %%eax \n\t" - "shr $2, %%eax \n\t" + "add %7, %k0 \n\t" + "shr $2, %k0 \n\t" "movl %%esi, %a9(%4) \n\t" "movl %3, %a10(%4) \n\t" - :"=&a"(coeff_count), "+r"(significant_coeff_ctx_base), "+m"(index), + :"=&r"(coeff_count), "+r"(significant_coeff_ctx_base), "+m"(index), "=&r"(low) :"r"(c), "m"(minusstart), "m"(end), "m"(minusindex), "m"(last_off), "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), @@ -100,7 +100,7 @@ static int decode_significance_8x8_x86(CABACContext *c, uint8_t *significant_coeff_ctx_base, int *index, x86_reg last_off, const uint8_t *sig_off){ int minusindex= 4-(int)index; - int coeff_count; + x86_reg coeff_count; int low; x86_reg last=0; __asm__ volatile( @@ -110,12 +110,12 @@ static int decode_significance_8x8_x86(CABACContext *c, "mov %1, %%"REG_D" \n\t" "2: \n\t" - "mov %7, %%"REG_a" \n\t" - "movzbl (%%"REG_a", %%"REG_D"), %%edi \n\t" + "mov %7, %0 \n\t" + "movzbl (%0, %%"REG_D"), %%edi \n\t" "add %6, %%"REG_D" \n\t" BRANCHLESS_GET_CABAC("%%edx", "%4", "(%%"REG_D")", "%3", - "%w3", "%%esi", "%%eax", "%%al", "%a11") + "%w3", "%%esi", "%k0", "%b0", "%a11") "mov %1, %%edi \n\t" "test $1, %%edx \n\t" @@ -126,32 +126,32 @@ static int decode_significance_8x8_x86(CABACContext *c, "add %8, %%"REG_D" \n\t" BRANCHLESS_GET_CABAC("%%edx", "%4", "(%%"REG_D")", "%3", - "%w3", "%%esi", "%%eax", "%%al", "%a11") + "%w3", "%%esi", "%k0", "%b0", "%a11") - "mov %2, %%"REG_a" \n\t" + "mov %2, %0 \n\t" "mov %1, %%edi \n\t" - "movl %%edi, (%%"REG_a") \n\t" + "movl %%edi, (%0) \n\t" "test $1, %%edx \n\t" " jnz 4f \n\t" - "add $4, %%"REG_a" \n\t" - "mov %%"REG_a", %2 \n\t" + "add $4, %0 \n\t" + "mov %0, %2 \n\t" "3: \n\t" "addl $1, %%edi \n\t" "mov %%edi, %1 \n\t" "cmpl $63, %%edi \n\t" " jb 2b \n\t" - "mov %2, %%"REG_a" \n\t" - "movl %%edi, (%%"REG_a") \n\t" + "mov %2, %0 \n\t" + "movl %%edi, (%0) \n\t" "4: \n\t" - "addl %5, %%eax \n\t" - "shr $2, %%eax \n\t" + "addl %5, %k0 \n\t" + "shr $2, %k0 \n\t" "movl %%esi, %a9(%4) \n\t" "movl %3, %a10(%4) \n\t" - :"=&a"(coeff_count),"+m"(last), "+m"(index), "=&r"(low) + :"=&r"(coeff_count),"+m"(last), "+m"(index), "=&r"(low) :"r"(c), "m"(minusindex), "m"(significant_coeff_ctx_base), "m"(sig_off), "m"(last_off), "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), "i"(offsetof(CABACContext, bytestream)) From 3fc4e36c78004b37b6179423231e3e0daa3c7e74 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Mon, 20 Jun 2011 10:06:07 +0100 Subject: [PATCH 099/109] x86: h264: remove hardcoded edx in decode_significance[_8x8]_x86() Signed-off-by: Mans Rullgard --- libavcodec/x86/h264_i386.h | 72 ++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/libavcodec/x86/h264_i386.h b/libavcodec/x86/h264_i386.h index a0dd7ea783..b303347c0f 100644 --- a/libavcodec/x86/h264_i386.h +++ b/libavcodec/x86/h264_i386.h @@ -42,31 +42,32 @@ static int decode_significance_x86(CABACContext *c, int max_coeff, void *end= significant_coeff_ctx_base + max_coeff - 1; int minusstart= -(int)significant_coeff_ctx_base; int minusindex= 4-(int)index; + int bit; x86_reg coeff_count; int low; __asm__ volatile( - "movl %a9(%4), %%esi \n\t" - "movl %a10(%4), %3 \n\t" + "movl %a10(%5), %%esi \n\t" + "movl %a11(%5), %3 \n\t" "2: \n\t" - BRANCHLESS_GET_CABAC("%%edx", "%4", "(%1)", "%3", - "%w3", "%%esi", "%k0", "%b0", "%a11") + BRANCHLESS_GET_CABAC("%4", "%5", "(%1)", "%3", + "%w3", "%%esi", "%k0", "%b0", "%a12") - "test $1, %%edx \n\t" + "test $1, %4 \n\t" " jz 3f \n\t" - "add %8, %1 \n\t" + "add %9, %1 \n\t" - BRANCHLESS_GET_CABAC("%%edx", "%4", "(%1)", "%3", - "%w3", "%%esi", "%k0", "%b0", "%a11") + BRANCHLESS_GET_CABAC("%4", "%5", "(%1)", "%3", + "%w3", "%%esi", "%k0", "%b0", "%a12") - "sub %8, %1 \n\t" + "sub %9, %1 \n\t" "mov %2, %0 \n\t" - "movl %5, %%ecx \n\t" + "movl %6, %%ecx \n\t" "add %1, %%"REG_c" \n\t" "movl %%ecx, (%0) \n\t" - "test $1, %%edx \n\t" + "test $1, %4 \n\t" " jnz 4f \n\t" "add $4, %0 \n\t" @@ -74,24 +75,24 @@ static int decode_significance_x86(CABACContext *c, int max_coeff, "3: \n\t" "add $1, %1 \n\t" - "cmp %6, %1 \n\t" + "cmp %7, %1 \n\t" " jb 2b \n\t" "mov %2, %0 \n\t" - "movl %5, %%ecx \n\t" + "movl %6, %%ecx \n\t" "add %1, %%"REG_c" \n\t" "movl %%ecx, (%0) \n\t" "4: \n\t" - "add %7, %k0 \n\t" + "add %8, %k0 \n\t" "shr $2, %k0 \n\t" - "movl %%esi, %a9(%4) \n\t" - "movl %3, %a10(%4) \n\t" + "movl %%esi, %a10(%5) \n\t" + "movl %3, %a11(%5) \n\t" :"=&r"(coeff_count), "+r"(significant_coeff_ctx_base), "+m"(index), - "=&r"(low) + "=&r"(low), "=&r"(bit) :"r"(c), "m"(minusstart), "m"(end), "m"(minusindex), "m"(last_off), "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), "i"(offsetof(CABACContext, bytestream)) - : "%"REG_c, "%edx", "%esi", "memory" + : "%"REG_c, "%esi", "memory" ); return coeff_count; } @@ -100,39 +101,40 @@ static int decode_significance_8x8_x86(CABACContext *c, uint8_t *significant_coeff_ctx_base, int *index, x86_reg last_off, const uint8_t *sig_off){ int minusindex= 4-(int)index; + int bit; x86_reg coeff_count; int low; x86_reg last=0; __asm__ volatile( - "movl %a9(%4), %%esi \n\t" - "movl %a10(%4), %3 \n\t" + "movl %a10(%5), %%esi \n\t" + "movl %a11(%5), %3 \n\t" "mov %1, %%"REG_D" \n\t" "2: \n\t" - "mov %7, %0 \n\t" + "mov %8, %0 \n\t" "movzbl (%0, %%"REG_D"), %%edi \n\t" - "add %6, %%"REG_D" \n\t" + "add %7, %%"REG_D" \n\t" - BRANCHLESS_GET_CABAC("%%edx", "%4", "(%%"REG_D")", "%3", - "%w3", "%%esi", "%k0", "%b0", "%a11") + BRANCHLESS_GET_CABAC("%4", "%5", "(%%"REG_D")", "%3", + "%w3", "%%esi", "%k0", "%b0", "%a12") "mov %1, %%edi \n\t" - "test $1, %%edx \n\t" + "test $1, %4 \n\t" " jz 3f \n\t" "movzbl "MANGLE(last_coeff_flag_offset_8x8)"(%%edi), %%edi\n\t" - "add %6, %%"REG_D" \n\t" - "add %8, %%"REG_D" \n\t" + "add %7, %%"REG_D" \n\t" + "add %9, %%"REG_D" \n\t" - BRANCHLESS_GET_CABAC("%%edx", "%4", "(%%"REG_D")", "%3", - "%w3", "%%esi", "%k0", "%b0", "%a11") + BRANCHLESS_GET_CABAC("%4", "%5", "(%%"REG_D")", "%3", + "%w3", "%%esi", "%k0", "%b0", "%a12") "mov %2, %0 \n\t" "mov %1, %%edi \n\t" "movl %%edi, (%0) \n\t" - "test $1, %%edx \n\t" + "test $1, %4 \n\t" " jnz 4f \n\t" "add $4, %0 \n\t" @@ -146,16 +148,16 @@ static int decode_significance_8x8_x86(CABACContext *c, "mov %2, %0 \n\t" "movl %%edi, (%0) \n\t" "4: \n\t" - "addl %5, %k0 \n\t" + "addl %6, %k0 \n\t" "shr $2, %k0 \n\t" - "movl %%esi, %a9(%4) \n\t" - "movl %3, %a10(%4) \n\t" - :"=&r"(coeff_count),"+m"(last), "+m"(index), "=&r"(low) + "movl %%esi, %a10(%5) \n\t" + "movl %3, %a11(%5) \n\t" + :"=&r"(coeff_count),"+m"(last), "+m"(index), "=&r"(low), "=&r"(bit) :"r"(c), "m"(minusindex), "m"(significant_coeff_ctx_base), "m"(sig_off), "m"(last_off), "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), "i"(offsetof(CABACContext, bytestream)) - : "%"REG_c, "%edx", "%esi", "%"REG_D, "memory" + : "%"REG_c, "%esi", "%"REG_D, "memory" ); return coeff_count; } From b92c1a6d2630e46b6e7c6ceca467e7f56fae5218 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Mon, 20 Jun 2011 10:12:29 +0100 Subject: [PATCH 100/109] x86: h264: remove hardcoded esi in decode_significance[_8x8]_x86() Signed-off-by: Mans Rullgard --- libavcodec/x86/h264_i386.h | 65 ++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 31 deletions(-) diff --git a/libavcodec/x86/h264_i386.h b/libavcodec/x86/h264_i386.h index b303347c0f..d38b18e5e5 100644 --- a/libavcodec/x86/h264_i386.h +++ b/libavcodec/x86/h264_i386.h @@ -45,25 +45,26 @@ static int decode_significance_x86(CABACContext *c, int max_coeff, int bit; x86_reg coeff_count; int low; + int range; __asm__ volatile( - "movl %a10(%5), %%esi \n\t" - "movl %a11(%5), %3 \n\t" + "movl %a11(%6), %5 \n\t" + "movl %a12(%6), %3 \n\t" "2: \n\t" - BRANCHLESS_GET_CABAC("%4", "%5", "(%1)", "%3", - "%w3", "%%esi", "%k0", "%b0", "%a12") + BRANCHLESS_GET_CABAC("%4", "%6", "(%1)", "%3", + "%w3", "%5", "%k0", "%b0", "%a13") "test $1, %4 \n\t" " jz 3f \n\t" - "add %9, %1 \n\t" + "add %10, %1 \n\t" - BRANCHLESS_GET_CABAC("%4", "%5", "(%1)", "%3", - "%w3", "%%esi", "%k0", "%b0", "%a12") + BRANCHLESS_GET_CABAC("%4", "%6", "(%1)", "%3", + "%w3", "%5", "%k0", "%b0", "%a13") - "sub %9, %1 \n\t" + "sub %10, %1 \n\t" "mov %2, %0 \n\t" - "movl %6, %%ecx \n\t" + "movl %7, %%ecx \n\t" "add %1, %%"REG_c" \n\t" "movl %%ecx, (%0) \n\t" @@ -75,24 +76,24 @@ static int decode_significance_x86(CABACContext *c, int max_coeff, "3: \n\t" "add $1, %1 \n\t" - "cmp %7, %1 \n\t" + "cmp %8, %1 \n\t" " jb 2b \n\t" "mov %2, %0 \n\t" - "movl %6, %%ecx \n\t" + "movl %7, %%ecx \n\t" "add %1, %%"REG_c" \n\t" "movl %%ecx, (%0) \n\t" "4: \n\t" - "add %8, %k0 \n\t" + "add %9, %k0 \n\t" "shr $2, %k0 \n\t" - "movl %%esi, %a10(%5) \n\t" - "movl %3, %a11(%5) \n\t" + "movl %5, %a11(%6) \n\t" + "movl %3, %a12(%6) \n\t" :"=&r"(coeff_count), "+r"(significant_coeff_ctx_base), "+m"(index), - "=&r"(low), "=&r"(bit) + "=&r"(low), "=&r"(bit), "=&r"(range) :"r"(c), "m"(minusstart), "m"(end), "m"(minusindex), "m"(last_off), "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), "i"(offsetof(CABACContext, bytestream)) - : "%"REG_c, "%esi", "memory" + : "%"REG_c, "memory" ); return coeff_count; } @@ -104,31 +105,32 @@ static int decode_significance_8x8_x86(CABACContext *c, int bit; x86_reg coeff_count; int low; + int range; x86_reg last=0; __asm__ volatile( - "movl %a10(%5), %%esi \n\t" - "movl %a11(%5), %3 \n\t" + "movl %a11(%6), %5 \n\t" + "movl %a12(%6), %3 \n\t" "mov %1, %%"REG_D" \n\t" "2: \n\t" - "mov %8, %0 \n\t" + "mov %9, %0 \n\t" "movzbl (%0, %%"REG_D"), %%edi \n\t" - "add %7, %%"REG_D" \n\t" + "add %8, %%"REG_D" \n\t" - BRANCHLESS_GET_CABAC("%4", "%5", "(%%"REG_D")", "%3", - "%w3", "%%esi", "%k0", "%b0", "%a12") + BRANCHLESS_GET_CABAC("%4", "%6", "(%%"REG_D")", "%3", + "%w3", "%5", "%k0", "%b0", "%a13") "mov %1, %%edi \n\t" "test $1, %4 \n\t" " jz 3f \n\t" "movzbl "MANGLE(last_coeff_flag_offset_8x8)"(%%edi), %%edi\n\t" - "add %7, %%"REG_D" \n\t" - "add %9, %%"REG_D" \n\t" + "add %8, %%"REG_D" \n\t" + "add %10, %%"REG_D" \n\t" - BRANCHLESS_GET_CABAC("%4", "%5", "(%%"REG_D")", "%3", - "%w3", "%%esi", "%k0", "%b0", "%a12") + BRANCHLESS_GET_CABAC("%4", "%6", "(%%"REG_D")", "%3", + "%w3", "%5", "%k0", "%b0", "%a13") "mov %2, %0 \n\t" "mov %1, %%edi \n\t" @@ -148,16 +150,17 @@ static int decode_significance_8x8_x86(CABACContext *c, "mov %2, %0 \n\t" "movl %%edi, (%0) \n\t" "4: \n\t" - "addl %6, %k0 \n\t" + "addl %7, %k0 \n\t" "shr $2, %k0 \n\t" - "movl %%esi, %a10(%5) \n\t" - "movl %3, %a11(%5) \n\t" - :"=&r"(coeff_count),"+m"(last), "+m"(index), "=&r"(low), "=&r"(bit) + "movl %5, %a11(%6) \n\t" + "movl %3, %a12(%6) \n\t" + :"=&r"(coeff_count),"+m"(last), "+m"(index), "=&r"(low), "=&r"(bit), + "=&r"(range) :"r"(c), "m"(minusindex), "m"(significant_coeff_ctx_base), "m"(sig_off), "m"(last_off), "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), "i"(offsetof(CABACContext, bytestream)) - : "%"REG_c, "%esi", "%"REG_D, "memory" + : "%"REG_c, "%"REG_D, "memory" ); return coeff_count; } From 3a4edb76d697cfa341ee060647732e5c1400da3a Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Mon, 20 Jun 2011 10:20:15 +0100 Subject: [PATCH 101/109] x86: h264: remove hardcoded edi in decode_significance_8x8_x86() Signed-off-by: Mans Rullgard --- libavcodec/x86/h264_i386.h | 51 +++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 25 deletions(-) diff --git a/libavcodec/x86/h264_i386.h b/libavcodec/x86/h264_i386.h index d38b18e5e5..1b55dd830f 100644 --- a/libavcodec/x86/h264_i386.h +++ b/libavcodec/x86/h264_i386.h @@ -107,34 +107,35 @@ static int decode_significance_8x8_x86(CABACContext *c, int low; int range; x86_reg last=0; + x86_reg state; __asm__ volatile( - "movl %a11(%6), %5 \n\t" - "movl %a12(%6), %3 \n\t" + "movl %a12(%7), %5 \n\t" + "movl %a13(%7), %3 \n\t" - "mov %1, %%"REG_D" \n\t" + "mov %1, %6 \n\t" "2: \n\t" - "mov %9, %0 \n\t" - "movzbl (%0, %%"REG_D"), %%edi \n\t" - "add %8, %%"REG_D" \n\t" + "mov %10, %0 \n\t" + "movzbl (%0, %6), %k6 \n\t" + "add %9, %6 \n\t" - BRANCHLESS_GET_CABAC("%4", "%6", "(%%"REG_D")", "%3", - "%w3", "%5", "%k0", "%b0", "%a13") + BRANCHLESS_GET_CABAC("%4", "%7", "(%6)", "%3", + "%w3", "%5", "%k0", "%b0", "%a14") - "mov %1, %%edi \n\t" + "mov %1, %k6 \n\t" "test $1, %4 \n\t" " jz 3f \n\t" - "movzbl "MANGLE(last_coeff_flag_offset_8x8)"(%%edi), %%edi\n\t" - "add %8, %%"REG_D" \n\t" - "add %10, %%"REG_D" \n\t" + "movzbl "MANGLE(last_coeff_flag_offset_8x8)"(%k6), %k6\n\t" + "add %9, %6 \n\t" + "add %11, %6 \n\t" - BRANCHLESS_GET_CABAC("%4", "%6", "(%%"REG_D")", "%3", - "%w3", "%5", "%k0", "%b0", "%a13") + BRANCHLESS_GET_CABAC("%4", "%7", "(%6)", "%3", + "%w3", "%5", "%k0", "%b0", "%a14") "mov %2, %0 \n\t" - "mov %1, %%edi \n\t" - "movl %%edi, (%0) \n\t" + "mov %1, %k6 \n\t" + "movl %k6, (%0) \n\t" "test $1, %4 \n\t" " jnz 4f \n\t" @@ -143,24 +144,24 @@ static int decode_significance_8x8_x86(CABACContext *c, "mov %0, %2 \n\t" "3: \n\t" - "addl $1, %%edi \n\t" - "mov %%edi, %1 \n\t" - "cmpl $63, %%edi \n\t" + "addl $1, %k6 \n\t" + "mov %k6, %1 \n\t" + "cmpl $63, %k6 \n\t" " jb 2b \n\t" "mov %2, %0 \n\t" - "movl %%edi, (%0) \n\t" + "movl %k6, (%0) \n\t" "4: \n\t" - "addl %7, %k0 \n\t" + "addl %8, %k0 \n\t" "shr $2, %k0 \n\t" - "movl %5, %a11(%6) \n\t" - "movl %3, %a12(%6) \n\t" + "movl %5, %a12(%7) \n\t" + "movl %3, %a13(%7) \n\t" :"=&r"(coeff_count),"+m"(last), "+m"(index), "=&r"(low), "=&r"(bit), - "=&r"(range) + "=&r"(range), "=&r"(state) :"r"(c), "m"(minusindex), "m"(significant_coeff_ctx_base), "m"(sig_off), "m"(last_off), "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), "i"(offsetof(CABACContext, bytestream)) - : "%"REG_c, "%"REG_D, "memory" + : "%"REG_c, "memory" ); return coeff_count; } From d075e7d5405d716170476a2fea707dfe3330093c Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Mon, 20 Jun 2011 10:24:26 +0100 Subject: [PATCH 102/109] x86: h264: cast pointers to intptr_t rather than int Only the low-order bits are used here so the type is not important, but this avoids a compiler warning. Signed-off-by: Mans Rullgard --- libavcodec/x86/h264_i386.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/x86/h264_i386.h b/libavcodec/x86/h264_i386.h index 1b55dd830f..9f5e53105e 100644 --- a/libavcodec/x86/h264_i386.h +++ b/libavcodec/x86/h264_i386.h @@ -40,8 +40,8 @@ static int decode_significance_x86(CABACContext *c, int max_coeff, uint8_t *significant_coeff_ctx_base, int *index, x86_reg last_off){ void *end= significant_coeff_ctx_base + max_coeff - 1; - int minusstart= -(int)significant_coeff_ctx_base; - int minusindex= 4-(int)index; + int minusstart= -(intptr_t)significant_coeff_ctx_base; + int minusindex= 4-(intptr_t)index; int bit; x86_reg coeff_count; int low; @@ -101,7 +101,7 @@ static int decode_significance_x86(CABACContext *c, int max_coeff, static int decode_significance_8x8_x86(CABACContext *c, uint8_t *significant_coeff_ctx_base, int *index, x86_reg last_off, const uint8_t *sig_off){ - int minusindex= 4-(int)index; + int minusindex= 4-(intptr_t)index; int bit; x86_reg coeff_count; int low; From 2143d69bddf42c8c2cf9f45e1f0ce7750e96aad3 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Mon, 20 Jun 2011 10:53:41 +0100 Subject: [PATCH 103/109] cabac: move x86 asm to libavcodec/x86/cabac.h Signed-off-by: Mans Rullgard --- libavcodec/cabac.h | 158 ++++++------------------------------- libavcodec/x86/cabac.h | 148 ++++++++++++++++++++++++++++++++++ libavcodec/x86/h264_i386.h | 1 + 3 files changed, 174 insertions(+), 133 deletions(-) create mode 100644 libavcodec/x86/cabac.h diff --git a/libavcodec/cabac.h b/libavcodec/cabac.h index adccf54aab..57d1d70d29 100644 --- a/libavcodec/cabac.h +++ b/libavcodec/cabac.h @@ -33,7 +33,6 @@ //#undef NDEBUG #include -#include "libavutil/x86_cpu.h" #define CABAC_BITS 16 #define CABAC_MASK ((1<bytestream+= CABAC_BITS/8; } -#if ! ( ARCH_X86 && HAVE_7REGS && !defined(BROKEN_RELOCATIONS) ) -static void refill2(CABACContext *c){ - int i, x; - - x= c->low ^ (c->low-1); - i= 7 - ff_h264_norm_shift[x>>(CABAC_BITS-1)]; - - x= -CABAC_MASK; - -#if CABAC_BITS == 16 - x+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); -#else - x+= c->bytestream[0]<<1; -#endif - - c->low += x<bytestream+= CABAC_BITS/8; -} -#endif - static inline void renorm_cabac_decoder(CABACContext *c){ while(c->range < 0x100){ c->range+= c->range; @@ -307,83 +289,26 @@ static inline void renorm_cabac_decoder_once(CABACContext *c){ refill(c); } +#ifndef get_cabac_inline +static void refill2(CABACContext *c){ + int i, x; + + x= c->low ^ (c->low-1); + i= 7 - ff_h264_norm_shift[x>>(CABAC_BITS-1)]; + + x= -CABAC_MASK; + +#if CABAC_BITS == 16 + x+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1); +#else + x+= c->bytestream[0]<<1; +#endif + + c->low += x<bytestream+= CABAC_BITS/8; +} + static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){ - //FIXME gcc generates duplicate load/stores for c->low and c->range -#if ARCH_X86 && HAVE_7REGS && !defined(BROKEN_RELOCATIONS) - int bit, low, range, tmp; - -#if HAVE_FAST_CMOV -#define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp)\ - "mov "tmp" , %%ecx \n\t"\ - "shl $17 , "tmp" \n\t"\ - "cmp "low" , "tmp" \n\t"\ - "cmova %%ecx , "range" \n\t"\ - "sbb %%ecx , %%ecx \n\t"\ - "and %%ecx , "tmp" \n\t"\ - "sub "tmp" , "low" \n\t"\ - "xor %%ecx , "ret" \n\t" -#else /* HAVE_FAST_CMOV */ -#define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp)\ - "mov "tmp" , %%ecx \n\t"\ - "shl $17 , "tmp" \n\t"\ - "sub "low" , "tmp" \n\t"\ - "sar $31 , "tmp" \n\t" /*lps_mask*/\ - "sub %%ecx , "range" \n\t" /*RangeLPS - range*/\ - "and "tmp" , "range" \n\t" /*(RangeLPS - range)&lps_mask*/\ - "add %%ecx , "range" \n\t" /*new range*/\ - "shl $17 , %%ecx \n\t"\ - "and "tmp" , %%ecx \n\t"\ - "sub %%ecx , "low" \n\t"\ - "xor "tmp" , "ret" \n\t" -#endif /* HAVE_FAST_CMOV */ - - -#define BRANCHLESS_GET_CABAC(ret, cabac, statep, low, lowword, range, tmp, tmpbyte, byte) \ - "movzbl "statep" , "ret" \n\t"\ - "mov "range" , "tmp" \n\t"\ - "and $0xC0 , "range" \n\t"\ - "movzbl "MANGLE(ff_h264_lps_range)"("ret", "range", 2), "range" \n\t"\ - "sub "range" , "tmp" \n\t"\ - BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp)\ - "movzbl " MANGLE(ff_h264_norm_shift) "("range"), %%ecx \n\t"\ - "shl %%cl , "range" \n\t"\ - "movzbl "MANGLE(ff_h264_mlps_state)"+128("ret"), "tmp" \n\t"\ - "mov "tmpbyte" , "statep" \n\t"\ - "shl %%cl , "low" \n\t"\ - "test "lowword" , "lowword" \n\t"\ - " jnz 1f \n\t"\ - "mov "byte"("cabac"), %%"REG_c" \n\t"\ - "movzwl (%%"REG_c") , "tmp" \n\t"\ - "bswap "tmp" \n\t"\ - "shr $15 , "tmp" \n\t"\ - "sub $0xFFFF , "tmp" \n\t"\ - "add $2 , %%"REG_c" \n\t"\ - "mov %%"REG_c" , "byte "("cabac") \n\t"\ - "lea -1("low") , %%ecx \n\t"\ - "xor "low" , %%ecx \n\t"\ - "shr $15 , %%ecx \n\t"\ - "movzbl " MANGLE(ff_h264_norm_shift) "(%%ecx), %%ecx \n\t"\ - "neg %%ecx \n\t"\ - "add $7 , %%ecx \n\t"\ - "shl %%cl , "tmp" \n\t"\ - "add "tmp" , "low" \n\t"\ - "1: \n\t" - - __asm__ volatile( - "movl %a6(%5), %2 \n\t" - "movl %a7(%5), %1 \n\t" - BRANCHLESS_GET_CABAC("%0", "%5", "(%4)", "%1", "%w1", "%2", "%3", "%b3", "%a8") - "movl %2, %a6(%5) \n\t" - "movl %1, %a7(%5) \n\t" - - :"=&r"(bit), "=&r"(low), "=&r"(range), "=&r"(tmp) - :"r"(state), "r"(c), - "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), - "i"(offsetof(CABACContext, bytestream)) - : "%"REG_c, "memory" - ); - bit&=1; -#else /* ARCH_X86 && HAVE_7REGS && !defined(BROKEN_RELOCATIONS) */ int s = *state; int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + s]; int bit, lps_mask; @@ -403,9 +328,9 @@ static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const st c->low <<= lps_mask; if(!(c->low & CABAC_MASK)) refill2(c); -#endif /* ARCH_X86 && HAVE_7REGS && !defined(BROKEN_RELOCATIONS) */ return bit; } +#endif static int av_noinline av_unused get_cabac_noinline(CABACContext *c, uint8_t * const state){ return get_cabac_inline(c,state); @@ -432,41 +357,8 @@ static int av_unused get_cabac_bypass(CABACContext *c){ } +#ifndef get_cabac_bypass_sign static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){ -#if ARCH_X86 - x86_reg tmp; - __asm__ volatile( - "movl %a3(%2), %k1 \n\t" - "movl %a4(%2), %%eax \n\t" - "shl $17, %k1 \n\t" - "add %%eax, %%eax \n\t" - "sub %k1, %%eax \n\t" - "cltd \n\t" - "and %%edx, %k1 \n\t" - "add %k1, %%eax \n\t" - "xor %%edx, %%ecx \n\t" - "sub %%edx, %%ecx \n\t" - "test %%ax, %%ax \n\t" - " jnz 1f \n\t" - "mov %a5(%2), %1 \n\t" - "subl $0xFFFF, %%eax \n\t" - "movzwl (%1), %%edx \n\t" - "bswap %%edx \n\t" - "shrl $15, %%edx \n\t" - "add $2, %1 \n\t" - "addl %%edx, %%eax \n\t" - "mov %1, %a5(%2) \n\t" - "1: \n\t" - "movl %%eax, %a4(%2) \n\t" - - :"+c"(val), "=&r"(tmp) - :"r"(c), - "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), - "i"(offsetof(CABACContext, bytestream)) - : "%eax", "%edx", "memory" - ); - return val; -#else int range, mask; c->low += c->low; @@ -479,8 +371,8 @@ static av_always_inline int get_cabac_bypass_sign(CABACContext *c, int val){ range &= mask; c->low += range; return (val^mask)-mask; -#endif } +#endif /** * diff --git a/libavcodec/x86/cabac.h b/libavcodec/x86/cabac.h new file mode 100644 index 0000000000..3e5a2217ae --- /dev/null +++ b/libavcodec/x86/cabac.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2003 Michael Niedermayer + * + * This file is part of Libav. + * + * Libav 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. + * + * Libav 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 Libav; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_X86_CABAC_H +#define AVCODEC_X86_CABAC_H + +#include "libavcodec/cabac.h" +#include "libavutil/attributes.h" +#include "libavutil/x86_cpu.h" +#include "config.h" + +#if HAVE_FAST_CMOV +#define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp)\ + "mov "tmp" , %%ecx \n\t"\ + "shl $17 , "tmp" \n\t"\ + "cmp "low" , "tmp" \n\t"\ + "cmova %%ecx , "range" \n\t"\ + "sbb %%ecx , %%ecx \n\t"\ + "and %%ecx , "tmp" \n\t"\ + "sub "tmp" , "low" \n\t"\ + "xor %%ecx , "ret" \n\t" +#else /* HAVE_FAST_CMOV */ +#define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp)\ + "mov "tmp" , %%ecx \n\t"\ + "shl $17 , "tmp" \n\t"\ + "sub "low" , "tmp" \n\t"\ + "sar $31 , "tmp" \n\t" /*lps_mask*/\ + "sub %%ecx , "range" \n\t" /*RangeLPS - range*/\ + "and "tmp" , "range" \n\t" /*(RangeLPS - range)&lps_mask*/\ + "add %%ecx , "range" \n\t" /*new range*/\ + "shl $17 , %%ecx \n\t"\ + "and "tmp" , %%ecx \n\t"\ + "sub %%ecx , "low" \n\t"\ + "xor "tmp" , "ret" \n\t" +#endif /* HAVE_FAST_CMOV */ + +#define BRANCHLESS_GET_CABAC(ret, cabac, statep, low, lowword, range, tmp, tmpbyte, byte) \ + "movzbl "statep" , "ret" \n\t"\ + "mov "range" , "tmp" \n\t"\ + "and $0xC0 , "range" \n\t"\ + "movzbl "MANGLE(ff_h264_lps_range)"("ret", "range", 2), "range" \n\t"\ + "sub "range" , "tmp" \n\t"\ + BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, \ + range, tmp) \ + "movzbl " MANGLE(ff_h264_norm_shift) "("range"), %%ecx \n\t"\ + "shl %%cl , "range" \n\t"\ + "movzbl "MANGLE(ff_h264_mlps_state)"+128("ret"), "tmp" \n\t"\ + "mov "tmpbyte" , "statep" \n\t"\ + "shl %%cl , "low" \n\t"\ + "test "lowword" , "lowword" \n\t"\ + " jnz 1f \n\t"\ + "mov "byte"("cabac"), %%"REG_c" \n\t"\ + "movzwl (%%"REG_c") , "tmp" \n\t"\ + "bswap "tmp" \n\t"\ + "shr $15 , "tmp" \n\t"\ + "sub $0xFFFF , "tmp" \n\t"\ + "add $2 , %%"REG_c" \n\t"\ + "mov %%"REG_c" , "byte "("cabac") \n\t"\ + "lea -1("low") , %%ecx \n\t"\ + "xor "low" , %%ecx \n\t"\ + "shr $15 , %%ecx \n\t"\ + "movzbl " MANGLE(ff_h264_norm_shift) "(%%ecx), %%ecx \n\t"\ + "neg %%ecx \n\t"\ + "add $7 , %%ecx \n\t"\ + "shl %%cl , "tmp" \n\t"\ + "add "tmp" , "low" \n\t"\ + "1: \n\t" + +#if ARCH_X86 && HAVE_7REGS && !defined(BROKEN_RELOCATIONS) +#define get_cabac_inline get_cabac_inline_x86 +static av_always_inline int get_cabac_inline_x86(CABACContext *c, + uint8_t *const state) +{ + int bit, low, range, tmp; + + __asm__ volatile( + "movl %a6(%5), %2 \n\t" + "movl %a7(%5), %1 \n\t" + BRANCHLESS_GET_CABAC("%0", "%5", "(%4)", "%1", "%w1", "%2", + "%3", "%b3", "%a8") + "movl %2, %a6(%5) \n\t" + "movl %1, %a7(%5) \n\t" + + :"=&r"(bit), "=&r"(low), "=&r"(range), "=&r"(tmp) + :"r"(state), "r"(c), + "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), + "i"(offsetof(CABACContext, bytestream)) + : "%"REG_c, "memory" + ); + return bit & 1; +} +#endif /* ARCH_X86 && HAVE_7REGS && !defined(BROKEN_RELOCATIONS) */ + +#define get_cabac_bypass_sign get_cabac_bypass_sign_x86 +static av_always_inline int get_cabac_bypass_sign_x86(CABACContext *c, int val) +{ + x86_reg tmp; + __asm__ volatile( + "movl %a3(%2), %k1 \n\t" + "movl %a4(%2), %%eax \n\t" + "shl $17, %k1 \n\t" + "add %%eax, %%eax \n\t" + "sub %k1, %%eax \n\t" + "cltd \n\t" + "and %%edx, %k1 \n\t" + "add %k1, %%eax \n\t" + "xor %%edx, %%ecx \n\t" + "sub %%edx, %%ecx \n\t" + "test %%ax, %%ax \n\t" + " jnz 1f \n\t" + "mov %a5(%2), %1 \n\t" + "subl $0xFFFF, %%eax \n\t" + "movzwl (%1), %%edx \n\t" + "bswap %%edx \n\t" + "shrl $15, %%edx \n\t" + "add $2, %1 \n\t" + "addl %%edx, %%eax \n\t" + "mov %1, %a5(%2) \n\t" + "1: \n\t" + "movl %%eax, %a4(%2) \n\t" + + :"+c"(val), "=&r"(tmp) + :"r"(c), + "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), + "i"(offsetof(CABACContext, bytestream)) + : "%eax", "%edx", "memory" + ); + return val; +} + +#endif /* AVCODEC_X86_CABAC_H */ diff --git a/libavcodec/x86/h264_i386.h b/libavcodec/x86/h264_i386.h index 9f5e53105e..af3addd848 100644 --- a/libavcodec/x86/h264_i386.h +++ b/libavcodec/x86/h264_i386.h @@ -32,6 +32,7 @@ #include #include "libavcodec/cabac.h" +#include "cabac.h" //FIXME use some macros to avoid duplicating get_cabac (cannot be done yet //as that would make optimization work hard) From c5ee740745596941b84b738cc528ec85b0e6f0a3 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Mon, 20 Jun 2011 23:10:26 +0100 Subject: [PATCH 104/109] x86: cabac: fix register constraints for 32-bit mode Some operands need to be accessed in byte mode, which restricts the available registers in 32-bit mode. Using the 'q' constraint selects a suitable register. Signed-off-by: Mans Rullgard --- libavcodec/x86/cabac.h | 2 +- libavcodec/x86/h264_i386.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/x86/cabac.h b/libavcodec/x86/cabac.h index 3e5a2217ae..52bea9c53d 100644 --- a/libavcodec/x86/cabac.h +++ b/libavcodec/x86/cabac.h @@ -98,7 +98,7 @@ static av_always_inline int get_cabac_inline_x86(CABACContext *c, "movl %2, %a6(%5) \n\t" "movl %1, %a7(%5) \n\t" - :"=&r"(bit), "=&r"(low), "=&r"(range), "=&r"(tmp) + :"=&r"(bit), "=&r"(low), "=&r"(range), "=&q"(tmp) :"r"(state), "r"(c), "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), "i"(offsetof(CABACContext, bytestream)) diff --git a/libavcodec/x86/h264_i386.h b/libavcodec/x86/h264_i386.h index af3addd848..9c86210371 100644 --- a/libavcodec/x86/h264_i386.h +++ b/libavcodec/x86/h264_i386.h @@ -89,7 +89,7 @@ static int decode_significance_x86(CABACContext *c, int max_coeff, "movl %5, %a11(%6) \n\t" "movl %3, %a12(%6) \n\t" - :"=&r"(coeff_count), "+r"(significant_coeff_ctx_base), "+m"(index), + :"=&q"(coeff_count), "+r"(significant_coeff_ctx_base), "+m"(index), "=&r"(low), "=&r"(bit), "=&r"(range) :"r"(c), "m"(minusstart), "m"(end), "m"(minusindex), "m"(last_off), "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), @@ -157,7 +157,7 @@ static int decode_significance_8x8_x86(CABACContext *c, "movl %5, %a12(%7) \n\t" "movl %3, %a13(%7) \n\t" - :"=&r"(coeff_count),"+m"(last), "+m"(index), "=&r"(low), "=&r"(bit), + :"=&q"(coeff_count),"+m"(last), "+m"(index), "=&r"(low), "=&r"(bit), "=&r"(range), "=&r"(state) :"r"(c), "m"(minusindex), "m"(significant_coeff_ctx_base), "m"(sig_off), "m"(last_off), "i"(offsetof(CABACContext, range)), "i"(offsetof(CABACContext, low)), From e6c52cee541ba23a7aec525f72dff73c188dad06 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 7 Jun 2011 13:40:22 -0400 Subject: [PATCH 105/109] Replace usages of av_get_bits_per_sample_fmt() with av_get_bytes_per_sample(). av_get_bits_per_sample_fmt() is deprecated. --- ffmpeg.c | 6 +++--- ffplay.c | 2 +- libavcodec/aacdec.c | 2 +- libavcodec/ac3dec.c | 2 +- libavcodec/alsdec.c | 4 ++-- libavcodec/dca.c | 2 +- libavcodec/resample.c | 4 ++-- libavcodec/utils.c | 2 +- libavcodec/vmdav.c | 2 +- libavcodec/vorbisdec.c | 2 +- libavfilter/defaults.c | 2 +- libavformat/matroskaenc.c | 2 +- 12 files changed, 16 insertions(+), 16 deletions(-) diff --git a/ffmpeg.c b/ffmpeg.c index b28408741c..9f2d5b98b4 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -778,8 +778,8 @@ static void do_audio_out(AVFormatContext *s, int size_out, frame_bytes, ret, resample_changed; AVCodecContext *enc= ost->st->codec; AVCodecContext *dec= ist->st->codec; - int osize= av_get_bits_per_sample_fmt(enc->sample_fmt)/8; - int isize= av_get_bits_per_sample_fmt(dec->sample_fmt)/8; + int osize = av_get_bytes_per_sample(enc->sample_fmt); + int isize = av_get_bytes_per_sample(dec->sample_fmt); const int coded_bps = av_get_bits_per_sample(enc->codec->id); need_realloc: @@ -1481,7 +1481,7 @@ static int output_packet(AVInputStream *ist, int ist_index, #endif AVPacket avpkt; - int bps = av_get_bits_per_sample_fmt(ist->st->codec->sample_fmt)>>3; + int bps = av_get_bytes_per_sample(ist->st->codec->sample_fmt); if(ist->next_pts == AV_NOPTS_VALUE) ist->next_pts= ist->pts; diff --git a/ffplay.c b/ffplay.c index c9891d3cdc..ffd4c230b8 100644 --- a/ffplay.c +++ b/ffplay.c @@ -2032,7 +2032,7 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr) if (is->reformat_ctx) { const void *ibuf[6]= {is->audio_buf1}; void *obuf[6]= {is->audio_buf2}; - int istride[6]= {av_get_bits_per_sample_fmt(dec->sample_fmt)/8}; + int istride[6]= {av_get_bytes_per_sample(dec->sample_fmt)}; int ostride[6]= {2}; int len= data_size/istride[0]; if (av_audio_convert(is->reformat_ctx, obuf, ostride, ibuf, istride, len)<0) { diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c index 69aacb86d6..26ce204257 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -2177,7 +2177,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, } data_size_tmp = samples * avctx->channels * - (av_get_bits_per_sample_fmt(avctx->sample_fmt) / 8); + av_get_bytes_per_sample(avctx->sample_fmt); if (*data_size < data_size_tmp) { av_log(avctx, AV_LOG_ERROR, "Output buffer too small (%d) or trying to output too many samples (%d) for this frame.\n", diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 2966c33b25..42b62ef701 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -1422,7 +1422,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, int *data_size, } } *data_size = s->num_blocks * 256 * avctx->channels * - (av_get_bits_per_sample_fmt(avctx->sample_fmt) / 8); + av_get_bytes_per_sample(avctx->sample_fmt); return FFMIN(buf_size, s->frame_size); } diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c index 17c54900f7..055bfd0d04 100644 --- a/libavcodec/alsdec.c +++ b/libavcodec/alsdec.c @@ -1450,7 +1450,7 @@ static int decode_frame(AVCodecContext *avctx, // check for size of decoded data size = ctx->cur_frame_length * avctx->channels * - (av_get_bits_per_sample_fmt(avctx->sample_fmt) >> 3); + av_get_bytes_per_sample(avctx->sample_fmt); if (size > *data_size) { av_log(avctx, AV_LOG_ERROR, "Decoded data exceeds buffer size.\n"); @@ -1714,7 +1714,7 @@ static av_cold int decode_init(AVCodecContext *avctx) ctx->crc_buffer = av_malloc(sizeof(*ctx->crc_buffer) * ctx->cur_frame_length * avctx->channels * - (av_get_bits_per_sample_fmt(avctx->sample_fmt) >> 3)); + av_get_bytes_per_sample(avctx->sample_fmt)); if (!ctx->crc_buffer) { av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n"); decode_end(avctx); diff --git a/libavcodec/dca.c b/libavcodec/dca.c index a9b2c9b0c9..68731c9033 100644 --- a/libavcodec/dca.c +++ b/libavcodec/dca.c @@ -1813,7 +1813,7 @@ static int dca_decode_frame(AVCodecContext * avctx, } out_size = 256 / 8 * s->sample_blocks * channels * - (av_get_bits_per_sample_fmt(avctx->sample_fmt) / 8); + av_get_bytes_per_sample(avctx->sample_fmt); if (*data_size < out_size) return -1; *data_size = out_size; diff --git a/libavcodec/resample.c b/libavcodec/resample.c index 0bebe1ab88..04bbbf07e4 100644 --- a/libavcodec/resample.c +++ b/libavcodec/resample.c @@ -187,8 +187,8 @@ ReSampleContext *av_audio_resample_init(int output_channels, int input_channels, s->sample_fmt[0] = sample_fmt_in; s->sample_fmt[1] = sample_fmt_out; - s->sample_size[0] = av_get_bits_per_sample_fmt(s->sample_fmt[0]) >> 3; - s->sample_size[1] = av_get_bits_per_sample_fmt(s->sample_fmt[1]) >> 3; + s->sample_size[0] = av_get_bytes_per_sample(s->sample_fmt[0]); + s->sample_size[1] = av_get_bytes_per_sample(s->sample_fmt[1]); if (s->sample_fmt[0] != AV_SAMPLE_FMT_S16) { if (!(s->convert_ctx[0] = av_audio_convert_alloc(AV_SAMPLE_FMT_S16, 1, diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 1e5886473d..146dd306c3 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -1131,7 +1131,7 @@ int av_get_bits_per_sample(enum CodecID codec_id){ #if FF_API_OLD_SAMPLE_FMT int av_get_bits_per_sample_format(enum AVSampleFormat sample_fmt) { - return av_get_bits_per_sample_fmt(sample_fmt); + return av_get_bytes_per_sample(sample_fmt) << 3; } #endif diff --git a/libavcodec/vmdav.c b/libavcodec/vmdav.c index d258252d95..283c2136d5 100644 --- a/libavcodec/vmdav.c +++ b/libavcodec/vmdav.c @@ -447,7 +447,7 @@ static av_cold int vmdaudio_decode_init(AVCodecContext *avctx) avctx->sample_fmt = AV_SAMPLE_FMT_S16; else avctx->sample_fmt = AV_SAMPLE_FMT_U8; - s->out_bps = av_get_bits_per_sample_fmt(avctx->sample_fmt) >> 3; + s->out_bps = av_get_bytes_per_sample(avctx->sample_fmt); av_log(avctx, AV_LOG_DEBUG, "%d channels, %d bits/sample, " "block align = %d, sample rate = %d\n", diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c index 017102e777..9fc60688a2 100644 --- a/libavcodec/vorbisdec.c +++ b/libavcodec/vorbisdec.c @@ -1646,7 +1646,7 @@ static int vorbis_decode_frame(AVCodecContext *avccontext, vc->audio_channels); *data_size = len * vc->audio_channels * - (av_get_bits_per_sample_fmt(avccontext->sample_fmt) / 8); + av_get_bytes_per_sample(avccontext->sample_fmt); return buf_size ; } diff --git a/libavfilter/defaults.c b/libavfilter/defaults.c index 146f1c7105..b891ab1f22 100644 --- a/libavfilter/defaults.c +++ b/libavfilter/defaults.c @@ -84,7 +84,7 @@ AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int per samples->refcount = 1; samples->free = ff_avfilter_default_free_buffer; - sample_size = av_get_bits_per_sample_fmt(sample_fmt) >>3; + sample_size = av_get_bytes_per_sample(sample_fmt); chans_nb = av_get_channel_layout_nb_channels(channel_layout); per_channel_size = size/chans_nb; diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index fde1470f9a..e485539a26 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -527,7 +527,7 @@ static int mkv_write_tracks(AVFormatContext *s) AVDictionaryEntry *tag; if (!bit_depth) - bit_depth = av_get_bits_per_sample_fmt(codec->sample_fmt); + bit_depth = av_get_bytes_per_sample(codec->sample_fmt) << 3; if (codec->codec_id == CODEC_ID_AAC) get_aac_sample_rates(s, codec, &sample_rate, &output_sample_rate); From 2d16394f972dca8cc5e5b5bf9ab0b343a6239b76 Mon Sep 17 00:00:00 2001 From: Kim Nguyen Date: Tue, 21 Jun 2011 00:18:54 +0200 Subject: [PATCH 106/109] ppc32: Fix movrel Fixes ticket272 --- libavcodec/ppc/asm.S | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libavcodec/ppc/asm.S b/libavcodec/ppc/asm.S index e372d53c60..2706d6b1d8 100644 --- a/libavcodec/ppc/asm.S +++ b/libavcodec/ppc/asm.S @@ -67,7 +67,11 @@ X(\name): .macro movrel rd, sym #if CONFIG_PIC - lwz \rd, \sym@got(r2) + bcl 20, 31, lab_pic_\@ +lab_pic_\@: + mflr \rd + addis \rd, \rd, (\sym - lab_pic_\@)@ha + addi \rd, \rd, (\sym - lab_pic_\@)@l #else lis \rd, \sym@ha la \rd, \sym@l(\rd) From b37dfe181cc34ea76155cf449d168c385f32f061 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 21 Jun 2011 02:49:20 +0200 Subject: [PATCH 107/109] mpegaudio_parser: be less picky on the start position Signed-off-by: Michael Niedermayer --- libavcodec/mpegaudio_parser.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/mpegaudio_parser.c b/libavcodec/mpegaudio_parser.c index 94a286fb14..9c19d6ffdb 100644 --- a/libavcodec/mpegaudio_parser.c +++ b/libavcodec/mpegaudio_parser.c @@ -66,7 +66,8 @@ static int mpegaudio_parse(AVCodecParserContext *s1, ret = ff_mpa_decode_header(avctx, state, &sr, &channels, &frame_size, &bit_rate); if (ret < 4) { - s->header_count= -2; + if(i > 4) + s->header_count= -2; } else { if((state&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header) s->header_count= -3; From 90c6963daea9210d7d2104e2ece94dd4e2fffc17 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 21 Jun 2011 04:24:03 +0200 Subject: [PATCH 108/109] avfilter picture pool: double free hotfix This fix introduces a small memleak Signed-off-by: Michael Niedermayer --- libavfilter/avfilter.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 44dd515518..a57677c0e4 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -182,10 +182,11 @@ void avfilter_link_free(AVFilterLink **link) av_freep(&picref->audio); av_freep(&picref->video); - av_freep(&picref); + av_freep(&(*link)->pool->pic[i]); } } - av_freep(&(*link)->pool); + (*link)->pool->count = 0; +// av_freep(&(*link)->pool); } av_freep(link); } From d39b33c63bc080231d8d6e79c6301a60b86150de Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 21 Jun 2011 04:45:29 +0200 Subject: [PATCH 109/109] libx264: fix open gop default. Please use -x264opts to force open gop This fixes Ticket268 Signed-off-by: Michael Niedermayer --- libavcodec/libx264.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c index 1b6f55f801..cc5b9837f8 100644 --- a/libavcodec/libx264.c +++ b/libavcodec/libx264.c @@ -377,7 +377,7 @@ static av_cold int X264_init(AVCodecContext *avctx) x4->params.b_interlaced = avctx->flags & CODEC_FLAG_INTERLACED_DCT; - x4->params.b_open_gop = !(avctx->flags & CODEC_FLAG_CLOSED_GOP); +// x4->params.b_open_gop = !(avctx->flags & CODEC_FLAG_CLOSED_GOP); x4->params.i_slice_count = avctx->slices;