From 488a5b3fddce6714cfa7ccd4a5c91cd2dd355033 Mon Sep 17 00:00:00 2001 From: Uoti Urpala Date: Sun, 18 Dec 2011 16:17:07 +0200 Subject: [PATCH 1/9] tmv decoder: set correct pix_fmt Previously the decoder only worked if the user had set avctx->pix_fmt manually. For some reason the libavformat tmv demuxer sets this, so the problem was not visible in avplay etc. Signed-off-by: Ronald S. Bultje --- libavcodec/tmv.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libavcodec/tmv.c b/libavcodec/tmv.c index 870f57159c..be809b3675 100644 --- a/libavcodec/tmv.c +++ b/libavcodec/tmv.c @@ -82,6 +82,12 @@ static int tmv_decode_frame(AVCodecContext *avctx, void *data, return avpkt->size; } +static av_cold int tmv_decode_init(AVCodecContext *avctx) +{ + avctx->pix_fmt = PIX_FMT_PAL8; + return 0; +} + static av_cold int tmv_decode_close(AVCodecContext *avctx) { TMVContext *tmv = avctx->priv_data; @@ -97,6 +103,7 @@ AVCodec ff_tmv_decoder = { .type = AVMEDIA_TYPE_VIDEO, .id = CODEC_ID_TMV, .priv_data_size = sizeof(TMVContext), + .init = tmv_decode_init, .close = tmv_decode_close, .decode = tmv_decode_frame, .capabilities = CODEC_CAP_DR1, From 08f7af0c379d9eaa931a93e6e733879237be054d Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 17 Dec 2011 15:00:04 +0100 Subject: [PATCH 2/9] lavf: rename oma.c -> omadec.c --- libavformat/Makefile | 2 +- libavformat/{oma.c => omadec.c} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename libavformat/{oma.c => omadec.c} (100%) diff --git a/libavformat/Makefile b/libavformat/Makefile index ea28290da8..fe59723b79 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -178,7 +178,7 @@ OBJS-$(CONFIG_OGG_DEMUXER) += oggdec.o \ vorbiscomment.o OBJS-$(CONFIG_OGG_MUXER) += oggenc.o \ vorbiscomment.o -OBJS-$(CONFIG_OMA_DEMUXER) += oma.o pcm.o +OBJS-$(CONFIG_OMA_DEMUXER) += omadec.o pcm.o OBJS-$(CONFIG_PCM_ALAW_DEMUXER) += pcmdec.o pcm.o rawdec.o OBJS-$(CONFIG_PCM_ALAW_MUXER) += pcmenc.o rawenc.o OBJS-$(CONFIG_PCM_F32BE_DEMUXER) += pcmdec.o pcm.o rawdec.o diff --git a/libavformat/oma.c b/libavformat/omadec.c similarity index 100% rename from libavformat/oma.c rename to libavformat/omadec.c From ee20b332c872b48cbcf914a2b4adc52aa3e94175 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 17 Dec 2011 15:23:13 +0100 Subject: [PATCH 3/9] omadec: split data that will be used in the muxer to a separate file. --- libavformat/Makefile | 2 +- libavformat/oma.c | 33 +++++++++++++++++++++++++++++++++ libavformat/oma.h | 39 +++++++++++++++++++++++++++++++++++++++ libavformat/omadec.c | 28 +++++----------------------- 4 files changed, 78 insertions(+), 24 deletions(-) create mode 100644 libavformat/oma.c create mode 100644 libavformat/oma.h diff --git a/libavformat/Makefile b/libavformat/Makefile index fe59723b79..aa15b7ea45 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -178,7 +178,7 @@ OBJS-$(CONFIG_OGG_DEMUXER) += oggdec.o \ vorbiscomment.o OBJS-$(CONFIG_OGG_MUXER) += oggenc.o \ vorbiscomment.o -OBJS-$(CONFIG_OMA_DEMUXER) += omadec.o pcm.o +OBJS-$(CONFIG_OMA_DEMUXER) += omadec.o pcm.o oma.o OBJS-$(CONFIG_PCM_ALAW_DEMUXER) += pcmdec.o pcm.o rawdec.o OBJS-$(CONFIG_PCM_ALAW_MUXER) += pcmenc.o rawenc.o OBJS-$(CONFIG_PCM_F32BE_DEMUXER) += pcmdec.o pcm.o rawdec.o diff --git a/libavformat/oma.c b/libavformat/oma.c new file mode 100644 index 0000000000..930991cf00 --- /dev/null +++ b/libavformat/oma.c @@ -0,0 +1,33 @@ +/* + * Sony OpenMG (OMA) common data + * + * 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 "internal.h" +#include "oma.h" +#include "libavcodec/avcodec.h" + +const uint16_t ff_oma_srate_tab[6] = { 320, 441, 480, 882, 960, 0 }; + +const AVCodecTag ff_oma_codec_tags[] = { + { CODEC_ID_ATRAC3, OMA_CODECID_ATRAC3 }, + { CODEC_ID_ATRAC3P, OMA_CODECID_ATRAC3P }, + { CODEC_ID_MP3, OMA_CODECID_MP3 }, + { CODEC_ID_PCM_S16BE, OMA_CODECID_LPCM }, + { 0 }, +}; diff --git a/libavformat/oma.h b/libavformat/oma.h new file mode 100644 index 0000000000..2830b34673 --- /dev/null +++ b/libavformat/oma.h @@ -0,0 +1,39 @@ +/* + * Sony OpenMG (OMA) common data + * + * 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 AVFORMAT_OMA_H +#define AVFORMAT_OMA_H + +#define EA3_HEADER_SIZE 96 +#define ID3v2_EA3_MAGIC "ea3" +#define OMA_ENC_HEADER_SIZE 16 + +enum { + OMA_CODECID_ATRAC3 = 0, + OMA_CODECID_ATRAC3P = 1, + OMA_CODECID_MP3 = 3, + OMA_CODECID_LPCM = 4, + OMA_CODECID_WMA = 5, +}; + +extern const uint16_t ff_oma_srate_tab[6]; + +extern const AVCodecTag ff_oma_codec_tags[]; +#endif diff --git a/libavformat/omadec.c b/libavformat/omadec.c index 1aa9a25477..0beed7165d 100644 --- a/libavformat/omadec.c +++ b/libavformat/omadec.c @@ -44,28 +44,11 @@ #include "internal.h" #include "libavutil/intreadwrite.h" #include "libavutil/des.h" +#include "oma.h" #include "pcm.h" #include "riff.h" #include "id3v2.h" -#define EA3_HEADER_SIZE 96 -#define ID3v2_EA3_MAGIC "ea3" -#define OMA_ENC_HEADER_SIZE 16 - -enum { - OMA_CODECID_ATRAC3 = 0, - OMA_CODECID_ATRAC3P = 1, - OMA_CODECID_MP3 = 3, - OMA_CODECID_LPCM = 4, - OMA_CODECID_WMA = 5, -}; - -static const AVCodecTag codec_oma_tags[] = { - { CODEC_ID_ATRAC3, OMA_CODECID_ATRAC3 }, - { CODEC_ID_ATRAC3P, OMA_CODECID_ATRAC3P }, - { CODEC_ID_MP3, OMA_CODECID_MP3 }, - { CODEC_ID_PCM_S16BE, OMA_CODECID_LPCM }, -}; static const uint64_t leaf_table[] = { 0xd79e8283acea4620, 0x7a9762f445afd0d8, @@ -276,7 +259,6 @@ static int decrypt_init(AVFormatContext *s, ID3v2ExtraMeta *em, uint8_t *header) static int oma_read_header(AVFormatContext *s, AVFormatParameters *ap) { - static const uint16_t srate_tab[6] = {320,441,480,882,960,0}; int ret, framesize, jsflag, samplerate; uint32_t codec_params; int16_t eid; @@ -316,11 +298,11 @@ static int oma_read_header(AVFormatContext *s, st->start_time = 0; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_tag = buf[32]; - st->codec->codec_id = ff_codec_get_id(codec_oma_tags, st->codec->codec_tag); + st->codec->codec_id = ff_codec_get_id(ff_oma_codec_tags, st->codec->codec_tag); switch (buf[32]) { case OMA_CODECID_ATRAC3: - samplerate = srate_tab[(codec_params >> 13) & 7]*100; + samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7]*100; if (samplerate != 44100) av_log_ask_for_sample(s, "Unsupported sample rate: %d\n", samplerate); @@ -350,7 +332,7 @@ static int oma_read_header(AVFormatContext *s, case OMA_CODECID_ATRAC3P: st->codec->channels = (codec_params >> 10) & 7; framesize = ((codec_params & 0x3FF) * 8) + 8; - st->codec->sample_rate = srate_tab[(codec_params >> 13) & 7]*100; + st->codec->sample_rate = ff_oma_srate_tab[(codec_params >> 13) & 7]*100; st->codec->bit_rate = st->codec->sample_rate * framesize * 8 / 1024; avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); av_log(s, AV_LOG_ERROR, "Unsupported codec ATRAC3+!\n"); @@ -459,6 +441,6 @@ AVInputFormat ff_oma_demuxer = { .read_seek = oma_read_seek, .flags = AVFMT_GENERIC_INDEX, .extensions = "oma,omg,aa3", - .codec_tag = (const AVCodecTag* const []){codec_oma_tags, 0}, + .codec_tag = (const AVCodecTag* const []){ff_oma_codec_tags, 0}, }; From f40e7eb573a42cd90323a1273af9634bbaf7ef14 Mon Sep 17 00:00:00 2001 From: Michael Karcher Date: Fri, 21 Oct 2011 23:32:33 +0200 Subject: [PATCH 4/9] lavf: add OpenMG audio muxer. Signed-off-by: Anton Khirnov --- Changelog | 1 + doc/general.texi | 2 +- libavformat/Makefile | 1 + libavformat/allformats.c | 2 +- libavformat/omaenc.c | 105 +++++++++++++++++++++++++++++++++++++++ libavformat/version.h | 2 +- 6 files changed, 110 insertions(+), 3 deletions(-) create mode 100644 libavformat/omaenc.c diff --git a/Changelog b/Changelog index b99935b0a3..5f5154a4bb 100644 --- a/Changelog +++ b/Changelog @@ -108,6 +108,7 @@ easier to use. The changes are: - CLJR encoder - Dxtory capture format decoder - v410 QuickTime uncompressed 4:4:4 10-bit encoder and decoder +- OpenMG Audio muxer version 0.7: diff --git a/doc/general.texi b/doc/general.texi index 88c044df2e..74f3cb6607 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -296,7 +296,7 @@ library: @tab Used in Sierra CD-ROM games. @item Smacker @tab @tab X @tab Multimedia format used by many games. -@item Sony OpenMG (OMA) @tab @tab X +@item Sony OpenMG (OMA) @tab X @tab X @tab Audio format used in Sony Sonic Stage and Sony Vegas. @item Sony PlayStation STR @tab @tab X @item Sony Wave64 (W64) @tab @tab X diff --git a/libavformat/Makefile b/libavformat/Makefile index aa15b7ea45..ff6140b0c9 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -179,6 +179,7 @@ OBJS-$(CONFIG_OGG_DEMUXER) += oggdec.o \ OBJS-$(CONFIG_OGG_MUXER) += oggenc.o \ vorbiscomment.o OBJS-$(CONFIG_OMA_DEMUXER) += omadec.o pcm.o oma.o +OBJS-$(CONFIG_OMA_MUXER) += omaenc.o rawenc.o oma.o OBJS-$(CONFIG_PCM_ALAW_DEMUXER) += pcmdec.o pcm.o rawdec.o OBJS-$(CONFIG_PCM_ALAW_MUXER) += pcmenc.o rawenc.o OBJS-$(CONFIG_PCM_F32BE_DEMUXER) += pcmdec.o pcm.o rawdec.o diff --git a/libavformat/allformats.c b/libavformat/allformats.c index fe775f4cce..c75f1bacae 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -156,7 +156,7 @@ void av_register_all(void) REGISTER_MUXDEMUX (NUT, nut); REGISTER_DEMUXER (NUV, nuv); REGISTER_MUXDEMUX (OGG, ogg); - REGISTER_DEMUXER (OMA, oma); + REGISTER_MUXDEMUX (OMA, oma); REGISTER_MUXDEMUX (PCM_ALAW, pcm_alaw); REGISTER_MUXDEMUX (PCM_MULAW, pcm_mulaw); REGISTER_MUXDEMUX (PCM_F64BE, pcm_f64be); diff --git a/libavformat/omaenc.c b/libavformat/omaenc.c new file mode 100644 index 0000000000..e932b4bbc1 --- /dev/null +++ b/libavformat/omaenc.c @@ -0,0 +1,105 @@ +/* + * Sony OpenMG (OMA) muxer + * + * Copyright (c) 2011 Michael Karcher + * + * 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 "avformat.h" +#include "avio_internal.h" +#include "id3v2.h" +#include "internal.h" +#include "oma.h" +#include "rawenc.h" + +static av_cold int oma_write_header(AVFormatContext *s) +{ + int i; + AVCodecContext *format; + int srate_index; + int isjointstereo; + + format = s->streams[0]->codec; + /* check for support of the format first */ + + for (srate_index = 0; ; srate_index++) { + if (ff_oma_srate_tab[srate_index] == 0) { + av_log(s, AV_LOG_ERROR, "Sample rate %d not supported in OpenMG audio\n", + format->sample_rate); + return AVERROR(EINVAL); + } + + if (ff_oma_srate_tab[srate_index] * 100 == format->sample_rate) + break; + } + + /* Metadata; OpenMG does not support ID3v2.4 */ + ff_id3v2_write(s, 3, ID3v2_EA3_MAGIC); + + ffio_wfourcc(s->pb, "EA3\0"); + avio_w8(s->pb, EA3_HEADER_SIZE >> 7); + avio_w8(s->pb, EA3_HEADER_SIZE & 0x7F); + avio_wl16(s->pb, 0xFFFF); /* not encrypted */ + for (i = 0; i < 6; i++) + avio_wl32(s->pb, 0); /* Padding + DRM id */ + + switch(format->codec_tag) { + case OMA_CODECID_ATRAC3: + if (format->channels != 2) { + av_log(s, AV_LOG_ERROR, "ATRAC3 in OMA is only supported with 2 channels"); + return AVERROR(EINVAL); + } + if (format->extradata_size == 14) /* WAV format extradata */ + isjointstereo = format->extradata[6] != 0; + else if(format->extradata_size == 10) /* RM format extradata */ + isjointstereo = format->extradata[8] == 0x12; + else { + av_log(s, AV_LOG_ERROR, "ATRAC3: Unsupported extradata size\n"); + return AVERROR(EINVAL); + } + avio_wb32(s->pb, (OMA_CODECID_ATRAC3 << 24) | + (isjointstereo << 17) | + (srate_index << 13) | + (format->block_align/8)); + break; + case OMA_CODECID_ATRAC3P: + avio_wb32(s->pb, (OMA_CODECID_ATRAC3P << 24) | + (srate_index << 13) | + (format->channels << 10) | + (format->block_align/8 - 1)); + break; + default: + av_log(s, AV_LOG_ERROR, "OMA: unsupported codec tag %d for write\n", + format->codec_tag); + } + for (i = 0; i < (EA3_HEADER_SIZE - 36)/4; i++) + avio_wl32(s->pb, 0); /* Padding */ + + return 0; +} + +AVOutputFormat ff_oma_muxer = { + .name = "oma", + .long_name = NULL_IF_CONFIG_SMALL("Sony OpenMG audio"), + .mime_type = "audio/x-oma", + .extensions = "oma", + .audio_codec = CODEC_ID_ATRAC3, + .write_header = oma_write_header, + .write_packet = ff_raw_write_packet, + .codec_tag = (const AVCodecTag* const []){ff_oma_codec_tags, 0}, +}; diff --git a/libavformat/version.h b/libavformat/version.h index e80787b2ee..a841701e50 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -30,7 +30,7 @@ #include "libavutil/avutil.h" #define LIBAVFORMAT_VERSION_MAJOR 53 -#define LIBAVFORMAT_VERSION_MINOR 17 +#define LIBAVFORMAT_VERSION_MINOR 18 #define LIBAVFORMAT_VERSION_MICRO 0 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ From d49352c7cc22fd8928a761a373c3508be17c9f19 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Sun, 18 Dec 2011 08:27:43 -0800 Subject: [PATCH 5/9] swscale: fix overflows in vertical scaling at top/bottom edges. This fixes integer multiplication overflows in RGB48 output (vertical) scaling as detected by IOC. What happens is that for certain types of filters (lanczos, spline, bicubic), the intermediate sum of coefficients in the middle of a filter can be larger than the fixed-point equivalent of 1.0, even if the final sum is 1.0. This is fine and we support that. However, at frame edges, initFilter() will merge the coefficients for the off-screen pixels into the top or bottom pixel, such as to emulate edge extension. This means that suddenly, a single coefficient can be larger than the fixed-point equivalent of 1.0, which the vertical scaling routines do not support. Therefore, remove the merging of coefficients for edges for the vertical scaling filter, and instead add edge detection to the scaler itself so that it copies the pointers (not data) for the edges (i.e. it uses line[0] for line[-1] as well), so that a single coefficient is never larger than the fixed-point equivalent of 1.0. --- libswscale/swscale.c | 51 +++++++++++++++++++++++++++++++++++++--- libswscale/utils.c | 56 +++++++++++++++++++++++--------------------- 2 files changed, 77 insertions(+), 30 deletions(-) diff --git a/libswscale/swscale.c b/libswscale/swscale.c index c9dfc8df2f..f24561b8bf 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -2487,9 +2487,11 @@ static int swScale(SwsContext *c, const uint8_t* src[], const int firstLumSrcY= vLumFilterPos[dstY]; //First line needed as input const int firstLumSrcY2= vLumFilterPos[FFMIN(dstY | ((1<chrDstVSubSample) - 1), dstH-1)]; const int firstChrSrcY= vChrFilterPos[chrDstY]; //First line needed as input - int lastLumSrcY= firstLumSrcY + vLumFilterSize -1; // Last line needed as input - int lastLumSrcY2=firstLumSrcY2+ vLumFilterSize -1; // Last line needed as input - int lastChrSrcY= firstChrSrcY + vChrFilterSize -1; // Last line needed as input + + // Last line needed as input + int lastLumSrcY = FFMIN(c->srcH, firstLumSrcY + vLumFilterSize) - 1; + int lastLumSrcY2 = FFMIN(c->srcH, firstLumSrcY2 + vLumFilterSize) - 1; + int lastChrSrcY = FFMIN(c->chrSrcH, firstChrSrcY + vChrFilterSize) - 1; int enough_lines; //handle holes (FAST_BILINEAR & weird filters) @@ -2585,6 +2587,49 @@ static int swScale(SwsContext *c, const uint8_t* src[], const int16_t **chrUSrcPtr= (const int16_t **) chrUPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize; const int16_t **chrVSrcPtr= (const int16_t **) chrVPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize; const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL; + + if (firstLumSrcY < 0 || firstLumSrcY + vLumFilterSize > c->srcH) { + const int16_t **tmpY = (const int16_t **) lumPixBuf + 2 * vLumBufSize; + int neg = -firstLumSrcY, i, end = FFMIN(c->srcH - firstLumSrcY, vLumFilterSize); + for (i = 0; i < neg; i++) + tmpY[i] = lumSrcPtr[neg]; + for ( ; i < end; i++) + tmpY[i] = lumSrcPtr[i]; + for ( ; i < vLumFilterSize; i++) + tmpY[i] = tmpY[i-1]; + lumSrcPtr = tmpY; + + if (alpSrcPtr) { + const int16_t **tmpA = (const int16_t **) alpPixBuf + 2 * vLumBufSize; + for (i = 0; i < neg; i++) + tmpA[i] = alpSrcPtr[neg]; + for ( ; i < end; i++) + tmpA[i] = alpSrcPtr[i]; + for ( ; i < vLumFilterSize; i++) + tmpA[i] = tmpA[i - 1]; + alpSrcPtr = tmpA; + } + } + if (firstChrSrcY < 0 || firstChrSrcY + vChrFilterSize > c->chrSrcH) { + const int16_t **tmpU = (const int16_t **) chrUPixBuf + 2 * vChrBufSize, + **tmpV = (const int16_t **) chrVPixBuf + 2 * vChrBufSize; + int neg = -firstChrSrcY, i, end = FFMIN(c->chrSrcH - firstChrSrcY, vChrFilterSize); + for (i = 0; i < neg; i++) { + tmpU[i] = chrUSrcPtr[neg]; + tmpV[i] = chrVSrcPtr[neg]; + } + for ( ; i < end; i++) { + tmpU[i] = chrUSrcPtr[i]; + tmpV[i] = chrVSrcPtr[i]; + } + for ( ; i < vChrFilterSize; i++) { + tmpU[i] = tmpU[i - 1]; + tmpV[i] = tmpV[i - 1]; + } + chrUSrcPtr = tmpU; + chrVSrcPtr = tmpV; + } + if (isPlanarYUV(dstFormat) || dstFormat==PIX_FMT_GRAY8) { //YV12 like const int chrSkipMask= (1<chrDstVSubSample)-1; diff --git a/libswscale/utils.c b/libswscale/utils.c index b644ed9610..12b3202b16 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -182,7 +182,7 @@ static double getSplineCoeff(double a, double b, double c, double d, double dist static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSize, int xInc, int srcW, int dstW, int filterAlign, int one, int flags, int cpu_flags, - SwsVector *srcFilter, SwsVector *dstFilter, double param[2]) + SwsVector *srcFilter, SwsVector *dstFilter, double param[2], int is_horizontal) { int i; int filterSize; @@ -459,27 +459,29 @@ static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSi //FIXME try to align filterPos if possible //fix borders - for (i=0; i srcW) { - int shift= (*filterPos)[i] + filterSize - srcW; - // move filter coefficients right to compensate for filterPos - for (j=filterSize-2; j>=0; j--) { - int right= FFMIN(j + shift, filterSize-1); - filter[i*filterSize +right] += filter[i*filterSize +j]; - filter[i*filterSize +j]=0; + if ((*filterPos)[i] + filterSize > srcW) { + int shift = (*filterPos)[i] + filterSize - srcW; + // move filter coefficients right to compensate for filterPos + for (j = filterSize - 2; j >= 0; j--) { + int right = FFMIN(j + shift, filterSize - 1); + filter[i * filterSize + right] += filter[i * filterSize + j]; + filter[i * filterSize + j ] = 0; + } + (*filterPos)[i] = srcW - filterSize; } - (*filterPos)[i]= srcW - filterSize; } } @@ -958,12 +960,12 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) if (initFilter(&c->hLumFilter, &c->hLumFilterPos, &c->hLumFilterSize, c->lumXInc, srcW , dstW, filterAlign, 1<<14, (flags&SWS_BICUBLIN) ? (flags|SWS_BICUBIC) : flags, cpu_flags, - srcFilter->lumH, dstFilter->lumH, c->param) < 0) + srcFilter->lumH, dstFilter->lumH, c->param, 1) < 0) goto fail; if (initFilter(&c->hChrFilter, &c->hChrFilterPos, &c->hChrFilterSize, c->chrXInc, c->chrSrcW, c->chrDstW, filterAlign, 1<<14, (flags&SWS_BICUBLIN) ? (flags|SWS_BILINEAR) : flags, cpu_flags, - srcFilter->chrH, dstFilter->chrH, c->param) < 0) + srcFilter->chrH, dstFilter->chrH, c->param, 1) < 0) goto fail; } } // initialize horizontal stuff @@ -978,12 +980,12 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) if (initFilter(&c->vLumFilter, &c->vLumFilterPos, &c->vLumFilterSize, c->lumYInc, srcH , dstH, filterAlign, (1<<12), (flags&SWS_BICUBLIN) ? (flags|SWS_BICUBIC) : flags, cpu_flags, - srcFilter->lumV, dstFilter->lumV, c->param) < 0) + srcFilter->lumV, dstFilter->lumV, c->param, 0) < 0) goto fail; if (initFilter(&c->vChrFilter, &c->vChrFilterPos, &c->vChrFilterSize, c->chrYInc, c->chrSrcH, c->chrDstH, filterAlign, (1<<12), (flags&SWS_BICUBLIN) ? (flags|SWS_BILINEAR) : flags, cpu_flags, - srcFilter->chrV, dstFilter->chrV, c->param) < 0) + srcFilter->chrV, dstFilter->chrV, c->param, 0) < 0) goto fail; #if HAVE_ALTIVEC @@ -1024,11 +1026,11 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) // allocate pixbufs (we use dynamic allocation because otherwise we would need to // allocate several megabytes to handle all possible cases) - FF_ALLOC_OR_GOTO(c, c->lumPixBuf, c->vLumBufSize*2*sizeof(int16_t*), fail); - FF_ALLOC_OR_GOTO(c, c->chrUPixBuf, c->vChrBufSize*2*sizeof(int16_t*), fail); - FF_ALLOC_OR_GOTO(c, c->chrVPixBuf, c->vChrBufSize*2*sizeof(int16_t*), fail); + FF_ALLOC_OR_GOTO(c, c->lumPixBuf, c->vLumBufSize*3*sizeof(int16_t*), fail); + FF_ALLOC_OR_GOTO(c, c->chrUPixBuf, c->vChrBufSize*3*sizeof(int16_t*), fail); + FF_ALLOC_OR_GOTO(c, c->chrVPixBuf, c->vChrBufSize*3*sizeof(int16_t*), fail); if (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat) && isALPHA(c->dstFormat)) - FF_ALLOCZ_OR_GOTO(c, c->alpPixBuf, c->vLumBufSize*2*sizeof(int16_t*), fail); + FF_ALLOCZ_OR_GOTO(c, c->alpPixBuf, c->vLumBufSize*3*sizeof(int16_t*), fail); //Note we need at least one pixel more at the end because of the MMX code (just in case someone wanna replace the 4000/8000) /* align at 16 bytes for AltiVec */ for (i=0; ivLumBufSize; i++) { From 93fc5a9ff66637475025433c91876b80422f7bb4 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Tue, 6 Dec 2011 07:51:54 +0100 Subject: [PATCH 6/9] lavf: force threads to 1 in avformat_find_stream_info() Fixes avformat_find_stream_info() on streams with number of frames < thread count. --- libavformat/utils.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavformat/utils.c b/libavformat/utils.c index f42428563d..bc5b7e02da 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2291,6 +2291,11 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) assert(!st->codec->codec); codec = avcodec_find_decoder(st->codec->codec_id); + /* this function doesn't flush the decoders, so force thread count + * to 1 to fix behavior when thread count > number of frames in the file */ + if (options) + av_dict_set(&options[i], "threads", "1", 0); + /* Ensure that subtitle_header is properly set. */ if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE && codec && !st->codec->codec) From bc78ceec2be6613c265387017221c7ceda15aa7d Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 18 Dec 2011 13:21:27 -0500 Subject: [PATCH 7/9] 4xm: remove unneeded check for remaining unused data. This is unnecessary complication that only prints a message and does not affect decoding. --- libavcodec/4xm.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c index 21bde52fee..0ae10d5905 100644 --- a/libavcodec/4xm.c +++ b/libavcodec/4xm.c @@ -415,15 +415,6 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length){ dst += 8*stride; } - if( bitstream_size != (get_bits_count(&f->gb)+31)/32*4 - || (((const char*)f->wordstream - (const char*)buf + 2)&~2) != extra + bitstream_size + wordstream_size - || (((const char*)f->bytestream - (const char*)buf + 3)&~3) != extra + bitstream_size + wordstream_size + bytestream_size) - av_log(f->avctx, AV_LOG_ERROR, " %d %td %td bytes left\n", - bitstream_size - (get_bits_count(&f->gb)+31)/32*4, - -(((const char*)f->bytestream - (const char*)buf + 3)&~3) + (extra + bitstream_size + wordstream_size + bytestream_size), - -(((const char*)f->wordstream - (const char*)buf + 2)&~2) + (extra + bitstream_size + wordstream_size) - ); - return 0; } From 8400b126acb153329c418433c377d96afd1d1e02 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sun, 18 Dec 2011 20:41:42 +0000 Subject: [PATCH 8/9] avcodec: deprecate AVFrame.age This was intended as an optimisation for skipped blocks in MPEG2 P-frames and never used elsewhere. Removing this "optimisation" speeds up MPEG2 decoding by 1-2% (ARM Cortex-A9). Signed-off-by: Mans Rullgard --- avplay.c | 1 - doc/APIchanges | 3 +++ libavcodec/avcodec.h | 9 ++++----- libavcodec/internal.h | 1 - libavcodec/mpegvideo.c | 36 +++++------------------------------- libavcodec/mpegvideo.h | 2 -- libavcodec/pthread.c | 7 ------- libavcodec/utils.c | 10 +--------- libavcodec/version.h | 5 ++++- 9 files changed, 17 insertions(+), 57 deletions(-) diff --git a/avplay.c b/avplay.c index f90899c57b..5fcfaa68e7 100644 --- a/avplay.c +++ b/avplay.c @@ -1564,7 +1564,6 @@ static int input_get_buffer(AVCodecContext *codec, AVFrame *pic) pic->linesize[i] = ref->linesize[i]; } pic->opaque = ref; - pic->age = INT_MAX; pic->type = FF_BUFFER_TYPE_USER; pic->reordered_opaque = codec->reordered_opaque; if(codec->pkt) pic->pkt_pts = codec->pkt->pts; diff --git a/doc/APIchanges b/doc/APIchanges index 49c49d8b49..a7acc6d0c2 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,9 @@ libavutil: 2011-04-18 API changes, most recent first: +2011-12-18 - xxxxxxx - lavc 53.28.1 + Deprecate AVFrame.age. The field is unused. + 2011-xx-xx - xxxxxxx - lavf 53.17.0 Add avformat_open_input(). Deprecate av_close_input_file() and av_close_input_stream(). diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 1715bbb32b..7f4651b80f 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -1004,13 +1004,12 @@ typedef struct AVFrame { */ int quality; +#if FF_API_AVFRAME_AGE /** - * buffer age (1->was last buffer and dint change, 2->..., ...). - * Set to INT_MAX if the buffer has not been used yet. - * - encoding: unused - * - decoding: MUST be set by get_buffer() for video. + * @deprecated unused */ - int age; + attribute_deprecated int age; +#endif /** * is this picture used as reference diff --git a/libavcodec/internal.h b/libavcodec/internal.h index fb011c7a3a..b5a04546f3 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -30,7 +30,6 @@ #include "avcodec.h" typedef struct InternalBuffer { - int last_pic_num; uint8_t *base[AV_NUM_DATA_POINTERS]; uint8_t *data[AV_NUM_DATA_POINTERS]; int linesize[AV_NUM_DATA_POINTERS]; diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index ab57b51e87..d190606eff 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -263,9 +263,9 @@ static int alloc_frame_buffer(MpegEncContext *s, Picture *pic) else r = avcodec_default_get_buffer(s->avctx, (AVFrame *) pic); - if (r < 0 || !pic->f.age || !pic->f.type || !pic->f.data[0]) { - av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (%d %d %d %p)\n", - r, pic->f.age, pic->f.type, pic->f.data[0]); + if (r < 0 || !pic->f.type || !pic->f.data[0]) { + av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (%d %d %p)\n", + r, pic->f.type, pic->f.data[0]); av_freep(&pic->f.hwaccel_picture_private); return -1; } @@ -369,15 +369,6 @@ int ff_alloc_picture(MpegEncContext *s, Picture *pic, int shared) 1 * sizeof(AVPanScan), fail) } - /* It might be nicer if the application would keep track of these - * but it would require an API change. */ - memmove(s->prev_pict_types + 1, s->prev_pict_types, - PREV_PICT_TYPES_BUFFER_SIZE-1); - s->prev_pict_types[0] = s->dropable ? AV_PICTURE_TYPE_B : s->pict_type; - if (pic->f.age < PREV_PICT_TYPES_BUFFER_SIZE && - s->prev_pict_types[pic->f.age] == AV_PICTURE_TYPE_B) - pic->f.age = INT_MAX; // Skipped MBs in B-frames are quite rare in MPEG-1/2 - // and it is a bit tricky to skip them anyway. pic->owner2 = s; return 0; @@ -574,9 +565,6 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst, s->current_picture_ptr = REBASE_PICTURE(s1->current_picture_ptr, s, s1); s->next_picture_ptr = REBASE_PICTURE(s1->next_picture_ptr, s, s1); - memcpy(s->prev_pict_types, s1->prev_pict_types, - PREV_PICT_TYPES_BUFFER_SIZE); - // Error/bug resilience s->next_p_frame_damaged = s1->next_p_frame_damaged; s->workaround_bugs = s1->workaround_bugs; @@ -880,8 +868,6 @@ av_cold int MPV_common_init(MpegEncContext *s) /* init macroblock skip table */ FF_ALLOCZ_OR_GOTO(s->avctx, s->mbskip_table, mb_array_size + 2, fail); // Note the + 1 is for a quicker mpeg4 slice_end detection - FF_ALLOCZ_OR_GOTO(s->avctx, s->prev_pict_types, - PREV_PICT_TYPES_BUFFER_SIZE, fail); s->parse_context.state = -1; if ((s->avctx->debug & (FF_DEBUG_VIS_QP | FF_DEBUG_VIS_MB_TYPE)) || @@ -981,7 +967,6 @@ void MPV_common_end(MpegEncContext *s) av_freep(&s->pred_dir_table); av_freep(&s->mbskip_table); - av_freep(&s->prev_pict_types); av_freep(&s->bitstream_buffer); s->allocated_bitstream_buffer_size = 0; @@ -2215,24 +2200,13 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64], /* skip only during decoding as we might trash the buffers during encoding a bit */ if(!s->encoding){ uint8_t *mbskip_ptr = &s->mbskip_table[mb_xy]; - const int age = s->current_picture.f.age; - - assert(age); if (s->mb_skipped) { s->mb_skipped= 0; assert(s->pict_type!=AV_PICTURE_TYPE_I); - - (*mbskip_ptr) ++; /* indicate that this time we skipped it */ - if(*mbskip_ptr >99) *mbskip_ptr= 99; - - /* if previous was skipped too, then nothing to do ! */ - if (*mbskip_ptr >= age && s->current_picture.f.reference){ - return; - } + *mbskip_ptr = 1; } else if(!s->current_picture.f.reference) { - (*mbskip_ptr) ++; /* increase counter so the age can be compared cleanly */ - if(*mbskip_ptr >99) *mbskip_ptr= 99; + *mbskip_ptr = 1; } else{ *mbskip_ptr = 0; /* not skipped */ } diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index 38bbd123ee..6483893c1a 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -309,8 +309,6 @@ typedef struct MpegEncContext { uint8_t *coded_block; ///< used for coded block pattern prediction (msmpeg4v3, wmv1) int16_t (*ac_val_base)[16]; int16_t (*ac_val[3])[16]; ///< used for for mpeg4 AC prediction, all 3 arrays must be continuous - uint8_t *prev_pict_types; ///< previous picture types in bitstream order, used for mb skip -#define PREV_PICT_TYPES_BUFFER_SIZE 256 int mb_skipped; ///< MUST BE SET only during DECODING uint8_t *mbskip_table; /**< used to avoid copy if macroblock skipped (for black regions for example) and used for b-frame encoding & decoding (contains skip table of next P Frame) */ diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c index 5f427c0390..7e03c64f40 100644 --- a/libavcodec/pthread.c +++ b/libavcodec/pthread.c @@ -855,13 +855,6 @@ int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f) pthread_mutex_unlock(&p->parent->buffer_mutex); - /* - * Buffer age is difficult to keep track of between - * multiple threads, and the optimizations it allows - * are not worth the effort. It is disabled for now. - */ - f->age = INT_MAX; - return err; } diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 68fc525184..9d17ee4edb 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -346,7 +346,6 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic) int w= s->width; int h= s->height; InternalBuffer *buf; - int *picture_number; AVCodecInternal *avci = s->internal; if(pic->data[0]!=NULL) { @@ -367,8 +366,6 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic) } buf = &avci->buffer[avci->buffer_count]; - picture_number = &(avci->buffer[INTERNAL_BUFFER_SIZE]).last_pic_num; //FIXME ugly hack - (*picture_number)++; if(buf->base[0] && (buf->width != w || buf->height != h || buf->pix_fmt != s->pix_fmt)){ if(s->active_thread_type&FF_THREAD_FRAME) { @@ -382,10 +379,7 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic) } } - if(buf->base[0]){ - pic->age= *picture_number - buf->last_pic_num; - buf->last_pic_num= *picture_number; - }else{ + if (!buf->base[0]) { int h_chroma_shift, v_chroma_shift; int size[4] = {0}; int tmpsize; @@ -424,7 +418,6 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic) size[i] = picture.data[i+1] - picture.data[i]; size[i] = tmpsize - (picture.data[i] - picture.data[0]); - buf->last_pic_num= -256*256*256*64; memset(buf->base, 0, sizeof(buf->base)); memset(buf->data, 0, sizeof(buf->data)); @@ -453,7 +446,6 @@ static int video_get_buffer(AVCodecContext *s, AVFrame *pic) buf->width = s->width; buf->height = s->height; buf->pix_fmt= s->pix_fmt; - pic->age= 256*256*256*64; } pic->type= FF_BUFFER_TYPE_INTERNAL; diff --git a/libavcodec/version.h b/libavcodec/version.h index d15fb48825..e95825139d 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -22,7 +22,7 @@ #define LIBAVCODEC_VERSION_MAJOR 53 #define LIBAVCODEC_VERSION_MINOR 28 -#define LIBAVCODEC_VERSION_MICRO 0 +#define LIBAVCODEC_VERSION_MICRO 1 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ @@ -116,5 +116,8 @@ #ifndef FF_API_OLD_DECODE_AUDIO #define FF_API_OLD_DECODE_AUDIO (LIBAVCODEC_VERSION_MAJOR < 54) #endif +#ifndef FF_API_AVFRAME_AGE +#define FF_API_AVFRAME_AGE (LIBAVCODEC_VERSION_MAJOR < 54) +#endif #endif /* AVCODEC_VERSION_H */ From 2a216ca2ef29282cac9003a716b469b8c80c0a15 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Sun, 18 Dec 2011 22:15:04 +0000 Subject: [PATCH 9/9] APIchanges: fill in revision for AVFrame.age deprecation Signed-off-by: Mans Rullgard --- doc/APIchanges | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/APIchanges b/doc/APIchanges index a7acc6d0c2..fa4e75e8e2 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,7 +13,7 @@ libavutil: 2011-04-18 API changes, most recent first: -2011-12-18 - xxxxxxx - lavc 53.28.1 +2011-12-18 - 8400b12 - lavc 53.28.1 Deprecate AVFrame.age. The field is unused. 2011-xx-xx - xxxxxxx - lavf 53.17.0