From 8e1340abc316e038bb89e5a3b46e92ff58c98a88 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 12 Jan 2012 09:51:23 +0100 Subject: [PATCH 1/5] avserver: fix build after the next bump. --- avserver.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/avserver.c b/avserver.c index 15fa64c144..f3ac319ef9 100644 --- a/avserver.c +++ b/avserver.c @@ -26,13 +26,16 @@ #include #include #include "libavformat/avformat.h" +// FIXME those are internal headers, avserver _really_ shouldn't use them #include "libavformat/ffm.h" #include "libavformat/network.h" #include "libavformat/os_support.h" #include "libavformat/rtpdec.h" #include "libavformat/rtsp.h" -// XXX for ffio_open_dyn_packet_buffer, to be removed #include "libavformat/avio_internal.h" +#include "libavformat/internal.h" +#include "libavformat/url.h" + #include "libavutil/avstring.h" #include "libavutil/lfg.h" #include "libavutil/dict.h" @@ -867,7 +870,7 @@ static void close_connection(HTTPContext *c) } h = c->rtp_handles[i]; if (h) - url_close(h); + ffurl_close(h); } ctx = &c->fmt_ctx; @@ -2248,7 +2251,6 @@ static int http_prepare_data(HTTPContext *c) * Default value from Libav * Try to set it use configuration option */ - c->fmt_ctx.preload = (int)(0.5*AV_TIME_BASE); c->fmt_ctx.max_delay = (int)(0.7*AV_TIME_BASE); if (avformat_write_header(&c->fmt_ctx, NULL) < 0) { @@ -2367,7 +2369,7 @@ static int http_prepare_data(HTTPContext *c) if (c->rtp_protocol == RTSP_LOWER_TRANSPORT_TCP) max_packet_size = RTSP_TCP_MAX_PACKET_SIZE; else - max_packet_size = url_get_max_packet_size(c->rtp_handles[c->packet_stream_index]); + max_packet_size = c->rtp_handles[c->packet_stream_index]->max_packet_size; ret = ffio_open_dyn_packet_buf(&ctx->pb, max_packet_size); } else { ret = avio_open_dyn_buf(&ctx->pb); @@ -2520,8 +2522,8 @@ static int http_send_data(HTTPContext *c) } else { /* send RTP packet directly in UDP */ c->buffer_ptr += 4; - url_write(c->rtp_handles[c->packet_stream_index], - c->buffer_ptr, len); + ffurl_write(c->rtp_handles[c->packet_stream_index], + c->buffer_ptr, len); c->buffer_ptr += len; /* here we continue as we can send several packets per 10 ms slot */ } @@ -3404,10 +3406,10 @@ static int rtp_new_av_stream(HTTPContext *c, "rtp://%s:%d", ipaddr, ntohs(dest_addr->sin_port)); } - if (url_open(&h, ctx->filename, AVIO_FLAG_WRITE) < 0) + if (ffurl_open(&h, ctx->filename, AVIO_FLAG_WRITE, NULL, NULL) < 0) goto fail; c->rtp_handles[stream_index] = h; - max_packet_size = url_get_max_packet_size(h); + max_packet_size = h->max_packet_size; break; case RTSP_LOWER_TRANSPORT_TCP: /* RTP/TCP case */ @@ -3430,7 +3432,7 @@ static int rtp_new_av_stream(HTTPContext *c, if (avformat_write_header(ctx, NULL) < 0) { fail: if (h) - url_close(h); + ffurl_close(h); av_free(ctx); return -1; } @@ -3467,7 +3469,7 @@ static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec, int cop } fst->priv_data = av_mallocz(sizeof(FeedData)); fst->index = stream->nb_streams; - av_set_pts_info(fst, 33, 1, 90000); + avpriv_set_pts_info(fst, 33, 1, 90000); fst->sample_aspect_ratio = codec->sample_aspect_ratio; stream->streams[stream->nb_streams++] = fst; return fst; From b89f8774f2778c5aad4633a98e3a12597344730a Mon Sep 17 00:00:00 2001 From: Dustin Brody Date: Wed, 18 Jan 2012 04:16:42 -0500 Subject: [PATCH 2/5] avidec: migrate last of lavf from FF_ER_* to AV_EF_* Signed-off-by: Anton Khirnov --- libavformat/avidec.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libavformat/avidec.c b/libavformat/avidec.c index b45224f641..b4ccfb50f8 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -666,9 +666,9 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) case MKTAG('i', 'n', 'd', 'x'): i= avio_tell(pb); if(pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX) && - read_braindead_odml_indx(s, 0) < 0 && s->error_recognition >= FF_ER_EXPLODE){ + read_braindead_odml_indx(s, 0) < 0 && + (s->error_recognition & AV_EF_EXPLODE)) goto fail; - } avio_seek(pb, i+size, SEEK_SET); break; case MKTAG('v', 'p', 'r', 'p'): @@ -705,7 +705,8 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) if(size > 1000000){ av_log(s, AV_LOG_ERROR, "Something went wrong during header parsing, " "I will ignore it and try to continue anyway.\n"); - if (s->error_recognition >= FF_ER_EXPLODE) goto fail; + if (s->error_recognition & AV_EF_EXPLODE) + goto fail; avi->movi_list = avio_tell(pb) - 4; avi->movi_end = avio_size(pb); goto end_of_header; From 59297ad63dbd7f9a587e742e1d5b0e94ae125fff Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Wed, 18 Jan 2012 20:32:32 +0100 Subject: [PATCH 3/5] lavf: force single-threaded decoding in avformat_find_stream_info The H.264 decoder needs SPS and PPS for initialization during multi-threaded decoding. When probed single-threaded SPS and PPS are copied to extradata and are available for proper initialization of the decoder before the first frame is decoded. --- libavformat/utils.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/libavformat/utils.c b/libavformat/utils.c index b1832ba717..22ee13b51f 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2138,10 +2138,18 @@ static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **option AVPacket pkt = *avpkt; if(!st->codec->codec){ + AVDictionary *thread_opt = NULL; + codec = avcodec_find_decoder(st->codec->codec_id); if (!codec) return -1; - ret = avcodec_open2(st->codec, codec, options); + + /* force thread count to 1 since the h264 decoder will not extract SPS + * and PPS to extradata during multi-threaded decoding */ + av_dict_set(options ? options : &thread_opt, "threads", "1", 0); + ret = avcodec_open2(st->codec, codec, options ? options : &thread_opt); + if (!options) + av_dict_free(&thread_opt); if (ret < 0) return ret; } @@ -2281,6 +2289,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) for(i=0;inb_streams;i++) { AVCodec *codec; + AVDictionary *thread_opt = NULL; st = ic->streams[i]; if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO || @@ -2300,16 +2309,24 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) assert(!st->codec->codec); codec = avcodec_find_decoder(st->codec->codec_id); + /* force thread count to 1 since the h264 decoder will not extract SPS + * and PPS to extradata during multi-threaded decoding */ + av_dict_set(options ? &options[i] : &thread_opt, "threads", "1", 0); + /* Ensure that subtitle_header is properly set. */ if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE && codec && !st->codec->codec) - avcodec_open2(st->codec, codec, options ? &options[i] : NULL); + avcodec_open2(st->codec, codec, options ? &options[i] + : &thread_opt); //try to just open decoders, in case this is enough to get parameters if(!has_codec_parameters(st->codec)){ if (codec && !st->codec->codec) - avcodec_open2(st->codec, codec, options ? &options[i] : NULL); + avcodec_open2(st->codec, codec, options ? &options[i] + : &thread_opt); } + if (!options) + av_dict_free(&thread_opt); } for (i=0; inb_streams; i++) { From c3d5e290ca868f72c53740fdc66133a474c12c7e Mon Sep 17 00:00:00 2001 From: Felipe Contreras Date: Fri, 20 Jan 2012 16:01:07 +0000 Subject: [PATCH 4/5] ARM: fix build with FFT enabled and MDCT disabled Signed-off-by: Felipe Contreras Signed-off-by: Mans Rullgard --- libavcodec/arm/fft_init_arm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/arm/fft_init_arm.c b/libavcodec/arm/fft_init_arm.c index 4ee4909682..b2c3b721fd 100644 --- a/libavcodec/arm/fft_init_arm.c +++ b/libavcodec/arm/fft_init_arm.c @@ -42,10 +42,12 @@ av_cold void ff_fft_init_arm(FFTContext *s) if (HAVE_NEON) { s->fft_permute = ff_fft_permute_neon; s->fft_calc = ff_fft_calc_neon; +#if CONFIG_MDCT s->imdct_calc = ff_imdct_calc_neon; s->imdct_half = ff_imdct_half_neon; s->mdct_calc = ff_mdct_calc_neon; s->mdct_permutation = FF_MDCT_PERM_INTERLEAVE; +#endif } } From 23e57d167a87d3a671fe25efb2d5a1cf1719efc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 19 Jan 2012 14:01:19 +0200 Subject: [PATCH 5/5] Add a tool that uses avio to read and write, doing a plain copy of data MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It also optionally can throttle its operation to a particular speed, to simulate realtime writing. Signed-off-by: Martin Storsjö --- libavformat/Makefile | 2 +- tools/aviocat.c | 97 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 98 insertions(+), 1 deletion(-) create mode 100644 tools/aviocat.c diff --git a/libavformat/Makefile b/libavformat/Makefile index e5642433dd..2a2a946104 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -354,6 +354,6 @@ SKIPHEADERS-$(CONFIG_NETWORK) += network.h rtsp.h EXAMPLES = metadata output TESTPROGS = seek -TOOLS = pktdumper probetest +TOOLS = aviocat pktdumper probetest $(SUBDIR)output-example$(EXESUF): ELIBS = -lswscale diff --git a/tools/aviocat.c b/tools/aviocat.c new file mode 100644 index 0000000000..c43c69d1be --- /dev/null +++ b/tools/aviocat.c @@ -0,0 +1,97 @@ +/* + * 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 +#include +#include +#include "libavformat/avformat.h" +#include "libavformat/riff.h" +#include "libavutil/intreadwrite.h" +#include "libavutil/mathematics.h" + +static int usage(const char *argv0, int ret) +{ + fprintf(stderr, "%s [-b bytespersec] input_url output_url\n", argv0); + return ret; +} + +int main(int argc, char **argv) +{ + int bps = 0, ret, i; + const char *input_url = NULL, *output_url = NULL; + int64_t stream_pos = 0; + int64_t start_time; + char errbuf[50]; + AVIOContext *input, *output; + + av_register_all(); + avformat_network_init(); + + for (i = 1; i < argc; i++) { + if (!strcmp(argv[i], "-b")) { + bps = atoi(argv[i + 1]); + i++; + } else if (!input_url) { + input_url = argv[i]; + } else if (!output_url) { + output_url = argv[i]; + } else { + return usage(argv[0], 1); + } + } + if (!output_url) + return usage(argv[0], 1); + + ret = avio_open2(&input, input_url, AVIO_FLAG_READ, NULL, NULL); + if (ret) { + av_strerror(ret, errbuf, sizeof(errbuf)); + fprintf(stderr, "Unable to open %s: %s\n", input_url, errbuf); + return 1; + } + ret = avio_open2(&output, output_url, AVIO_FLAG_WRITE, NULL, NULL); + if (ret) { + av_strerror(ret, errbuf, sizeof(errbuf)); + fprintf(stderr, "Unable to open %s: %s\n", output_url, errbuf); + goto fail; + } + + start_time = av_gettime(); + while (1) { + uint8_t buf[1024]; + int n; + n = avio_read(input, buf, sizeof(buf)); + if (n <= 0) + break; + avio_write(output, buf, n); + stream_pos += n; + if (bps) { + avio_flush(output); + while ((av_gettime() - start_time)*bps/AV_TIME_BASE < stream_pos) + usleep(50*1000); + } + } + + avio_close(output); +fail: + avio_close(input); + avformat_network_deinit(); + return ret ? 1 : 0; +}