From db28b01dcf089f7f470def6b3a482a88908893d8 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 18 Jun 2012 12:57:25 +0100 Subject: [PATCH 01/24] dirac: replace compound literal with normal initialiser Signed-off-by: Mans Rullgard --- libavcodec/dirac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/dirac.c b/libavcodec/dirac.c index bf56088c75..07329e3f4d 100644 --- a/libavcodec/dirac.c +++ b/libavcodec/dirac.c @@ -108,7 +108,7 @@ static const enum PixelFormat dirac_pix_fmt[2][3] = { static int parse_source_parameters(AVCodecContext *avctx, GetBitContext *gb, dirac_source_params *source) { - AVRational frame_rate = (AVRational){0,0}; + AVRational frame_rate = {0,0}; unsigned luma_depth = 8, luma_offset = 16; int idx; From bbc8038614df85b608a11baaa2770f0d342d26fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 18 Jun 2012 16:19:33 +0300 Subject: [PATCH 02/24] rtsp: Send mode=record instead of mode=receive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This seems to be the correct mode to send, according to the original RTSP RFC, and matches the method RECORD which is sent later when starting to send data. Darwin Streaming Server works fine with either of them. Signed-off-by: Martin Storsjö --- libavformat/rtsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 19fdaf1c4b..a70ea04df2 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -1284,7 +1284,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, "%s/UDP;multicast", trans_pref); } if (s->oformat) { - av_strlcat(transport, ";mode=receive", sizeof(transport)); + av_strlcat(transport, ";mode=record", sizeof(transport)); } else if (rt->server_type == RTSP_SERVER_REAL || rt->server_type == RTSP_SERVER_WMS) av_strlcat(transport, ";mode=play", sizeof(transport)); From 46743a859ceb6b6bf4f0b1cbe26e5b311ed9eef4 Mon Sep 17 00:00:00 2001 From: Samuel Pitoiset Date: Mon, 18 Jun 2012 14:55:55 +0200 Subject: [PATCH 03/24] rtmp: Don't send every flv packet in a separate HTTP request in RTMPT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a new option 'rtmp_flush_interval' that allows specifying the number of packets to write before sending it off as a HTTP request. This is mostly relevant for RTMPT - for plain RTMP, it only controls how often we check the socket for incoming packets, which shouldn't affect the performance in any noticeable way. Signed-off-by: Martin Storsjö --- doc/protocols.texi | 4 ++++ libavformat/rtmpproto.c | 8 ++++++++ libavformat/version.h | 2 +- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/doc/protocols.texi b/doc/protocols.texi index 0b4f1b1772..e90d1b4a63 100644 --- a/doc/protocols.texi +++ b/doc/protocols.texi @@ -217,6 +217,10 @@ times to construct arbitrary AMF sequences. Version of the Flash plugin used to run the SWF player. The default is LNX 9,0,124,2. +@item rtmp_flush_interval +Number of packets flushed in the same request (RTMPT only). The default +is 10. + @item rtmp_live Specify that the media is a live stream. No resuming or seeking in live streams is possible. The default value is @code{any}, which means the diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index b3e2a30f48..b48274bdd8 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -76,6 +76,7 @@ typedef struct RTMPContext { uint8_t* flv_data; ///< buffer with data for demuxer int flv_size; ///< current buffer size int flv_off; ///< number of bytes read from current buffer + int flv_nb_packets; ///< number of flv packets published RTMPPacket out_pkt; ///< rtmp packet, created from flv a/v or metadata (for output) uint32_t client_report_size; ///< number of bytes after which client should report to server uint32_t bytes_read; ///< number of bytes read from server @@ -90,6 +91,7 @@ typedef struct RTMPContext { char* swfurl; ///< url of the swf player int server_bw; ///< server bandwidth int client_buffer_time; ///< client buffer time in ms + int flush_interval; ///< number of packets flushed in the same request (RTMPT only) } RTMPContext; #define PLAYER_KEY_OPEN_PART_LEN 30 ///< length of partial key used for first client digest signing @@ -1361,9 +1363,14 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size) rt->flv_size = 0; rt->flv_off = 0; rt->flv_header_bytes = 0; + rt->flv_nb_packets++; } } while (buf_temp - buf < size); + if (rt->flv_nb_packets < rt->flush_interval) + return size; + rt->flv_nb_packets = 0; + /* set stream into nonblocking mode */ rt->stream->flags |= AVIO_FLAG_NONBLOCK; @@ -1404,6 +1411,7 @@ static const AVOption rtmp_options[] = { {"rtmp_buffer", "Set buffer time in milliseconds. The default is 3000.", OFFSET(client_buffer_time), AV_OPT_TYPE_INT, {3000}, 0, INT_MAX, DEC|ENC}, {"rtmp_conn", "Append arbitrary AMF data to the Connect message", OFFSET(conn), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC}, {"rtmp_flashver", "Version of the Flash plugin used to run the SWF player.", OFFSET(flashver), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC}, + {"rtmp_flush_interval", "Number of packets flushed in the same request (RTMPT only).", OFFSET(flush_interval), AV_OPT_TYPE_INT, {10}, 0, INT_MAX, ENC}, {"rtmp_live", "Specify that the media is a live stream.", OFFSET(live), AV_OPT_TYPE_INT, {-2}, INT_MIN, INT_MAX, DEC, "rtmp_live"}, {"any", "both", 0, AV_OPT_TYPE_CONST, {-2}, 0, 0, DEC, "rtmp_live"}, {"live", "live stream", 0, AV_OPT_TYPE_CONST, {-1}, 0, 0, DEC, "rtmp_live"}, diff --git a/libavformat/version.h b/libavformat/version.h index e1703319b6..ecb59b893b 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -31,7 +31,7 @@ #define LIBAVFORMAT_VERSION_MAJOR 54 #define LIBAVFORMAT_VERSION_MINOR 4 -#define LIBAVFORMAT_VERSION_MICRO 1 +#define LIBAVFORMAT_VERSION_MICRO 2 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ From 3641b0489ce8517ae4ce75ea43c1445b6d1ad2f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 16 Jun 2012 00:42:13 +0300 Subject: [PATCH 04/24] Add support for iLBC decoding/encoding via the external library libilbc MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The library is 3-clause BSD licensed. Signed-off-by: Martin Storsjö --- Changelog | 1 + configure | 6 ++ doc/general.texi | 13 +++ libavcodec/Makefile | 2 + libavcodec/allcodecs.c | 1 + libavcodec/avcodec.h | 1 + libavcodec/libilbc.c | 209 +++++++++++++++++++++++++++++++++++++++++ libavcodec/utils.c | 5 + libavcodec/version.h | 2 +- 9 files changed, 239 insertions(+), 1 deletion(-) create mode 100644 libavcodec/libilbc.c diff --git a/Changelog b/Changelog index 4288aa3cc5..51b8c83764 100644 --- a/Changelog +++ b/Changelog @@ -26,6 +26,7 @@ version : - Indeo Audio decoder - channelsplit audio filter - RTMPT protocol support +- iLBC encoding/decoding via libilbc version 0.8: diff --git a/configure b/configure index a5d27870a2..ea80d480b2 100755 --- a/configure +++ b/configure @@ -172,6 +172,7 @@ External library support: --enable-libfaac enable FAAC support via libfaac [no] --enable-libfreetype enable libfreetype [no] --enable-libgsm enable GSM support via libgsm [no] + --enable-libilbc enable iLBC de/encoding via libilbc [no] --enable-libmp3lame enable MP3 encoding via libmp3lame [no] --enable-libopencore-amrnb enable AMR-NB de/encoding via libopencore-amrnb [no] --enable-libopencore-amrwb enable AMR-WB decoding via libopencore-amrwb [no] @@ -945,6 +946,7 @@ CONFIG_LIST=" libfaac libfreetype libgsm + libilbc libmp3lame libopencore_amrnb libopencore_amrwb @@ -1427,6 +1429,8 @@ libgsm_decoder_deps="libgsm" libgsm_encoder_deps="libgsm" libgsm_ms_decoder_deps="libgsm" libgsm_ms_encoder_deps="libgsm" +libilbc_decoder_deps="libilbc" +libilbc_encoder_deps="libilbc" libmp3lame_encoder_deps="libmp3lame" libopencore_amrnb_decoder_deps="libopencore_amrnb" libopencore_amrnb_encoder_deps="libopencore_amrnb" @@ -2917,6 +2921,7 @@ enabled gnutls && require_pkg_config gnutls gnutls/gnutls.h gnutls_global_in enabled libfaac && require2 libfaac "stdint.h faac.h" faacEncGetVersion -lfaac enabled libfreetype && require_pkg_config freetype2 "ft2build.h freetype/freetype.h" FT_Init_FreeType enabled libgsm && require libgsm gsm/gsm.h gsm_create -lgsm +enabled libilbc && require libilbc ilbc.h WebRtcIlbcfix_InitDecode -lilbc enabled libmp3lame && require "libmp3lame >= 3.98.3" lame/lame.h lame_set_VBR_quality -lmp3lame enabled libopencore_amrnb && require libopencore_amrnb opencore-amrnb/interf_dec.h Decoder_Interface_init -lopencore-amrnb enabled libopencore_amrwb && require libopencore_amrwb opencore-amrwb/dec_if.h D_IF_init -lopencore-amrwb @@ -3206,6 +3211,7 @@ echo "libcdio support ${libcdio-no}" echo "libdc1394 support ${libdc1394-no}" echo "libfaac enabled ${libfaac-no}" echo "libgsm enabled ${libgsm-no}" +echo "libilbc enabled ${libilbc-no}" echo "libmp3lame enabled ${libmp3lame-no}" echo "libopencore-amrnb support ${libopencore_amrnb-no}" echo "libopencore-amrwb support ${libopencore_amrwb-no}" diff --git a/doc/general.texi b/doc/general.texi index 9a4746a570..0c600ce948 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -85,6 +85,17 @@ x264 is under the GNU Public License Version 2 or later details), you must upgrade Libav's license to GPL in order to use it. @end float +@section libilbc + +iLBC is a narrowband speech codec that has been made freely available +by Google as part of the WebRTC project. libilbc is a packaging friendly +copy of the iLBC codec. Libav can make use of the libilbc library for +iLBC encoding and decoding. + +Go to @url{https://github.com/dekkers/libilbc} and follow the instructions for +installing the library. Then pass @code{--enable-libilbc} to configure to +enable it. + @chapter Supported File Formats and Codecs @@ -707,6 +718,8 @@ following image formats are supported: @item GSM Microsoft variant @tab E @tab X @tab encoding supported through external library libgsm @item IAC (Indeo Audio Coder) @tab @tab X +@item iLBC (Internet Low Bitrate Codec) @tab E @tab E + @tab encoding and decoding supported through external library libilbc @item IMC (Intel Music Coder) @tab @tab X @item MACE (Macintosh Audio Compression/Expansion) 3:1 @tab @tab X @item MACE (Macintosh Audio Compression/Expansion) 6:1 @tab @tab X diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 3bfd78bc63..c4f7e986fa 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -596,6 +596,8 @@ OBJS-$(CONFIG_LIBGSM_DECODER) += libgsm.o OBJS-$(CONFIG_LIBGSM_ENCODER) += libgsm.o OBJS-$(CONFIG_LIBGSM_MS_DECODER) += libgsm.o OBJS-$(CONFIG_LIBGSM_MS_ENCODER) += libgsm.o +OBJS-$(CONFIG_LIBILBC_DECODER) += libilbc.o +OBJS-$(CONFIG_LIBILBC_ENCODER) += libilbc.o OBJS-$(CONFIG_LIBMP3LAME_ENCODER) += libmp3lame.o mpegaudiodecheader.o \ audio_frame_queue.o OBJS-$(CONFIG_LIBOPENCORE_AMRNB_DECODER) += libopencore-amr.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 01d13d5348..a9d85e694f 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -379,6 +379,7 @@ void avcodec_register_all(void) REGISTER_ENCODER (LIBFAAC, libfaac); REGISTER_ENCDEC (LIBGSM, libgsm); REGISTER_ENCDEC (LIBGSM_MS, libgsm_ms); + REGISTER_ENCDEC (LIBILBC, libilbc); REGISTER_ENCODER (LIBMP3LAME, libmp3lame); REGISTER_ENCDEC (LIBOPENCORE_AMRNB, libopencore_amrnb); REGISTER_DECODER (LIBOPENCORE_AMRWB, libopencore_amrwb); diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 4a07d6dd57..94c2ed7655 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -394,6 +394,7 @@ enum CodecID { CODEC_ID_BMV_AUDIO, CODEC_ID_RALF, CODEC_ID_IAC, + CODEC_ID_ILBC, /* subtitle codecs */ CODEC_ID_FIRST_SUBTITLE = 0x17000, ///< A dummy ID pointing at the start of subtitle codecs. diff --git a/libavcodec/libilbc.c b/libavcodec/libilbc.c new file mode 100644 index 0000000000..1c056d5cd7 --- /dev/null +++ b/libavcodec/libilbc.c @@ -0,0 +1,209 @@ +/* + * iLBC decoder/encoder stub + * Copyright (c) 2012 Martin Storsjo + * + * 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 + +#include "avcodec.h" +#include "libavutil/opt.h" +#include "internal.h" + +static int get_mode(AVCodecContext *avctx) +{ + if (avctx->block_align == 38) + return 20; + else if (avctx->block_align == 50) + return 30; + else if (avctx->bit_rate > 0) + return avctx->bit_rate <= 14000 ? 30 : 20; + else + return -1; +} + +typedef struct ILBCDecContext { + const AVClass *class; + AVFrame frame; + iLBC_Dec_Inst_t decoder; + int enhance; +} ILBCDecContext; + +static const AVOption ilbc_dec_options[] = { + { "enhance", "Enhance the decoded audio (adds delay)", offsetof(ILBCDecContext, enhance), AV_OPT_TYPE_INT, { 0 }, 0, 1, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM }, + { NULL } +}; + +static const AVClass ilbc_dec_class = { + "libilbc", av_default_item_name, ilbc_dec_options, LIBAVUTIL_VERSION_INT +}; + +static av_cold int ilbc_decode_init(AVCodecContext *avctx) +{ + ILBCDecContext *s = avctx->priv_data; + int mode; + + if ((mode = get_mode(avctx)) < 0) { + av_log(avctx, AV_LOG_ERROR, "iLBC frame mode not indicated\n"); + return AVERROR(EINVAL); + } + + WebRtcIlbcfix_InitDecode(&s->decoder, mode, s->enhance); + avcodec_get_frame_defaults(&s->frame); + avctx->coded_frame = &s->frame; + + avctx->channels = 1; + avctx->sample_rate = 8000; + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + + return 0; +} + +static int ilbc_decode_frame(AVCodecContext *avctx, void *data, + int *got_frame_ptr, AVPacket *avpkt) +{ + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + ILBCDecContext *s = avctx->priv_data; + int ret; + + if (s->decoder.no_of_bytes > buf_size) { + av_log(avctx, AV_LOG_ERROR, "iLBC frame too short (%u, should be %u)\n", + buf_size, s->decoder.no_of_bytes); + return AVERROR_INVALIDDATA; + } + + s->frame.nb_samples = s->decoder.blockl; + if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return ret; + } + + WebRtcIlbcfix_DecodeImpl((WebRtc_Word16*) s->frame.data[0], + (const WebRtc_UWord16*) buf, &s->decoder, 1); + + *got_frame_ptr = 1; + *(AVFrame *)data = s->frame; + + return s->decoder.no_of_bytes; +} + +AVCodec ff_libilbc_decoder = { + .name = "libilbc", + .type = AVMEDIA_TYPE_AUDIO, + .id = CODEC_ID_ILBC, + .priv_data_size = sizeof(ILBCDecContext), + .init = ilbc_decode_init, + .decode = ilbc_decode_frame, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("Internet Low Bitrate Codec (iLBC)"), + .priv_class = &ilbc_dec_class, +}; + +typedef struct ILBCEncContext { + const AVClass *class; + iLBC_Enc_Inst_t encoder; + int mode; +} ILBCEncContext; + +static const AVOption ilbc_enc_options[] = { + { "mode", "iLBC mode (20 or 30 ms frames)", offsetof(ILBCEncContext, mode), AV_OPT_TYPE_INT, { 20 }, 20, 30, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, + { NULL } +}; + +static const AVClass ilbc_enc_class = { + "libilbc", av_default_item_name, ilbc_enc_options, LIBAVUTIL_VERSION_INT +}; + +static av_cold int ilbc_encode_init(AVCodecContext *avctx) +{ + ILBCEncContext *s = avctx->priv_data; + int mode; + + if (avctx->sample_rate != 8000) { + av_log(avctx, AV_LOG_ERROR, "Only 8000Hz sample rate supported\n"); + return AVERROR(EINVAL); + } + + if (avctx->channels != 1) { + av_log(avctx, AV_LOG_ERROR, "Only mono supported\n"); + return AVERROR(EINVAL); + } + + if ((mode = get_mode(avctx)) > 0) + s->mode = mode; + else + s->mode = s->mode != 30 ? 20 : 30; + WebRtcIlbcfix_InitEncode(&s->encoder, s->mode); + + avctx->block_align = s->encoder.no_of_bytes; + avctx->frame_size = s->encoder.blockl; +#if FF_API_OLD_ENCODE_AUDIO + avctx->coded_frame = avcodec_alloc_frame(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); +#endif + + return 0; +} + +static av_cold int ilbc_encode_close(AVCodecContext *avctx) +{ +#if FF_API_OLD_ENCODE_AUDIO + av_freep(&avctx->coded_frame); +#endif + return 0; +} + +static int ilbc_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, + const AVFrame *frame, int *got_packet_ptr) +{ + ILBCEncContext *s = avctx->priv_data; + int ret; + + if ((ret = ff_alloc_packet(avpkt, 50))) { + av_log(avctx, AV_LOG_ERROR, "Error getting output packet\n"); + return ret; + } + + WebRtcIlbcfix_EncodeImpl((WebRtc_UWord16*) avpkt->data, (const WebRtc_Word16*) frame->data[0], &s->encoder); + + avpkt->size = s->encoder.no_of_bytes; + *got_packet_ptr = 1; + return 0; +} + +static const AVCodecDefault ilbc_encode_defaults[] = { + { "b", "0" }, + { NULL } +}; + +AVCodec ff_libilbc_encoder = { + .name = "libilbc", + .type = AVMEDIA_TYPE_AUDIO, + .id = CODEC_ID_ILBC, + .priv_data_size = sizeof(ILBCEncContext), + .init = ilbc_encode_init, + .encode2 = ilbc_encode_frame, + .close = ilbc_encode_close, + .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16, + AV_SAMPLE_FMT_NONE }, + .long_name = NULL_IF_CONFIG_SMALL("Internet Low Bitrate Codec (iLBC)"), + .defaults = ilbc_encode_defaults, + .priv_class = &ilbc_enc_class, +}; diff --git a/libavcodec/utils.c b/libavcodec/utils.c index d2ee9f893b..514a1f5569 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -1832,6 +1832,11 @@ int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes) case 29: return 288; case 37: return 480; } + } else if (id == CODEC_ID_ILBC) { + switch (ba) { + case 38: return 160; + case 50: return 240; + } } } diff --git a/libavcodec/version.h b/libavcodec/version.h index e8f0b5cb84..46b0f2358d 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -27,7 +27,7 @@ */ #define LIBAVCODEC_VERSION_MAJOR 54 -#define LIBAVCODEC_VERSION_MINOR 14 +#define LIBAVCODEC_VERSION_MINOR 15 #define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ From 9e74db685063170d8f30191a17cd16769488d156 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 17 Jun 2012 00:29:26 +0300 Subject: [PATCH 05/24] mov: Support muxing/demuxing iLBC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The packet size, signalled via block_align, has to be passed via the container. Signed-off-by: Martin Storsjö --- libavformat/isom.c | 1 + libavformat/mov.c | 1 + libavformat/movenc.c | 3 ++- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/libavformat/isom.c b/libavformat/isom.c index 3ea8ce135a..e5cde5a366 100644 --- a/libavformat/isom.c +++ b/libavformat/isom.c @@ -244,6 +244,7 @@ const AVCodecTag ff_codec_movaudio_tags[] = { { CODEC_ID_DVAUDIO, MKTAG('v', 'd', 'v', 'a') }, { CODEC_ID_DVAUDIO, MKTAG('d', 'v', 'c', 'a') }, { CODEC_ID_GSM, MKTAG('a', 'g', 's', 'm') }, + { CODEC_ID_ILBC, MKTAG('i', 'l', 'b', 'c') }, { CODEC_ID_MACE3, MKTAG('M', 'A', 'C', '3') }, { CODEC_ID_MACE6, MKTAG('M', 'A', 'C', '6') }, { CODEC_ID_MP1, MKTAG('.', 'm', 'p', '1') }, diff --git a/libavformat/mov.c b/libavformat/mov.c index 1395259c5c..44dc2c821c 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1456,6 +1456,7 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries) case CODEC_ID_GSM: case CODEC_ID_ADPCM_MS: case CODEC_ID_ADPCM_IMA_WAV: + case CODEC_ID_ILBC: st->codec->block_align = sc->bytes_per_frame; break; case CODEC_ID_ALAC: diff --git a/libavformat/movenc.c b/libavformat/movenc.c index bf888bc3be..350ac951f6 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -3095,7 +3095,8 @@ static int mov_write_header(AVFormatContext *s) }else if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO){ track->timescale = st->codec->sample_rate; /* set sample_size for PCM and ADPCM */ - if (av_get_bits_per_sample(st->codec->codec_id)) { + if (av_get_bits_per_sample(st->codec->codec_id) || + st->codec->codec_id == CODEC_ID_ILBC) { if (!st->codec->block_align) { av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set\n", i); goto error; From a2b251a05e6f87bca826269d4baa5b8da7aeb430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 17 Jun 2012 15:54:31 +0300 Subject: [PATCH 06/24] Implement the iLBC storage file format MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- doc/general.texi | 1 + libavformat/Makefile | 2 + libavformat/allformats.c | 1 + libavformat/ilbc.c | 141 +++++++++++++++++++++++++++++++++++++++ libavformat/version.h | 4 +- 5 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 libavformat/ilbc.c diff --git a/doc/general.texi b/doc/general.texi index 0c600ce948..82a181c822 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -184,6 +184,7 @@ library: @item IEC61937 encapsulation @tab X @tab X @item IFF @tab @tab X @tab Interchange File Format +@item iLBC @tab X @tab X @item Interplay MVE @tab @tab X @tab Format used in various Interplay computer games. @item IV8 @tab @tab X diff --git a/libavformat/Makefile b/libavformat/Makefile index 6262324830..88e8db4c83 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -110,6 +110,8 @@ OBJS-$(CONFIG_H264_MUXER) += rawenc.o OBJS-$(CONFIG_HLS_DEMUXER) += hls.o OBJS-$(CONFIG_IDCIN_DEMUXER) += idcin.o OBJS-$(CONFIG_IFF_DEMUXER) += iff.o +OBJS-$(CONFIG_ILBC_DEMUXER) += ilbc.o +OBJS-$(CONFIG_ILBC_MUXER) += ilbc.o OBJS-$(CONFIG_IMAGE2_DEMUXER) += img2dec.o img2.o OBJS-$(CONFIG_IMAGE2_MUXER) += img2enc.o img2.o OBJS-$(CONFIG_IMAGE2PIPE_DEMUXER) += img2dec.o img2.o diff --git a/libavformat/allformats.c b/libavformat/allformats.c index 42c588f294..8456398cb5 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -108,6 +108,7 @@ void av_register_all(void) REGISTER_DEMUXER (HLS, hls); REGISTER_DEMUXER (IDCIN, idcin); REGISTER_DEMUXER (IFF, iff); + REGISTER_MUXDEMUX (ILBC, ilbc); REGISTER_MUXDEMUX (IMAGE2, image2); REGISTER_MUXDEMUX (IMAGE2PIPE, image2pipe); REGISTER_DEMUXER (INGENIENT, ingenient); diff --git a/libavformat/ilbc.c b/libavformat/ilbc.c new file mode 100644 index 0000000000..33aed77163 --- /dev/null +++ b/libavformat/ilbc.c @@ -0,0 +1,141 @@ +/* + * iLBC storage file format + * Copyright (c) 2012 Martin Storsjo + * + * 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 "internal.h" + +static const char mode20_header[] = "#!iLBC20\n"; +static const char mode30_header[] = "#!iLBC30\n"; + +static int ilbc_write_header(AVFormatContext *s) +{ + AVIOContext *pb = s->pb; + AVCodecContext *enc; + + if (s->nb_streams != 1) { + av_log(s, AV_LOG_ERROR, "Unsupported number of streams\n"); + return AVERROR(EINVAL); + } + enc = s->streams[0]->codec; + + if (enc->codec_id != CODEC_ID_ILBC) { + av_log(s, AV_LOG_ERROR, "Unsupported codec\n"); + return AVERROR(EINVAL); + } + + if (enc->block_align == 50) { + avio_write(pb, mode30_header, sizeof(mode30_header) - 1); + } else if (enc->block_align == 38) { + avio_write(pb, mode20_header, sizeof(mode20_header) - 1); + } else { + av_log(s, AV_LOG_ERROR, "Unsupported mode\n"); + return AVERROR(EINVAL); + } + avio_flush(pb); + return 0; +} + +static int ilbc_write_packet(AVFormatContext *s, AVPacket *pkt) +{ + avio_write(s->pb, pkt->data, pkt->size); + avio_flush(s->pb); + return 0; +} + +static int ilbc_probe(AVProbeData *p) +{ + // Only check for "#!iLBC" which matches both formats + if (!memcmp(p->buf, mode20_header, 6)) + return AVPROBE_SCORE_MAX; + else + return 0; +} + +static int ilbc_read_header(AVFormatContext *s) +{ + AVIOContext *pb = s->pb; + AVStream *st; + uint8_t header[9]; + + avio_read(pb, header, 9); + + st = avformat_new_stream(s, NULL); + if (!st) + return AVERROR(ENOMEM); + st->codec->codec_id = CODEC_ID_ILBC; + st->codec->sample_rate = 8000; + st->codec->channels = 1; + st->codec->codec_type = AVMEDIA_TYPE_AUDIO; + st->start_time = 0; + avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); + if (!memcmp(header, mode20_header, sizeof(mode20_header) - 1)) { + st->codec->block_align = 38; + st->codec->bit_rate = 15200; + } else if (!memcmp(header, mode30_header, sizeof(mode30_header) - 1)) { + st->codec->block_align = 50; + st->codec->bit_rate = 13333; + } else { + av_log(s, AV_LOG_ERROR, "Unrecognized iLBC file header\n"); + return AVERROR_INVALIDDATA; + } + + return 0; +} + +static int ilbc_read_packet(AVFormatContext *s, + AVPacket *pkt) +{ + AVCodecContext *enc = s->streams[0]->codec; + int ret; + + if ((ret = av_new_packet(pkt, enc->block_align)) < 0) + return ret; + + pkt->stream_index = 0; + pkt->pos = avio_tell(s->pb); + pkt->duration = enc->block_align == 38 ? 160 : 240; + if ((ret = avio_read(s->pb, pkt->data, enc->block_align)) != enc->block_align) { + av_free_packet(pkt); + return ret < 0 ? ret : AVERROR(EIO); + } + + return 0; +} + +AVInputFormat ff_ilbc_demuxer = { + .name = "ilbc", + .long_name = NULL_IF_CONFIG_SMALL("iLBC storage file format"), + .read_probe = ilbc_probe, + .read_header = ilbc_read_header, + .read_packet = ilbc_read_packet, + .flags = AVFMT_GENERIC_INDEX, +}; + +AVOutputFormat ff_ilbc_muxer = { + .name = "ilbc", + .long_name = NULL_IF_CONFIG_SMALL("iLBC storage file format"), + .mime_type = "audio/iLBC", + .extensions = "lbc", + .audio_codec = CODEC_ID_ILBC, + .write_header = ilbc_write_header, + .write_packet = ilbc_write_packet, + .flags = AVFMT_NOTIMESTAMPS, +}; diff --git a/libavformat/version.h b/libavformat/version.h index ecb59b893b..0db01fa175 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -30,8 +30,8 @@ #include "libavutil/avutil.h" #define LIBAVFORMAT_VERSION_MAJOR 54 -#define LIBAVFORMAT_VERSION_MINOR 4 -#define LIBAVFORMAT_VERSION_MICRO 2 +#define LIBAVFORMAT_VERSION_MINOR 5 +#define LIBAVFORMAT_VERSION_MICRO 0 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ From 89c3960544310c4e8b11f788638e13e63a0ee37b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 17 Jun 2012 16:12:53 +0300 Subject: [PATCH 07/24] rtpdec: Add a depacketizer for iLBC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/Makefile | 1 + libavformat/rtpdec.c | 1 + libavformat/rtpdec_formats.h | 1 + libavformat/rtpdec_ilbc.c | 73 ++++++++++++++++++++++++++++++++++++ libavformat/version.h | 2 +- 5 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 libavformat/rtpdec_ilbc.c diff --git a/libavformat/Makefile b/libavformat/Makefile index 88e8db4c83..f3f0372f8e 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -264,6 +264,7 @@ OBJS-$(CONFIG_RTPDEC) += rdt.o \ rtpdec_h263.o \ rtpdec_h263_rfc2190.o \ rtpdec_h264.o \ + rtpdec_ilbc.o \ rtpdec_latm.o \ rtpdec_mpeg4.o \ rtpdec_qcelp.o \ diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c index 41e6eb4cab..b3bce2408d 100644 --- a/libavformat/rtpdec.c +++ b/libavformat/rtpdec.c @@ -68,6 +68,7 @@ void av_register_rtp_dynamic_payload_handlers(void) ff_register_dynamic_payload_handler(&ff_h263_2000_dynamic_handler); ff_register_dynamic_payload_handler(&ff_h263_rfc2190_dynamic_handler); ff_register_dynamic_payload_handler(&ff_h264_dynamic_handler); + ff_register_dynamic_payload_handler(&ff_ilbc_dynamic_handler); ff_register_dynamic_payload_handler(&ff_vorbis_dynamic_handler); ff_register_dynamic_payload_handler(&ff_theora_dynamic_handler); ff_register_dynamic_payload_handler(&ff_qdm2_dynamic_handler); diff --git a/libavformat/rtpdec_formats.h b/libavformat/rtpdec_formats.h index 60edecb4ed..aaa18094d7 100644 --- a/libavformat/rtpdec_formats.h +++ b/libavformat/rtpdec_formats.h @@ -45,6 +45,7 @@ extern RTPDynamicProtocolHandler ff_h263_1998_dynamic_handler; extern RTPDynamicProtocolHandler ff_h263_2000_dynamic_handler; extern RTPDynamicProtocolHandler ff_h263_rfc2190_dynamic_handler; extern RTPDynamicProtocolHandler ff_h264_dynamic_handler; +extern RTPDynamicProtocolHandler ff_ilbc_dynamic_handler; extern RTPDynamicProtocolHandler ff_mp4a_latm_dynamic_handler; extern RTPDynamicProtocolHandler ff_mp4v_es_dynamic_handler; extern RTPDynamicProtocolHandler ff_mpeg4_generic_dynamic_handler; diff --git a/libavformat/rtpdec_ilbc.c b/libavformat/rtpdec_ilbc.c new file mode 100644 index 0000000000..7159dcf6be --- /dev/null +++ b/libavformat/rtpdec_ilbc.c @@ -0,0 +1,73 @@ +/* + * RTP iLBC Depacketizer, RFC 3952 + * Copyright (c) 2012 Martin Storsjo + * + * 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 "rtpdec_formats.h" +#include "libavutil/avstring.h" + +static int ilbc_parse_fmtp(AVStream *stream, PayloadContext *data, + char *attr, char *value) +{ + if (!strcmp(attr, "mode")) { + int mode = atoi(value); + switch (mode) { + case 20: + stream->codec->block_align = 38; + break; + case 30: + stream->codec->block_align = 50; + break; + default: + av_log(NULL, AV_LOG_ERROR, "Unsupported iLBC mode %d\n", mode); + return AVERROR(EINVAL); + } + } + return 0; +} + +static int ilbc_parse_sdp_line(AVFormatContext *s, int st_index, + PayloadContext *data, const char *line) +{ + const char *p; + AVStream *st; + + if (st_index < 0) + return 0; + st = s->streams[st_index]; + + if (av_strstart(line, "fmtp:", &p)) { + int ret = ff_parse_fmtp(st, data, p, ilbc_parse_fmtp); + if (ret < 0) + return ret; + if (!st->codec->block_align) { + av_log(s, AV_LOG_ERROR, "No iLBC mode set\n"); + return AVERROR(EINVAL); + } + } + return 0; +} + +RTPDynamicProtocolHandler ff_ilbc_dynamic_handler = { + .enc_name = "iLBC", + .codec_type = AVMEDIA_TYPE_AUDIO, + .codec_id = CODEC_ID_ILBC, + .parse_sdp_a_line = ilbc_parse_sdp_line, +}; diff --git a/libavformat/version.h b/libavformat/version.h index 0db01fa175..66a460dce3 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -31,7 +31,7 @@ #define LIBAVFORMAT_VERSION_MAJOR 54 #define LIBAVFORMAT_VERSION_MINOR 5 -#define LIBAVFORMAT_VERSION_MICRO 0 +#define LIBAVFORMAT_VERSION_MICRO 1 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ From 579fd87b46ccf8b126fed180a7194460fe55c016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 17 Jun 2012 17:25:46 +0300 Subject: [PATCH 08/24] rtpenc: Support packetizing iLBC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/rtpenc.c | 44 +++++++++++++++++++++++++++++++++++++++++++ libavformat/sdp.c | 6 ++++++ libavformat/version.h | 2 +- 3 files changed, 51 insertions(+), 1 deletion(-) diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c index 6752fb6f7e..9cf1a165d2 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -74,6 +74,7 @@ static int is_supported(enum CodecID id) case CODEC_ID_VP8: case CODEC_ID_ADPCM_G722: case CODEC_ID_ADPCM_G726: + case CODEC_ID_ILBC: return 1; default: return 0; @@ -187,6 +188,16 @@ static int rtp_write_header(AVFormatContext *s1) * 8000, even if the sample rate is 16000. See RFC 3551. */ avpriv_set_pts_info(st, 32, 1, 8000); break; + case CODEC_ID_ILBC: + if (st->codec->block_align != 38 && st->codec->block_align != 50) { + av_log(s1, AV_LOG_ERROR, "Incorrect iLBC block size specified\n"); + goto fail; + } + if (!s->max_frames_per_packet) + s->max_frames_per_packet = 1; + s->max_frames_per_packet = FFMIN(s->max_frames_per_packet, + s->max_payload_size / st->codec->block_align); + goto defaultcase; case CODEC_ID_AMR_NB: case CODEC_ID_AMR_WB: if (!s->max_frames_per_packet) @@ -395,6 +406,36 @@ static void rtp_send_mpegts_raw(AVFormatContext *s1, } } +static int rtp_send_ilbc(AVFormatContext *s1, const uint8_t *buf, int size) +{ + RTPMuxContext *s = s1->priv_data; + AVStream *st = s1->streams[0]; + int frame_duration = av_get_audio_frame_duration(st->codec, 0); + int frame_size = st->codec->block_align; + int frames = size / frame_size; + + while (frames > 0) { + int n = FFMIN(s->max_frames_per_packet - s->num_frames, frames); + + if (!s->num_frames) { + s->buf_ptr = s->buf; + s->timestamp = s->cur_timestamp; + } + memcpy(s->buf_ptr, buf, n * frame_size); + frames -= n; + s->num_frames += n; + s->buf_ptr += n * frame_size; + buf += n * frame_size; + s->cur_timestamp += n * frame_duration; + + if (s->num_frames == s->max_frames_per_packet) { + ff_rtp_send_data(s1, s->buf, s->buf_ptr - s->buf, 1); + s->num_frames = 0; + } + } + return 0; +} + static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt) { RTPMuxContext *s = s1->priv_data; @@ -483,6 +524,9 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt) case CODEC_ID_VP8: ff_rtp_send_vp8(s1, pkt->data, size); break; + case CODEC_ID_ILBC: + rtp_send_ilbc(s1, pkt->data, size); + break; default: /* better than nothing : send the codec raw data */ rtp_send_raw(s1, pkt->data, size); diff --git a/libavformat/sdp.c b/libavformat/sdp.c index 7df8b13b67..1867225f71 100644 --- a/libavformat/sdp.c +++ b/libavformat/sdp.c @@ -549,6 +549,12 @@ static char *sdp_write_media_attributes(char *buff, int size, AVCodecContext *c, c->sample_rate); break; } + case CODEC_ID_ILBC: + av_strlcatf(buff, size, "a=rtpmap:%d iLBC/%d\r\n" + "a=fmtp:%d mode=%d\r\n", + payload_type, c->sample_rate, + payload_type, c->block_align == 38 ? 20 : 30); + break; default: /* Nothing special to do here... */ break; diff --git a/libavformat/version.h b/libavformat/version.h index 66a460dce3..2216e4eabd 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -31,7 +31,7 @@ #define LIBAVFORMAT_VERSION_MAJOR 54 #define LIBAVFORMAT_VERSION_MINOR 5 -#define LIBAVFORMAT_VERSION_MICRO 1 +#define LIBAVFORMAT_VERSION_MICRO 2 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ LIBAVFORMAT_VERSION_MINOR, \ From 1168e29df13c3d8694e3285b126e16063d2dfd67 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 20 Apr 2012 15:48:08 -0400 Subject: [PATCH 09/24] lavr: Add x86-optimized function for s16 to s32 conversion --- libavresample/x86/audio_convert.asm | 23 +++++++++++++++++++++++ libavresample/x86/audio_convert_init.c | 6 ++++++ 2 files changed, 29 insertions(+) diff --git a/libavresample/x86/audio_convert.asm b/libavresample/x86/audio_convert.asm index ba59f3314f..e2cfbf950c 100644 --- a/libavresample/x86/audio_convert.asm +++ b/libavresample/x86/audio_convert.asm @@ -1,6 +1,7 @@ ;****************************************************************************** ;* x86 optimized Format Conversion Utils ;* Copyright (c) 2008 Loren Merritt +;* Copyright (c) 2012 Justin Ruggles ;* ;* This file is part of Libav. ;* @@ -24,6 +25,28 @@ SECTION_TEXT +;------------------------------------------------------------------------------ +; void ff_conv_s16_to_s32(int32_t *dst, const int16_t *src, int len); +;------------------------------------------------------------------------------ + +INIT_XMM sse2 +cglobal conv_s16_to_s32, 3,3,3, dst, src, len + lea lenq, [2*lend] + lea dstq, [dstq+2*lenq] + add srcq, lenq + neg lenq +.loop: + mova m2, [srcq+lenq] + pxor m0, m0 + pxor m1, m1 + punpcklwd m0, m2 + punpckhwd m1, m2 + mova [dstq+2*lenq ], m0 + mova [dstq+2*lenq+mmsize], m1 + add lenq, mmsize + jl .loop + REP_RET + ;----------------------------------------------------------------------------- ; void ff_conv_fltp_to_flt_6ch(float *dst, float *const *src, int len, ; int channels); diff --git a/libavresample/x86/audio_convert_init.c b/libavresample/x86/audio_convert_init.c index 206aede751..a1dac7efe5 100644 --- a/libavresample/x86/audio_convert_init.c +++ b/libavresample/x86/audio_convert_init.c @@ -22,6 +22,8 @@ #include "libavutil/cpu.h" #include "libavresample/audio_convert.h" +extern void ff_conv_s16_to_s32_sse2(int16_t *dst, const int32_t *src, int len); + extern void ff_conv_fltp_to_flt_6ch_mmx (float *dst, float *const *src, int len); extern void ff_conv_fltp_to_flt_6ch_sse4(float *dst, float *const *src, int len); extern void ff_conv_fltp_to_flt_6ch_avx (float *dst, float *const *src, int len); @@ -43,5 +45,9 @@ av_cold void ff_audio_convert_init_x86(AudioConvert *ac) ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP, 6, 16, 4, "AVX", ff_conv_fltp_to_flt_6ch_avx); } + if (mm_flags & AV_CPU_FLAG_SSE2 && HAVE_SSE) { + ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16, + 0, 16, 8, "SSE2", ff_conv_s16_to_s32_sse2); + } #endif } From d721f67d0a7faff2cc501f186ef78e6b01394d59 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 23 Apr 2012 22:10:26 -0400 Subject: [PATCH 10/24] lavr: Add x86-optimized functions for s16 to flt conversion --- libavresample/x86/audio_convert.asm | 36 ++++++++++++++++++++++++++ libavresample/x86/audio_convert_init.c | 9 +++++++ 2 files changed, 45 insertions(+) diff --git a/libavresample/x86/audio_convert.asm b/libavresample/x86/audio_convert.asm index e2cfbf950c..6e14892928 100644 --- a/libavresample/x86/audio_convert.asm +++ b/libavresample/x86/audio_convert.asm @@ -22,6 +22,11 @@ %include "x86inc.asm" %include "x86util.asm" +%include "util.asm" + +SECTION_RODATA 32 + +pf_s16_inv_scale: times 4 dd 0x38000000 SECTION_TEXT @@ -47,6 +52,37 @@ cglobal conv_s16_to_s32, 3,3,3, dst, src, len jl .loop REP_RET +;------------------------------------------------------------------------------ +; void ff_conv_s16_to_flt(float *dst, const int16_t *src, int len); +;------------------------------------------------------------------------------ + +%macro CONV_S16_TO_FLT 0 +cglobal conv_s16_to_flt, 3,3,3, dst, src, len + lea lenq, [2*lend] + add srcq, lenq + lea dstq, [dstq + 2*lenq] + neg lenq + mova m2, [pf_s16_inv_scale] + ALIGN 16 +.loop: + mova m0, [srcq+lenq] + S16_TO_S32_SX 0, 1 + cvtdq2ps m0, m0 + cvtdq2ps m1, m1 + mulps m0, m2 + mulps m1, m2 + mova [dstq+2*lenq ], m0 + mova [dstq+2*lenq+mmsize], m1 + add lenq, mmsize + jl .loop + REP_RET +%endmacro + +INIT_XMM sse2 +CONV_S16_TO_FLT +INIT_XMM sse4 +CONV_S16_TO_FLT + ;----------------------------------------------------------------------------- ; void ff_conv_fltp_to_flt_6ch(float *dst, float *const *src, int len, ; int channels); diff --git a/libavresample/x86/audio_convert_init.c b/libavresample/x86/audio_convert_init.c index a1dac7efe5..2488cd3724 100644 --- a/libavresample/x86/audio_convert_init.c +++ b/libavresample/x86/audio_convert_init.c @@ -24,6 +24,9 @@ extern void ff_conv_s16_to_s32_sse2(int16_t *dst, const int32_t *src, int len); +extern void ff_conv_s16_to_flt_sse2(float *dst, const int16_t *src, int len); +extern void ff_conv_s16_to_flt_sse4(float *dst, const int16_t *src, int len); + extern void ff_conv_fltp_to_flt_6ch_mmx (float *dst, float *const *src, int len); extern void ff_conv_fltp_to_flt_6ch_sse4(float *dst, float *const *src, int len); extern void ff_conv_fltp_to_flt_6ch_avx (float *dst, float *const *src, int len); @@ -48,6 +51,12 @@ av_cold void ff_audio_convert_init_x86(AudioConvert *ac) if (mm_flags & AV_CPU_FLAG_SSE2 && HAVE_SSE) { ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16, 0, 16, 8, "SSE2", ff_conv_s16_to_s32_sse2); + ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, + 0, 16, 8, "SSE2", ff_conv_s16_to_flt_sse2); + } + if (mm_flags & AV_CPU_FLAG_SSE4 && HAVE_SSE) { + ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, + 0, 16, 8, "SSE4", ff_conv_s16_to_flt_sse4); } #endif } From 5904f25b9f0bc5d79685b37c9befb8d12e430352 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 20 Apr 2012 13:49:53 -0400 Subject: [PATCH 11/24] lavr: Add x86-optimized functions for s32 to s16 conversion --- libavresample/x86/audio_convert.asm | 38 ++++++++++++++++++++++++++ libavresample/x86/audio_convert_init.c | 9 ++++++ 2 files changed, 47 insertions(+) diff --git a/libavresample/x86/audio_convert.asm b/libavresample/x86/audio_convert.asm index 6e14892928..8435edefb0 100644 --- a/libavresample/x86/audio_convert.asm +++ b/libavresample/x86/audio_convert.asm @@ -83,6 +83,44 @@ CONV_S16_TO_FLT INIT_XMM sse4 CONV_S16_TO_FLT +;------------------------------------------------------------------------------ +; void ff_conv_s32_to_s16(int16_t *dst, const int32_t *src, int len); +;------------------------------------------------------------------------------ + +%macro CONV_S32_TO_S16 0 +cglobal conv_s32_to_s16, 3,3,4, dst, src, len + lea lenq, [2*lend] + lea srcq, [srcq+2*lenq] + add dstq, lenq + neg lenq +.loop: + mova m0, [srcq+2*lenq ] + mova m1, [srcq+2*lenq+ mmsize] + mova m2, [srcq+2*lenq+2*mmsize] + mova m3, [srcq+2*lenq+3*mmsize] + psrad m0, 16 + psrad m1, 16 + psrad m2, 16 + psrad m3, 16 + packssdw m0, m1 + packssdw m2, m3 + mova [dstq+lenq ], m0 + mova [dstq+lenq+mmsize], m2 + add lenq, mmsize*2 + jl .loop +%if mmsize == 8 + emms + RET +%else + REP_RET +%endif +%endmacro + +INIT_MMX mmx +CONV_S32_TO_S16 +INIT_XMM sse2 +CONV_S32_TO_S16 + ;----------------------------------------------------------------------------- ; void ff_conv_fltp_to_flt_6ch(float *dst, float *const *src, int len, ; int channels); diff --git a/libavresample/x86/audio_convert_init.c b/libavresample/x86/audio_convert_init.c index 2488cd3724..c4fe3aee07 100644 --- a/libavresample/x86/audio_convert_init.c +++ b/libavresample/x86/audio_convert_init.c @@ -27,6 +27,9 @@ extern void ff_conv_s16_to_s32_sse2(int16_t *dst, const int32_t *src, int len); extern void ff_conv_s16_to_flt_sse2(float *dst, const int16_t *src, int len); extern void ff_conv_s16_to_flt_sse4(float *dst, const int16_t *src, int len); +extern void ff_conv_s32_to_s16_mmx (int16_t *dst, const int32_t *src, int len); +extern void ff_conv_s32_to_s16_sse2(int16_t *dst, const int32_t *src, int len); + extern void ff_conv_fltp_to_flt_6ch_mmx (float *dst, float *const *src, int len); extern void ff_conv_fltp_to_flt_6ch_sse4(float *dst, float *const *src, int len); extern void ff_conv_fltp_to_flt_6ch_avx (float *dst, float *const *src, int len); @@ -37,6 +40,8 @@ av_cold void ff_audio_convert_init_x86(AudioConvert *ac) int mm_flags = av_get_cpu_flags(); if (mm_flags & AV_CPU_FLAG_MMX && HAVE_MMX) { + ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, + 0, 1, 8, "MMX", ff_conv_s32_to_s16_mmx); ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_FLTP, 6, 1, 4, "MMX", ff_conv_fltp_to_flt_6ch_mmx); } @@ -49,6 +54,10 @@ av_cold void ff_audio_convert_init_x86(AudioConvert *ac) 6, 16, 4, "AVX", ff_conv_fltp_to_flt_6ch_avx); } if (mm_flags & AV_CPU_FLAG_SSE2 && HAVE_SSE) { + if (!(mm_flags & AV_CPU_FLAG_SSE2SLOW)) { + ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, + 0, 16, 16, "SSE2", ff_conv_s32_to_s16_sse2); + } ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_S16, 0, 16, 8, "SSE2", ff_conv_s16_to_s32_sse2); ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, From 97ce1ba8673636c96d3cc002bb76221c60324d95 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 23 Apr 2012 18:29:58 -0400 Subject: [PATCH 12/24] lavr: Add x86-optimized functions for s32 to flt conversion --- libavresample/x86/audio_convert.asm | 37 ++++++++++++++++++++++++++ libavresample/x86/audio_convert_init.c | 9 +++++++ 2 files changed, 46 insertions(+) diff --git a/libavresample/x86/audio_convert.asm b/libavresample/x86/audio_convert.asm index 8435edefb0..53091acf99 100644 --- a/libavresample/x86/audio_convert.asm +++ b/libavresample/x86/audio_convert.asm @@ -26,6 +26,7 @@ SECTION_RODATA 32 +pf_s32_inv_scale: times 8 dd 0x30000000 pf_s16_inv_scale: times 4 dd 0x38000000 SECTION_TEXT @@ -121,6 +122,42 @@ CONV_S32_TO_S16 INIT_XMM sse2 CONV_S32_TO_S16 +;------------------------------------------------------------------------------ +; void ff_conv_s32_to_flt(float *dst, const int32_t *src, int len); +;------------------------------------------------------------------------------ + +%macro CONV_S32_TO_FLT 0 +cglobal conv_s32_to_flt, 3,3,3, dst, src, len + lea lenq, [4*lend] + add srcq, lenq + add dstq, lenq + neg lenq + mova m0, [pf_s32_inv_scale] + ALIGN 16 +.loop: + cvtdq2ps m1, [srcq+lenq ] + cvtdq2ps m2, [srcq+lenq+mmsize] + mulps m1, m1, m0 + mulps m2, m2, m0 + mova [dstq+lenq ], m1 + mova [dstq+lenq+mmsize], m2 + add lenq, mmsize*2 + jl .loop +%if mmsize == 32 + vzeroupper + RET +%else + REP_RET +%endif +%endmacro + +INIT_XMM sse2 +CONV_S32_TO_FLT +%if HAVE_AVX +INIT_YMM avx +CONV_S32_TO_FLT +%endif + ;----------------------------------------------------------------------------- ; void ff_conv_fltp_to_flt_6ch(float *dst, float *const *src, int len, ; int channels); diff --git a/libavresample/x86/audio_convert_init.c b/libavresample/x86/audio_convert_init.c index c4fe3aee07..f0a1a1a55f 100644 --- a/libavresample/x86/audio_convert_init.c +++ b/libavresample/x86/audio_convert_init.c @@ -30,6 +30,9 @@ extern void ff_conv_s16_to_flt_sse4(float *dst, const int16_t *src, int len); extern void ff_conv_s32_to_s16_mmx (int16_t *dst, const int32_t *src, int len); extern void ff_conv_s32_to_s16_sse2(int16_t *dst, const int32_t *src, int len); +extern void ff_conv_s32_to_flt_sse2(float *dst, const int32_t *src, int len); +extern void ff_conv_s32_to_flt_avx (float *dst, const int32_t *src, int len); + extern void ff_conv_fltp_to_flt_6ch_mmx (float *dst, float *const *src, int len); extern void ff_conv_fltp_to_flt_6ch_sse4(float *dst, float *const *src, int len); extern void ff_conv_fltp_to_flt_6ch_avx (float *dst, float *const *src, int len); @@ -62,10 +65,16 @@ av_cold void ff_audio_convert_init_x86(AudioConvert *ac) 0, 16, 8, "SSE2", ff_conv_s16_to_s32_sse2); ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, 0, 16, 8, "SSE2", ff_conv_s16_to_flt_sse2); + ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32, + 0, 16, 8, "SSE2", ff_conv_s32_to_flt_sse2); } if (mm_flags & AV_CPU_FLAG_SSE4 && HAVE_SSE) { ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, 0, 16, 8, "SSE4", ff_conv_s16_to_flt_sse4); } + if (mm_flags & AV_CPU_FLAG_AVX && HAVE_AVX) { + ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32, + 0, 32, 16, "AVX", ff_conv_s32_to_flt_avx); + } #endif } From 6c63cbfe7aa24f37064e2384f9b39431a91bfb29 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 23 Apr 2012 22:22:28 -0400 Subject: [PATCH 13/24] lavr: Add x86-optimized function for flt to s16 conversion --- libavresample/x86/audio_convert.asm | 33 ++++++++++++++++++++++++++ libavresample/x86/audio_convert_init.c | 4 ++++ 2 files changed, 37 insertions(+) diff --git a/libavresample/x86/audio_convert.asm b/libavresample/x86/audio_convert.asm index 53091acf99..a28198197f 100644 --- a/libavresample/x86/audio_convert.asm +++ b/libavresample/x86/audio_convert.asm @@ -28,6 +28,7 @@ SECTION_RODATA 32 pf_s32_inv_scale: times 8 dd 0x30000000 pf_s16_inv_scale: times 4 dd 0x38000000 +pf_s16_scale: times 4 dd 0x47000000 SECTION_TEXT @@ -158,6 +159,38 @@ INIT_YMM avx CONV_S32_TO_FLT %endif +;------------------------------------------------------------------------------ +; void ff_conv_flt_to_s16(int16_t *dst, const float *src, int len); +;------------------------------------------------------------------------------ + +INIT_XMM sse2 +cglobal conv_flt_to_s16, 3,3,5, dst, src, len + lea lenq, [2*lend] + lea srcq, [srcq+2*lenq] + add dstq, lenq + neg lenq + mova m4, [pf_s16_scale] +.loop: + mova m0, [srcq+2*lenq ] + mova m1, [srcq+2*lenq+1*mmsize] + mova m2, [srcq+2*lenq+2*mmsize] + mova m3, [srcq+2*lenq+3*mmsize] + mulps m0, m4 + mulps m1, m4 + mulps m2, m4 + mulps m3, m4 + cvtps2dq m0, m0 + cvtps2dq m1, m1 + cvtps2dq m2, m2 + cvtps2dq m3, m3 + packssdw m0, m1 + packssdw m2, m3 + mova [dstq+lenq ], m0 + mova [dstq+lenq+mmsize], m2 + add lenq, mmsize*2 + jl .loop + REP_RET + ;----------------------------------------------------------------------------- ; void ff_conv_fltp_to_flt_6ch(float *dst, float *const *src, int len, ; int channels); diff --git a/libavresample/x86/audio_convert_init.c b/libavresample/x86/audio_convert_init.c index f0a1a1a55f..1b2f93c1da 100644 --- a/libavresample/x86/audio_convert_init.c +++ b/libavresample/x86/audio_convert_init.c @@ -33,6 +33,8 @@ extern void ff_conv_s32_to_s16_sse2(int16_t *dst, const int32_t *src, int len); extern void ff_conv_s32_to_flt_sse2(float *dst, const int32_t *src, int len); extern void ff_conv_s32_to_flt_avx (float *dst, const int32_t *src, int len); +extern void ff_conv_flt_to_s16_sse2(int16_t *dst, const float *src, int len); + extern void ff_conv_fltp_to_flt_6ch_mmx (float *dst, float *const *src, int len); extern void ff_conv_fltp_to_flt_6ch_sse4(float *dst, float *const *src, int len); extern void ff_conv_fltp_to_flt_6ch_avx (float *dst, float *const *src, int len); @@ -67,6 +69,8 @@ av_cold void ff_audio_convert_init_x86(AudioConvert *ac) 0, 16, 8, "SSE2", ff_conv_s16_to_flt_sse2); ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32, 0, 16, 8, "SSE2", ff_conv_s32_to_flt_sse2); + ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT, + 0, 16, 16, "SSE2", ff_conv_flt_to_s16_sse2); } if (mm_flags & AV_CPU_FLAG_SSE4 && HAVE_SSE) { ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, From 4e4dd7173023502b5b3e7c3d7ccd7e6fe45b7afe Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 20 Apr 2012 16:09:15 -0400 Subject: [PATCH 14/24] lavr: Add x86-optimized function for flt to s32 conversion --- libavresample/x86/audio_convert.asm | 42 ++++++++++++++++++++++++++ libavresample/x86/audio_convert_init.c | 7 +++++ 2 files changed, 49 insertions(+) diff --git a/libavresample/x86/audio_convert.asm b/libavresample/x86/audio_convert.asm index a28198197f..7b3cc223c7 100644 --- a/libavresample/x86/audio_convert.asm +++ b/libavresample/x86/audio_convert.asm @@ -27,6 +27,7 @@ SECTION_RODATA 32 pf_s32_inv_scale: times 8 dd 0x30000000 +pf_s32_scale: times 8 dd 0x4f000000 pf_s16_inv_scale: times 4 dd 0x38000000 pf_s16_scale: times 4 dd 0x47000000 @@ -191,6 +192,47 @@ cglobal conv_flt_to_s16, 3,3,5, dst, src, len jl .loop REP_RET +;------------------------------------------------------------------------------ +; void ff_conv_flt_to_s32(int32_t *dst, const float *src, int len); +;------------------------------------------------------------------------------ + +%macro CONV_FLT_TO_S32 0 +cglobal conv_flt_to_s32, 3,3,5, dst, src, len + lea lenq, [lend*4] + add srcq, lenq + add dstq, lenq + neg lenq + mova m4, [pf_s32_scale] +.loop: + mulps m0, m4, [srcq+lenq ] + mulps m1, m4, [srcq+lenq+1*mmsize] + mulps m2, m4, [srcq+lenq+2*mmsize] + mulps m3, m4, [srcq+lenq+3*mmsize] + cvtps2dq m0, m0 + cvtps2dq m1, m1 + cvtps2dq m2, m2 + cvtps2dq m3, m3 + mova [dstq+lenq ], m0 + mova [dstq+lenq+1*mmsize], m1 + mova [dstq+lenq+2*mmsize], m2 + mova [dstq+lenq+3*mmsize], m3 + add lenq, mmsize*4 + jl .loop +%if mmsize == 32 + vzeroupper + RET +%else + REP_RET +%endif +%endmacro + +INIT_XMM sse2 +CONV_FLT_TO_S32 +%if HAVE_AVX +INIT_YMM avx +CONV_FLT_TO_S32 +%endif + ;----------------------------------------------------------------------------- ; void ff_conv_fltp_to_flt_6ch(float *dst, float *const *src, int len, ; int channels); diff --git a/libavresample/x86/audio_convert_init.c b/libavresample/x86/audio_convert_init.c index 1b2f93c1da..f41d974445 100644 --- a/libavresample/x86/audio_convert_init.c +++ b/libavresample/x86/audio_convert_init.c @@ -35,6 +35,9 @@ extern void ff_conv_s32_to_flt_avx (float *dst, const int32_t *src, int len); extern void ff_conv_flt_to_s16_sse2(int16_t *dst, const float *src, int len); +extern void ff_conv_flt_to_s32_sse2(int32_t *dst, const float *src, int len); +extern void ff_conv_flt_to_s32_avx (int32_t *dst, const float *src, int len); + extern void ff_conv_fltp_to_flt_6ch_mmx (float *dst, float *const *src, int len); extern void ff_conv_fltp_to_flt_6ch_sse4(float *dst, float *const *src, int len); extern void ff_conv_fltp_to_flt_6ch_avx (float *dst, float *const *src, int len); @@ -71,6 +74,8 @@ av_cold void ff_audio_convert_init_x86(AudioConvert *ac) 0, 16, 8, "SSE2", ff_conv_s32_to_flt_sse2); ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLT, 0, 16, 16, "SSE2", ff_conv_flt_to_s16_sse2); + ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT, + 0, 16, 16, "SSE2", ff_conv_flt_to_s32_sse2); } if (mm_flags & AV_CPU_FLAG_SSE4 && HAVE_SSE) { ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S16, @@ -79,6 +84,8 @@ av_cold void ff_audio_convert_init_x86(AudioConvert *ac) if (mm_flags & AV_CPU_FLAG_AVX && HAVE_AVX) { ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_S32, 0, 32, 16, "AVX", ff_conv_s32_to_flt_avx); + ff_audio_convert_set_func(ac, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT, + 0, 32, 32, "AVX", ff_conv_flt_to_s32_avx); } #endif } From cb5042d02c66aed68643633446f6bf623b72416e Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 8 Jun 2012 13:49:56 -0400 Subject: [PATCH 15/24] float_dsp: Move vector_fmac_scalar() from libavcodec to libavutil --- libavcodec/arm/dsputil_init_neon.c | 3 -- libavcodec/arm/dsputil_neon.S | 48 ----------------------------- libavcodec/dca.c | 9 +++--- libavcodec/dsputil.c | 9 ------ libavcodec/dsputil.h | 11 ------- libavutil/arm/float_dsp_init_neon.c | 4 +++ libavutil/arm/float_dsp_neon.S | 48 +++++++++++++++++++++++++++++ libavutil/float_dsp.c | 9 ++++++ libavutil/float_dsp.h | 16 ++++++++++ 9 files changed, 82 insertions(+), 75 deletions(-) diff --git a/libavcodec/arm/dsputil_init_neon.c b/libavcodec/arm/dsputil_init_neon.c index 398326c8c8..65db20d2b3 100644 --- a/libavcodec/arm/dsputil_init_neon.c +++ b/libavcodec/arm/dsputil_init_neon.c @@ -154,8 +154,6 @@ void ff_vector_fmul_window_neon(float *dst, const float *src0, const float *src1, const float *win, int len); void ff_vector_fmul_scalar_neon(float *dst, const float *src, float mul, int len); -void ff_vector_fmac_scalar_neon(float *dst, const float *src, float mul, - int len); void ff_butterflies_float_neon(float *v1, float *v2, int len); float ff_scalarproduct_float_neon(const float *v1, const float *v2, int len); void ff_vector_fmul_reverse_neon(float *dst, const float *src0, @@ -329,7 +327,6 @@ void ff_dsputil_init_neon(DSPContext *c, AVCodecContext *avctx) c->vector_fmul_window = ff_vector_fmul_window_neon; c->vector_fmul_scalar = ff_vector_fmul_scalar_neon; - c->vector_fmac_scalar = ff_vector_fmac_scalar_neon; c->butterflies_float = ff_butterflies_float_neon; c->scalarproduct_float = ff_scalarproduct_float_neon; c->vector_fmul_reverse = ff_vector_fmul_reverse_neon; diff --git a/libavcodec/arm/dsputil_neon.S b/libavcodec/arm/dsputil_neon.S index 9a5a40d6ac..358ed61299 100644 --- a/libavcodec/arm/dsputil_neon.S +++ b/libavcodec/arm/dsputil_neon.S @@ -682,54 +682,6 @@ NOVFP vdup.32 q8, r2 .unreq len endfunc -function ff_vector_fmac_scalar_neon, export=1 -VFP len .req r2 -VFP acc .req r3 -NOVFP len .req r3 -NOVFP acc .req r2 -VFP vdup.32 q15, d0[0] -NOVFP vdup.32 q15, r2 - bics r12, len, #15 - mov acc, r0 - beq 3f - vld1.32 {q0}, [r1,:128]! - vld1.32 {q8}, [acc,:128]! - vld1.32 {q1}, [r1,:128]! - vld1.32 {q9}, [acc,:128]! -1: vmla.f32 q8, q0, q15 - vld1.32 {q2}, [r1,:128]! - vld1.32 {q10}, [acc,:128]! - vmla.f32 q9, q1, q15 - vld1.32 {q3}, [r1,:128]! - vld1.32 {q11}, [acc,:128]! - vmla.f32 q10, q2, q15 - vst1.32 {q8}, [r0,:128]! - vmla.f32 q11, q3, q15 - vst1.32 {q9}, [r0,:128]! - subs r12, r12, #16 - beq 2f - vld1.32 {q0}, [r1,:128]! - vld1.32 {q8}, [acc,:128]! - vst1.32 {q10}, [r0,:128]! - vld1.32 {q1}, [r1,:128]! - vld1.32 {q9}, [acc,:128]! - vst1.32 {q11}, [r0,:128]! - b 1b -2: vst1.32 {q10}, [r0,:128]! - vst1.32 {q11}, [r0,:128]! - ands len, len, #15 - it eq - bxeq lr -3: vld1.32 {q0}, [r1,:128]! - vld1.32 {q8}, [acc,:128]! - vmla.f32 q8, q0, q15 - vst1.32 {q8}, [r0,:128]! - subs len, len, #4 - bgt 3b - bx lr - .unreq len -endfunc - function ff_butterflies_float_neon, export=1 1: vld1.32 {q0},[r0,:128] vld1.32 {q1},[r1,:128] diff --git a/libavcodec/dca.c b/libavcodec/dca.c index 103f0588e3..b37dc49d3f 100644 --- a/libavcodec/dca.c +++ b/libavcodec/dca.c @@ -27,6 +27,7 @@ #include #include "libavutil/common.h" +#include "libavutil/float_dsp.h" #include "libavutil/intmath.h" #include "libavutil/intreadwrite.h" #include "libavutil/mathematics.h" @@ -383,7 +384,7 @@ typedef struct { int profile; int debug_flag; ///< used for suppressing repeated error messages output - DSPContext dsp; + AVFloatDSPContext fdsp; FFTContext imdct; SynthFilterContext synth; DCADSPContext dcadsp; @@ -1865,8 +1866,8 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, float *back_chan = s->samples + s->channel_order_tab[s->xch_base_channel] * 256; float *lt_chan = s->samples + s->channel_order_tab[s->xch_base_channel - 2] * 256; float *rt_chan = s->samples + s->channel_order_tab[s->xch_base_channel - 1] * 256; - s->dsp.vector_fmac_scalar(lt_chan, back_chan, -M_SQRT1_2, 256); - s->dsp.vector_fmac_scalar(rt_chan, back_chan, -M_SQRT1_2, 256); + s->fdsp.vector_fmac_scalar(lt_chan, back_chan, -M_SQRT1_2, 256); + s->fdsp.vector_fmac_scalar(rt_chan, back_chan, -M_SQRT1_2, 256); } if (avctx->sample_fmt == AV_SAMPLE_FMT_FLT) { @@ -1908,7 +1909,7 @@ static av_cold int dca_decode_init(AVCodecContext *avctx) s->avctx = avctx; dca_init_vlcs(); - ff_dsputil_init(&s->dsp, avctx); + avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT); ff_mdct_init(&s->imdct, 6, 1, 1.0); ff_synth_filter_init(&s->synth); ff_dcadsp_init(&s->dcadsp); diff --git a/libavcodec/dsputil.c b/libavcodec/dsputil.c index 942f606ea8..15f184e406 100644 --- a/libavcodec/dsputil.c +++ b/libavcodec/dsputil.c @@ -2401,14 +2401,6 @@ static void vector_fmul_scalar_c(float *dst, const float *src, float mul, dst[i] = src[i] * mul; } -static void vector_fmac_scalar_c(float *dst, const float *src, float mul, - int len) -{ - int i; - for (i = 0; i < len; i++) - dst[i] += src[i] * mul; -} - static void butterflies_float_c(float *restrict v1, float *restrict v2, int len) { @@ -2904,7 +2896,6 @@ av_cold void ff_dsputil_init(DSPContext* c, AVCodecContext *avctx) c->butterflies_float = butterflies_float_c; c->butterflies_float_interleave = butterflies_float_interleave_c; c->vector_fmul_scalar = vector_fmul_scalar_c; - c->vector_fmac_scalar = vector_fmac_scalar_c; c->shrink[0]= av_image_copy_plane; c->shrink[1]= ff_shrink22; diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h index ec3d7ee007..e54ae69831 100644 --- a/libavcodec/dsputil.h +++ b/libavcodec/dsputil.h @@ -416,17 +416,6 @@ typedef struct DSPContext { */ void (*vector_fmul_scalar)(float *dst, const float *src, float mul, int len); - /** - * Multiply a vector of floats by a scalar float and add to - * destination vector. Source and destination vectors must - * overlap exactly or not at all. - * @param dst result vector, 16-byte aligned - * @param src input vector, 16-byte aligned - * @param mul scalar value - * @param len length of vector, multiple of 4 - */ - void (*vector_fmac_scalar)(float *dst, const float *src, float mul, - int len); /** * Calculate the scalar product of two vectors of floats. * @param v1 first vector, 16-byte aligned diff --git a/libavutil/arm/float_dsp_init_neon.c b/libavutil/arm/float_dsp_init_neon.c index fa6d0d7d15..3ca0288b31 100644 --- a/libavutil/arm/float_dsp_init_neon.c +++ b/libavutil/arm/float_dsp_init_neon.c @@ -26,7 +26,11 @@ void ff_vector_fmul_neon(float *dst, const float *src0, const float *src1, int len); +void ff_vector_fmac_scalar_neon(float *dst, const float *src, float mul, + int len); + void ff_float_dsp_init_neon(AVFloatDSPContext *fdsp) { fdsp->vector_fmul = ff_vector_fmul_neon; + fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_neon; } diff --git a/libavutil/arm/float_dsp_neon.S b/libavutil/arm/float_dsp_neon.S index d66fa09424..03b164388f 100644 --- a/libavutil/arm/float_dsp_neon.S +++ b/libavutil/arm/float_dsp_neon.S @@ -62,3 +62,51 @@ function ff_vector_fmul_neon, export=1 3: vst1.32 {d16-d19},[r0,:128]! bx lr endfunc + +function ff_vector_fmac_scalar_neon, export=1 +VFP len .req r2 +VFP acc .req r3 +NOVFP len .req r3 +NOVFP acc .req r2 +VFP vdup.32 q15, d0[0] +NOVFP vdup.32 q15, r2 + bics r12, len, #15 + mov acc, r0 + beq 3f + vld1.32 {q0}, [r1,:128]! + vld1.32 {q8}, [acc,:128]! + vld1.32 {q1}, [r1,:128]! + vld1.32 {q9}, [acc,:128]! +1: vmla.f32 q8, q0, q15 + vld1.32 {q2}, [r1,:128]! + vld1.32 {q10}, [acc,:128]! + vmla.f32 q9, q1, q15 + vld1.32 {q3}, [r1,:128]! + vld1.32 {q11}, [acc,:128]! + vmla.f32 q10, q2, q15 + vst1.32 {q8}, [r0,:128]! + vmla.f32 q11, q3, q15 + vst1.32 {q9}, [r0,:128]! + subs r12, r12, #16 + beq 2f + vld1.32 {q0}, [r1,:128]! + vld1.32 {q8}, [acc,:128]! + vst1.32 {q10}, [r0,:128]! + vld1.32 {q1}, [r1,:128]! + vld1.32 {q9}, [acc,:128]! + vst1.32 {q11}, [r0,:128]! + b 1b +2: vst1.32 {q10}, [r0,:128]! + vst1.32 {q11}, [r0,:128]! + ands len, len, #15 + it eq + bxeq lr +3: vld1.32 {q0}, [r1,:128]! + vld1.32 {q8}, [acc,:128]! + vmla.f32 q8, q0, q15 + vst1.32 {q8}, [r0,:128]! + subs len, len, #4 + bgt 3b + bx lr + .unreq len +endfunc diff --git a/libavutil/float_dsp.c b/libavutil/float_dsp.c index 039dd07d36..2e90939090 100644 --- a/libavutil/float_dsp.c +++ b/libavutil/float_dsp.c @@ -28,9 +28,18 @@ static void vector_fmul_c(float *dst, const float *src0, const float *src1, dst[i] = src0[i] * src1[i]; } +static void vector_fmac_scalar_c(float *dst, const float *src, float mul, + int len) +{ + int i; + for (i = 0; i < len; i++) + dst[i] += src[i] * mul; +} + void avpriv_float_dsp_init(AVFloatDSPContext *fdsp, int bit_exact) { fdsp->vector_fmul = vector_fmul_c; + fdsp->vector_fmac_scalar = vector_fmac_scalar_c; #if ARCH_ARM ff_float_dsp_init_arm(fdsp); diff --git a/libavutil/float_dsp.h b/libavutil/float_dsp.h index 30161a252b..4e266304da 100644 --- a/libavutil/float_dsp.h +++ b/libavutil/float_dsp.h @@ -35,6 +35,22 @@ typedef struct AVFloatDSPContext { */ void (*vector_fmul)(float *dst, const float *src0, const float *src1, int len); + + /** + * Multiply a vector of floats by a scalar float and add to + * destination vector. Source and destination vectors must + * overlap exactly or not at all. + * + * @param dst result vector + * constraints: 16-byte aligned + * @param src input vector + * constraints: 16-byte aligned + * @param mul scalar value + * @param len length of vector + * constraints: multiple of 4 + */ + void (*vector_fmac_scalar)(float *dst, const float *src, float mul, + int len); } AVFloatDSPContext; /** From 82b2df979069063beb14be340350501c8340f9cd Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 8 Jun 2012 23:20:59 -0400 Subject: [PATCH 16/24] float_dsp: add x86-optimized functions for vector_fmac_scalar() --- libavutil/float_dsp.h | 6 ++--- libavutil/x86/float_dsp.asm | 47 ++++++++++++++++++++++++++++++++++ libavutil/x86/float_dsp_init.c | 7 +++++ 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/libavutil/float_dsp.h b/libavutil/float_dsp.h index 4e266304da..95cef62f29 100644 --- a/libavutil/float_dsp.h +++ b/libavutil/float_dsp.h @@ -42,12 +42,12 @@ typedef struct AVFloatDSPContext { * overlap exactly or not at all. * * @param dst result vector - * constraints: 16-byte aligned + * constraints: 32-byte aligned * @param src input vector - * constraints: 16-byte aligned + * constraints: 32-byte aligned * @param mul scalar value * @param len length of vector - * constraints: multiple of 4 + * constraints: multiple of 16 */ void (*vector_fmac_scalar)(float *dst, const float *src, float mul, int len); diff --git a/libavutil/x86/float_dsp.asm b/libavutil/x86/float_dsp.asm index 53be7ab99a..66ef09398d 100644 --- a/libavutil/x86/float_dsp.asm +++ b/libavutil/x86/float_dsp.asm @@ -19,6 +19,7 @@ ;****************************************************************************** %include "x86inc.asm" +%include "x86util.asm" SECTION .text @@ -53,3 +54,49 @@ VECTOR_FMUL INIT_YMM avx VECTOR_FMUL %endif + +;------------------------------------------------------------------------------ +; void ff_vector_fmac_scalar(float *dst, const float *src, float mul, int len) +;------------------------------------------------------------------------------ + +%macro VECTOR_FMAC_SCALAR 0 +%if UNIX64 +cglobal vector_fmac_scalar, 3,3,3, dst, src, len +%else +cglobal vector_fmac_scalar, 4,4,3, dst, src, mul, len +%endif +%if WIN64 + SWAP 0, 2 +%endif +%if ARCH_X86_32 + VBROADCASTSS m0, mulm +%else + shufps xmm0, xmm0, 0 +%if cpuflag(avx) + vinsertf128 m0, m0, xmm0, 1 +%endif +%endif + lea lenq, [lend*4-2*mmsize] +.loop + mulps m1, m0, [srcq+lenq ] + mulps m2, m0, [srcq+lenq+mmsize] + addps m1, m1, [dstq+lenq ] + addps m2, m2, [dstq+lenq+mmsize] + mova [dstq+lenq ], m1 + mova [dstq+lenq+mmsize], m2 + sub lenq, 2*mmsize + jge .loop +%if mmsize == 32 + vzeroupper + RET +%else + REP_RET +%endif +%endmacro + +INIT_XMM sse +VECTOR_FMAC_SCALAR +%if HAVE_AVX +INIT_YMM avx +VECTOR_FMAC_SCALAR +%endif diff --git a/libavutil/x86/float_dsp_init.c b/libavutil/x86/float_dsp_init.c index 10bb226f23..d259a367e0 100644 --- a/libavutil/x86/float_dsp_init.c +++ b/libavutil/x86/float_dsp_init.c @@ -26,6 +26,11 @@ extern void ff_vector_fmul_sse(float *dst, const float *src0, const float *src1, extern void ff_vector_fmul_avx(float *dst, const float *src0, const float *src1, int len); +extern void ff_vector_fmac_scalar_sse(float *dst, const float *src, float mul, + int len); +extern void ff_vector_fmac_scalar_avx(float *dst, const float *src, float mul, + int len); + void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp) { #if HAVE_YASM @@ -33,9 +38,11 @@ void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp) if (mm_flags & AV_CPU_FLAG_SSE && HAVE_SSE) { fdsp->vector_fmul = ff_vector_fmul_sse; + fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_sse; } if (mm_flags & AV_CPU_FLAG_AVX && HAVE_AVX) { fdsp->vector_fmul = ff_vector_fmul_avx; + fdsp->vector_fmac_scalar = ff_vector_fmac_scalar_avx; } #endif } From f0ece49e74bf4443b91a98c228da8b645a8c5173 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 8 Jun 2012 22:34:30 -0400 Subject: [PATCH 17/24] af_amix: use AVFloatDSPContext.vector_fmac_scalar() --- libavfilter/af_amix.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c index 003a8e8e62..44549801ae 100644 --- a/libavfilter/af_amix.c +++ b/libavfilter/af_amix.c @@ -32,6 +32,7 @@ #include "libavutil/audio_fifo.h" #include "libavutil/avassert.h" #include "libavutil/avstring.h" +#include "libavutil/float_dsp.h" #include "libavutil/mathematics.h" #include "libavutil/opt.h" #include "libavutil/samplefmt.h" @@ -152,6 +153,7 @@ static int frame_list_add_frame(FrameList *frame_list, int nb_samples, int64_t p typedef struct MixContext { const AVClass *class; /**< class for AVOptions */ + AVFloatDSPContext fdsp; int nb_inputs; /**< number of inputs */ int active_inputs; /**< number of input currently active */ @@ -263,14 +265,6 @@ static int config_output(AVFilterLink *outlink) return 0; } -/* TODO: move optimized version from DSPContext to libavutil */ -static void vector_fmac_scalar(float *dst, const float *src, float mul, int len) -{ - int i; - for (i = 0; i < len; i++) - dst[i] += src[i] * mul; -} - /** * Read samples from the input FIFOs, mix, and write to the output link. */ @@ -295,9 +289,10 @@ static int output_frame(AVFilterLink *outlink, int nb_samples) if (s->input_state[i] == INPUT_ON) { av_audio_fifo_read(s->fifos[i], (void **)in_buf->extended_data, nb_samples); - vector_fmac_scalar((float *)out_buf->extended_data[0], - (float *) in_buf->extended_data[0], - s->input_scale[i], nb_samples * s->nb_channels); + s->fdsp.vector_fmac_scalar((float *)out_buf->extended_data[0], + (float *) in_buf->extended_data[0], + s->input_scale[i], + FFALIGN(nb_samples * s->nb_channels, 16)); } } avfilter_unref_buffer(in_buf); @@ -500,6 +495,8 @@ static int init(AVFilterContext *ctx, const char *args, void *opaque) ff_insert_inpad(ctx, i, &pad); } + avpriv_float_dsp_init(&s->fdsp, 0); + return 0; } From ae46fbee1d92789401e431a12c3ab4fdf19917e8 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 8 Jun 2012 23:59:04 -0400 Subject: [PATCH 18/24] af_amix: allow float planar sample format as input --- libavfilter/af_amix.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c index 44549801ae..4af5f80d57 100644 --- a/libavfilter/af_amix.c +++ b/libavfilter/af_amix.c @@ -162,6 +162,7 @@ typedef struct MixContext { int nb_channels; /**< number of channels */ int sample_rate; /**< sample rate */ + int planar; AVAudioFifo **fifos; /**< audio fifo for each input */ uint8_t *input_state; /**< current state of each input */ float *input_scale; /**< mixing scale factor for each input */ @@ -225,6 +226,7 @@ static int config_output(AVFilterLink *outlink) int i; char buf[64]; + s->planar = av_sample_fmt_is_planar(outlink->format); s->sample_rate = outlink->sample_rate; outlink->time_base = (AVRational){ 1, outlink->sample_rate }; s->next_pts = AV_NOPTS_VALUE; @@ -287,12 +289,20 @@ static int output_frame(AVFilterLink *outlink, int nb_samples) for (i = 0; i < s->nb_inputs; i++) { if (s->input_state[i] == INPUT_ON) { + int planes, plane_size, p; + av_audio_fifo_read(s->fifos[i], (void **)in_buf->extended_data, nb_samples); - s->fdsp.vector_fmac_scalar((float *)out_buf->extended_data[0], - (float *) in_buf->extended_data[0], - s->input_scale[i], - FFALIGN(nb_samples * s->nb_channels, 16)); + + planes = s->planar ? s->nb_channels : 1; + plane_size = nb_samples * (s->planar ? 1 : s->nb_channels); + plane_size = FFALIGN(plane_size, 16); + + for (p = 0; p < planes; p++) { + s->fdsp.vector_fmac_scalar((float *)out_buf->extended_data[p], + (float *) in_buf->extended_data[p], + s->input_scale[i], plane_size); + } } } avfilter_unref_buffer(in_buf); @@ -523,6 +533,7 @@ static int query_formats(AVFilterContext *ctx) { AVFilterFormats *formats = NULL; ff_add_format(&formats, AV_SAMPLE_FMT_FLT); + ff_add_format(&formats, AV_SAMPLE_FMT_FLTP); ff_set_common_formats(ctx, formats); ff_set_common_channel_layouts(ctx, ff_all_channel_layouts()); ff_set_common_samplerates(ctx, ff_all_samplerates()); From ae2bb52cd24482762ac8af77f3cf69f658aba1fd Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 18 Jun 2012 13:57:59 +0100 Subject: [PATCH 19/24] mpegts: remove unused/incomplete/broken seeking code --- libavformat/mpegts.c | 96 -------------------------------------------- 1 file changed, 96 deletions(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index ebc5f2c66a..5b44c0e824 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -19,8 +19,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -//#define USE_SYNCPOINT_SEARCH - #include "libavutil/crc.h" #include "libavutil/intreadwrite.h" #include "libavutil/log.h" @@ -2093,92 +2091,6 @@ static int64_t mpegts_get_pcr(AVFormatContext *s, int stream_index, return timestamp; } -#ifdef USE_SYNCPOINT_SEARCH - -static int read_seek2(AVFormatContext *s, - int stream_index, - int64_t min_ts, - int64_t target_ts, - int64_t max_ts, - int flags) -{ - int64_t pos; - - int64_t ts_ret, ts_adj; - int stream_index_gen_search; - AVStream *st; - AVParserState *backup; - - backup = ff_store_parser_state(s); - - // detect direction of seeking for search purposes - flags |= (target_ts - min_ts > (uint64_t)(max_ts - target_ts)) ? - AVSEEK_FLAG_BACKWARD : 0; - - if (flags & AVSEEK_FLAG_BYTE) { - // use position directly, we will search starting from it - pos = target_ts; - } else { - // search for some position with good timestamp match - if (stream_index < 0) { - stream_index_gen_search = av_find_default_stream_index(s); - if (stream_index_gen_search < 0) { - ff_restore_parser_state(s, backup); - return -1; - } - - st = s->streams[stream_index_gen_search]; - // timestamp for default must be expressed in AV_TIME_BASE units - ts_adj = av_rescale(target_ts, - st->time_base.den, - AV_TIME_BASE * (int64_t)st->time_base.num); - } else { - ts_adj = target_ts; - stream_index_gen_search = stream_index; - } - pos = ff_gen_search(s, stream_index_gen_search, ts_adj, - 0, INT64_MAX, -1, - AV_NOPTS_VALUE, - AV_NOPTS_VALUE, - flags, &ts_ret, mpegts_get_pcr); - if (pos < 0) { - ff_restore_parser_state(s, backup); - return -1; - } - } - - // search for actual matching keyframe/starting position for all streams - if (ff_gen_syncpoint_search(s, stream_index, pos, - min_ts, target_ts, max_ts, - flags) < 0) { - ff_restore_parser_state(s, backup); - return -1; - } - - ff_free_parser_state(s, backup); - return 0; -} - -static int read_seek(AVFormatContext *s, int stream_index, int64_t target_ts, int flags) -{ - int ret; - if (flags & AVSEEK_FLAG_BACKWARD) { - flags &= ~AVSEEK_FLAG_BACKWARD; - ret = read_seek2(s, stream_index, INT64_MIN, target_ts, target_ts, flags); - if (ret < 0) - // for compatibility reasons, seek to the best-fitting timestamp - ret = read_seek2(s, stream_index, INT64_MIN, target_ts, INT64_MAX, flags); - } else { - ret = read_seek2(s, stream_index, target_ts, target_ts, INT64_MAX, flags); - if (ret < 0) - // for compatibility reasons, seek to the best-fitting timestamp - ret = read_seek2(s, stream_index, INT64_MIN, target_ts, INT64_MAX, flags); - } - return ret; -} - -#else - static int read_seek(AVFormatContext *s, int stream_index, int64_t target_ts, int flags){ MpegTSContext *ts = s->priv_data; uint8_t buf[TS_PACKET_SIZE]; @@ -2202,8 +2114,6 @@ static int read_seek(AVFormatContext *s, int stream_index, int64_t target_ts, in return 0; } -#endif - /**************************************************************/ /* parsing functions - called from other demuxers such as RTP */ @@ -2268,9 +2178,6 @@ AVInputFormat ff_mpegts_demuxer = { .read_seek = read_seek, .read_timestamp = mpegts_get_pcr, .flags = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT, -#ifdef USE_SYNCPOINT_SEARCH - .read_seek2 = read_seek2, -#endif }; AVInputFormat ff_mpegtsraw_demuxer = { @@ -2283,8 +2190,5 @@ AVInputFormat ff_mpegtsraw_demuxer = { .read_seek = read_seek, .read_timestamp = mpegts_get_pcr, .flags = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT, -#ifdef USE_SYNCPOINT_SEARCH - .read_seek2 = read_seek2, -#endif .priv_class = &mpegtsraw_class, }; From 51a2b5546b29b113da4abd1cd9793c01e545da19 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 18 Jun 2012 14:02:43 +0100 Subject: [PATCH 20/24] http: replace atoll() with strtoll() --- libavformat/http.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavformat/http.c b/libavformat/http.c index a4941937dd..8ccb64986c 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -309,15 +309,15 @@ static int process_line(URLContext *h, char *line, int line_count, strcpy(s->location, p); *new_location = 1; } else if (!av_strcasecmp (tag, "Content-Length") && s->filesize == -1) { - s->filesize = atoll(p); + s->filesize = strtoll(p, NULL, 10); } else if (!av_strcasecmp (tag, "Content-Range")) { /* "bytes $from-$to/$document_size" */ const char *slash; if (!strncmp (p, "bytes ", 6)) { p += 6; - s->off = atoll(p); + s->off = strtoll(p, NULL, 10); if ((slash = strchr(p, '/')) && strlen(slash) > 0) - s->filesize = atoll(slash+1); + s->filesize = strtoll(slash+1, NULL, 10); } h->is_streamed = 0; /* we _can_ in fact seek */ } else if (!av_strcasecmp(tag, "Accept-Ranges") && !strncmp(p, "bytes", 5)) { From 8703f0140f89bb761e9b158978aee51d90d5293d Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 18 Jun 2012 15:22:15 +0100 Subject: [PATCH 21/24] flvdec: remove incomplete, disabled seeking code --- libavformat/flvdec.c | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index f04f4fec25..8e9759ba28 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -749,33 +749,6 @@ static int flv_read_seek(AVFormatContext *s, int stream_index, return avio_seek_time(s->pb, stream_index, ts, flags); } -#if 0 /* don't know enough to implement this */ -static int flv_read_seek2(AVFormatContext *s, int stream_index, - int64_t min_ts, int64_t ts, int64_t max_ts, int flags) -{ - int ret = AVERROR(ENOSYS); - - if (ts - min_ts > (uint64_t)(max_ts - ts)) flags |= AVSEEK_FLAG_BACKWARD; - - if (!s->pb->seekable) { - if (stream_index < 0) { - stream_index = av_find_default_stream_index(s); - if (stream_index < 0) - return -1; - - /* timestamp for default must be expressed in AV_TIME_BASE units */ - ts = av_rescale_rnd(ts, 1000, AV_TIME_BASE, - flags & AVSEEK_FLAG_BACKWARD ? AV_ROUND_DOWN : AV_ROUND_UP); - } - ret = avio_seek_time(s->pb, stream_index, ts, flags); - } - - if (ret == AVERROR(ENOSYS)) - ret = av_seek_frame(s, stream_index, ts, flags); - return ret; -} -#endif - AVInputFormat ff_flv_demuxer = { .name = "flv", .long_name = NULL_IF_CONFIG_SMALL("FLV format"), @@ -784,9 +757,6 @@ AVInputFormat ff_flv_demuxer = { .read_header = flv_read_header, .read_packet = flv_read_packet, .read_seek = flv_read_seek, -#if 0 - .read_seek2 = flv_read_seek2, -#endif .read_close = flv_read_close, .extensions = "flv", }; From 7146177d1812966b3e19025271965625ac7a054d Mon Sep 17 00:00:00 2001 From: "Simon A. Eugster" Date: Sat, 9 Jun 2012 11:16:12 +0200 Subject: [PATCH 22/24] lavc: Extend the documentation for avcodec_init_packet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a note that pkt->data and pkt->size must be initialized. Signed-off-by: Martin Storsjö --- libavcodec/avcodec.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 94c2ed7655..eac68946b2 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -3284,6 +3284,9 @@ void av_destruct_packet(AVPacket *pkt); /** * Initialize optional fields of a packet with default values. * + * Note, this does not touch the data and size members, which have to be + * initialized separately. + * * @param pkt packet */ void av_init_packet(AVPacket *pkt); From be1a839ca638e308748831fdc6fa0b7a7c8e94cf Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 18 Jun 2012 14:37:02 +0100 Subject: [PATCH 23/24] mem: add support for _aligned_malloc() as found on Windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The check uses check_func_header, since this function is conditionally available depending on the targeted MSVCRT version. Signed-off-by: Martin Storsjö --- configure | 4 +++- libavutil/mem.c | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/configure b/configure index ea80d480b2..0baa755d77 100755 --- a/configure +++ b/configure @@ -1051,6 +1051,7 @@ HAVE_LIST=" $ARCH_EXT_LIST $HAVE_LIST_PUB $THREADS_LIST + aligned_malloc aligned_stack alsa_asoundlib_h altivec_h @@ -2838,6 +2839,7 @@ check_func ${malloc_prefix}memalign && enable memalign check_func mkstemp check_func mmap check_func ${malloc_prefix}posix_memalign && enable posix_memalign +check_func_headers malloc.h _aligned_malloc && enable aligned_malloc check_func setrlimit check_func strerror_r check_func strptime @@ -3144,7 +3146,7 @@ check_deps $CONFIG_LIST \ enabled asm || { arch=c; disable $ARCH_LIST $ARCH_EXT_LIST; } -! enabled_any memalign posix_memalign && +! enabled_any memalign posix_memalign aligned_malloc && enabled_any $need_memalign && enable memalign_hack echo "install prefix $prefix" diff --git a/libavutil/mem.c b/libavutil/mem.c index bf1a542db8..0fe9f5422a 100644 --- a/libavutil/mem.c +++ b/libavutil/mem.c @@ -84,6 +84,8 @@ void *av_malloc(size_t size) #elif HAVE_POSIX_MEMALIGN if (posix_memalign(&ptr,32,size)) ptr = NULL; +#elif HAVE_ALIGNED_MALLOC + ptr = _aligned_malloc(size, 32); #elif HAVE_MEMALIGN ptr = memalign(32,size); /* Why 64? @@ -131,6 +133,8 @@ void *av_realloc(void *ptr, size_t size) if(!ptr) return av_malloc(size); diff= ((char*)ptr)[-1]; return (char*)realloc((char*)ptr - diff, size + diff) + diff; +#elif HAVE_ALIGNED_MALLOC + return _aligned_realloc(ptr, size, 32); #else return realloc(ptr, size); #endif @@ -141,6 +145,8 @@ void av_free(void *ptr) #if CONFIG_MEMALIGN_HACK if (ptr) free((char*)ptr - ((char*)ptr)[-1]); +#elif HAVE_ALIGNED_MALLOC + _aligned_free(ptr); #else free(ptr); #endif From 4cc2920dd2c0ce4e64e709da4f78508e1ec9871e Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Fri, 29 Jul 2011 12:02:54 +0200 Subject: [PATCH 24/24] flvdec: remove incomplete, disabled seeking code --- libavcodec/ratecontrol.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/libavcodec/ratecontrol.c b/libavcodec/ratecontrol.c index 5e4b49adf3..9065f8e416 100644 --- a/libavcodec/ratecontrol.c +++ b/libavcodec/ratecontrol.c @@ -508,14 +508,6 @@ static double predict_size(Predictor *p, double q, double var) return p->coeff*var / (q*p->count); } -/* -static double predict_qp(Predictor *p, double size, double var) -{ -//printf("coeff:%f, count:%f, var:%f, size:%f//\n", p->coeff, p->count, var, size); - return p->coeff*var / (size*p->count); -} -*/ - static void update_predictor(Predictor *p, double q, double var, double size) { double new_coeff= size*q / (var + 1); @@ -555,10 +547,6 @@ static void adaptive_quantization(MpegEncContext *s, double q){ int mb_y = mb_xy / s->mb_stride; int mb_distance; float mb_factor = 0.0; -#if 0 - if(spat_cplx < q/3) spat_cplx= q/3; //FIXME finetune - if(temp_cplx < q/3) temp_cplx= q/3; //FIXME finetune -#endif if(spat_cplx < 4) spat_cplx= 4; //FIXME finetune if(temp_cplx < 4) temp_cplx= 4; //FIXME finetune