- Discworld II BMV decoding support
- VBLE Decoder
- OS X Video Decoder Acceleration (VDA) support
+- compact and csv output in ffprobe
+- pan audio filter
+- IFF Amiga Continuous Bitmap (ACBM) decoder
+- ass filter
- CRI ADX audio format demuxer
+ - Playstation Portable PMP format demuxer
-version 0.7:
-
-- E-AC-3 audio encoder
-- ac3enc: add channel coupling support
-- floating-point sample format support for (E-)AC-3, DCA, AAC, Vorbis decoders
-- H.264/MPEG frame-level multithreading
-- av_metadata_* functions renamed to av_dict_* and moved to libavutil
-- 4:4:4 H.264 decoding support
-- 10-bit H.264 optimizations for x86
-- bump libswscale for recently reported ABI break
-
-
-version 0.7_beta2:
+version 0.8:
-- VP8 frame-level multithreading
-- NEON optimizations for VP8
-- removed a lot of deprecated API cruft
-- FFT and IMDCT optimizations for AVX (Sandy Bridge) processors
-- DPX image encoder
-- SMPTE 302M AES3 audio decoder
-- ffmpeg no longer quits after the 'q' key is pressed; use 'ctrl+c' instead
-- 9bit and 10bit per sample support in the H.264 decoder
-
-
-version 0.7_beta1:
+- many many things we forgot because we rather write code than changelogs
- WebM support in Matroska de/muxer
- low overhead Ogg muxing
- MMS-TCP support
--- /dev/null
- Context *c;
-
- c = av_mallocz(sizeof(Context));
- if (!c) {
- return AVERROR(ENOMEM);
- }
- h->priv_data = c;
+/*
+ * Input cache protocol.
+ * Copyright (c) 2011 Michael Niedermayer
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Based on file.c by Fabrice Bellard
+ */
+
+/**
+ * @TODO
+ * support non continuous caching
+ * support keeping files
+ * support filling with a background thread
+ */
+
+#include "libavutil/avassert.h"
+#include "libavutil/avstring.h"
+#include "libavutil/file.h"
+#include "avformat.h"
+#include <fcntl.h>
+#if HAVE_SETMODE
+#include <io.h>
+#endif
+#include <unistd.h>
+#include <sys/stat.h>
+#include <stdlib.h>
+#include "os_support.h"
+#include "url.h"
+
+typedef struct Context {
+ int fd;
+ int64_t end;
+ int64_t pos;
+ URLContext *inner;
+} Context;
+
+static int cache_open(URLContext *h, const char *arg, int flags)
+{
+ int access;
+ const char *buffername;
- av_freep(&h->priv_data);
-
++ Context *c= h->priv_data;
+
+ av_strstart(arg, "cache:", &arg);
+
+ c->fd = av_tempfile("ffcache", &buffername, 0, h);
+ if (c->fd < 0){
+ av_log(h, AV_LOG_ERROR, "Failed to create tempfile\n");
+ return c->fd;
+ }
+
+ unlink(buffername);
+ av_free(buffername);
+
+ return ffurl_open(&c->inner, arg, flags, &h->interrupt_callback, NULL);
+}
+
+static int cache_read(URLContext *h, unsigned char *buf, int size)
+{
+ Context *c= h->priv_data;
+ int r;
+
+ if(c->pos<c->end){
+ r = read(c->fd, buf, FFMIN(size, c->end - c->pos));
+ if(r>0)
+ c->pos += r;
+ return (-1 == r)?AVERROR(errno):r;
+ }else{
+ r = ffurl_read(c->inner, buf, size);
+ if(r > 0){
+ int r2= write(c->fd, buf, r);
+ av_assert0(r2==r); // FIXME handle cache failure
+ c->pos += r;
+ c->end += r;
+ }
+ return r;
+ }
+}
+
+static int64_t cache_seek(URLContext *h, int64_t pos, int whence)
+{
+ Context *c= h->priv_data;
+
+ if (whence == AVSEEK_SIZE) {
+ pos= ffurl_seek(c->inner, pos, whence);
+ if(pos <= 0){
+ pos= ffurl_seek(c->inner, -1, SEEK_END);
+ ffurl_seek(c->inner, c->end, SEEK_SET);
+ if(pos <= 0)
+ return c->end;
+ }
+ return pos;
+ }
+
+ pos= lseek(c->fd, pos, whence);
+ if(pos<0){
+ return pos;
+ }else if(pos <= c->end){
+ c->pos= pos;
+ return pos;
+ }else{
+ lseek(c->fd, c->pos, SEEK_SET);
+ return AVERROR(EPIPE);
+ }
+}
+
+static int cache_close(URLContext *h)
+{
+ Context *c= h->priv_data;
+ close(c->fd);
+ ffurl_close(c->inner);
+
+ return 0;
+}
+
+URLProtocol ff_cache_protocol = {
+ .name = "cache",
+ .url_open = cache_open,
+ .url_read = cache_read,
+ .url_seek = cache_seek,
+ .url_close = cache_close,
++ .priv_data_size = sizeof(Context),
+};
}
}
-static int mmsh_open(URLContext *h, const char *uri, int flags)
+static int mmsh_open_internal(URLContext *h, const char *uri, int flags, int timestamp, int64_t pos)
{
int i, port, err;
- char httpname[256], path[256], host[128], location[1024];
+ char httpname[256], path[256], host[128];
char *stream_selection = NULL;
char headers[1024];
- MMSHContext *mmsh;
+ MMSHContext *mmsh = h->priv_data;
MMSContext *mms;
- mmsh = h->priv_data = av_mallocz(sizeof(MMSHContext));
- if (!h->priv_data)
- return AVERROR(ENOMEM);
mmsh->request_seq = h->is_streamed = 1;
mms = &mmsh->mms;
- av_strlcpy(location, uri, sizeof(location));
+ av_strlcpy(mmsh->location, uri, sizeof(mmsh->location));
av_url_split(NULL, 0, NULL, 0,
- host, sizeof(host), &port, path, sizeof(path), location);
+ host, sizeof(host), &port, path, sizeof(path), mmsh->location);
if (port<0)
port = 80; // default mmsh protocol port
ff_url_join(httpname, sizeof(httpname), "http", NULL, host, port, "%s", path);
return res;
}
+static int64_t mmsh_read_seek(URLContext *h, int stream_index,
+ int64_t timestamp, int flags)
+{
+ MMSHContext *mmsh = h->priv_data;
+ MMSContext *mms = &mmsh->mms;
+ int ret;
+
+ ret= mmsh_open_internal(h, mmsh->location, 0, FFMAX(timestamp, 0), 0);
+
+ if(ret>=0){
+ if (mms->mms_hd)
+ ffurl_close(mms->mms_hd);
+ av_freep(&mms->streams);
+ av_freep(&mms->asf_header);
+ av_free(mmsh);
+ mmsh = h->priv_data;
+ mms = &mmsh->mms;
+ mms->asf_header_read_size= mms->asf_header_size;
+ }else
+ h->priv_data= mmsh;
+ return ret;
+}
+
+static int64_t mmsh_seek(URLContext *h, int64_t pos, int whence)
+{
+ MMSHContext *mmsh = h->priv_data;
+ MMSContext *mms = &mmsh->mms;
+
+ if(pos == 0 && whence == SEEK_CUR)
+ return mms->asf_header_read_size + mms->remaining_in_len + mmsh->chunk_seq * mms->asf_packet_len;
+ return AVERROR(ENOSYS);
+}
+
URLProtocol ff_mmsh_protocol = {
- .name = "mmsh",
- .url_open = mmsh_open,
- .url_read = mmsh_read,
- .url_seek = mmsh_seek,
- .url_close = mmsh_close,
+ .name = "mmsh",
+ .url_open = mmsh_open,
+ .url_read = mmsh_read,
++ .url_seek = mmsh_seek,
+ .url_close = mmsh_close,
+ .url_read_seek = mmsh_read_seek,
+ .priv_data_size = sizeof(MMSHContext),
};
AVStream *ast = avformat_new_stream(s, NULL);
if (!ast)
return AVERROR(ENOMEM);
- ast->id = i;
- ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
- ast->codec->codec_id = audio_codec_id;
- ast->codec->channels = channels;
+ ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
+ ast->codec->codec_id = audio_codec_id;
+ ast->codec->channels = channels;
ast->codec->sample_rate = srate;
- avpriv_set_pts_info(ast, 32, 1, srate);
+ av_set_pts_info(ast, 32, 1, srate);
}
- pos = avio_tell(pb) + 4 * index_cnt;
+ pos = avio_tell(pb) + 4*index_cnt;
for (i = 0; i < index_cnt; i++) {
- int size = avio_rl32(pb);
+ int size = avio_rl32(pb);
int flags = size & 1 ? AVINDEX_KEYFRAME : 0;
size >>= 1;
av_add_index_entry(vst, pos, i, size, 0, flags);
pmp->packet_sizes[i] = avio_rl32(pb);
}
ret = av_get_packet(pb, pkt, pmp->packet_sizes[pmp->current_packet]);
- if (ret > 0) {
+ if (ret >= 0) {
ret = 0;
- // FIXME: this is a hack that should be remove once
- // compute_pkt_fields can handle
+ // FIXME: this is a hack that should be removed once
+ // compute_pkt_fields() can handle timestamps properly
if (pmp->cur_stream == 0)
pkt->dts = s->streams[0]->cur_dts++;
pkt->stream_index = pmp->cur_stream;
return ret;
}
- static int pmp_seek(AVFormatContext *s, int stream_index,
- int64_t ts, int flags) {
-static int pmp_seek(AVFormatContext *s, int stream_idx, int64_t ts, int flags)
++static int pmp_seek(AVFormatContext *s, int stream_index, int64_t ts, int flags)
+ {
PMPContext *pmp = s->priv_data;
pmp->cur_stream = 0;
// fallback to default seek now
fail:
if (udp_fd >= 0)
closesocket(udp_fd);
- av_free(s);
+ av_fifo_free(s->fifo);
return AVERROR(EIO);
}
if (s->is_multicast && (h->flags & AVIO_FLAG_READ))
udp_leave_multicast_group(s->udp_fd, (struct sockaddr *)&s->dest_addr);
closesocket(s->udp_fd);
- av_free(s);
+ av_fifo_free(s->fifo);
return 0;
}
#include "libavutil/cpu.h"
#include "libavutil/avutil.h"
#include "libavutil/bswap.h"
+ #include "libavutil/mathematics.h"
#include "libavutil/opt.h"
#include "libavutil/pixdesc.h"
+#include "libavutil/avassert.h"
unsigned swscale_version(void)
{
--- /dev/null
-a4e18d1ca9ef5b8132a84d43625ddc47 *./tests/data/acodec/pcm_s16be.mov
-1060037 ./tests/data/acodec/pcm_s16be.mov
++9686b93d1439fc2df991a004ab0298f4 *./tests/data/acodec/pcm_s16be.mov
++1058993 ./tests/data/acodec/pcm_s16be.mov
+ 64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/pcm_s16be.acodec.out.wav
+ stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
--- /dev/null
-971d2d2633e41a0326fe2d04a2d0350f *./tests/data/acodec/pcm_s24be.mov
-1589237 ./tests/data/acodec/pcm_s24be.mov
++22c5c3df0a4765e28c205a4fb95b3cdc *./tests/data/acodec/pcm_s24be.mov
++1588193 ./tests/data/acodec/pcm_s24be.mov
+ 64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/pcm_s24be.acodec.out.wav
+ stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
--- /dev/null
-8168a5c1343553ef027541830f2cb879 *./tests/data/acodec/pcm_s24daud.302
++1b75d5198ae789ab3c48f7024e08f4a9 *./tests/data/acodec/pcm_s24daud.302
+ 10368730 ./tests/data/acodec/pcm_s24daud.302
-f552afadfdfcd6348a07095da6382de5 *./tests/data/pcm_s24daud.acodec.out.wav
-stddev: 9416.28 PSNR: 16.85 MAXDIFF:42744 bytes: 6911796/ 1058400
++4708f86529c594e29404603c64bb208c *./tests/data/pcm_s24daud.acodec.out.wav
++stddev: 8967.92 PSNR: 17.28 MAXDIFF:42548 bytes: 6911796/ 1058400
--- /dev/null
-fc4f4e3e195bbde037ed31021d229f12 *./tests/data/acodec/pcm_s32be.mov
-2118437 ./tests/data/acodec/pcm_s32be.mov
++b36ac7a1b4fc28248a565a676e555bd1 *./tests/data/acodec/pcm_s32be.mov
++2117393 ./tests/data/acodec/pcm_s32be.mov
+ 64151e4bcc2b717aa5a8454d424d6a1f *./tests/data/pcm_s32be.acodec.out.wav
+ stddev: 0.00 PSNR:999.99 MAXDIFF: 0 bytes: 1058400/ 1058400
--- /dev/null
-760f85fb9f4e8aba326fb44ae84c9507 *./tests/data/acodec/pcm_s8.mov
-530837 ./tests/data/acodec/pcm_s8.mov
++b78d2a30df75af08ecf86f201281fec2 *./tests/data/acodec/pcm_s8.mov
++529793 ./tests/data/acodec/pcm_s8.mov
+ 651d4eb8d98dfcdda96ae6c43d8f156b *./tests/data/pcm_s8.acodec.out.wav
+ stddev: 147.89 PSNR: 52.93 MAXDIFF: 255 bytes: 1058400/ 1058400