From 45fcb86cf86a0dca43a196e927817efb188fd7da Mon Sep 17 00:00:00 2001 From: Mike Melanson Date: Mon, 7 Nov 2011 23:28:02 -0800 Subject: AIFF: add 'twos' FourCC for the mux/demuxer (big endian PCM audio) Signed-off-by: Anton Khirnov --- libavformat/aiff.h | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/aiff.h b/libavformat/aiff.h index cd2bd256d6..3190a22787 100644 --- a/libavformat/aiff.h +++ b/libavformat/aiff.h @@ -43,6 +43,7 @@ static const AVCodecTag ff_codec_aiff_tags[] = { { CODEC_ID_MACE6, MKTAG('M','A','C','6') }, { CODEC_ID_GSM, MKTAG('G','S','M',' ') }, { CODEC_ID_ADPCM_G726, MKTAG('G','7','2','6') }, + { CODEC_ID_PCM_S16BE, MKTAG('t','w','o','s') }, { CODEC_ID_PCM_S16LE, MKTAG('s','o','w','t') }, { CODEC_ID_ADPCM_IMA_QT, MKTAG('i','m','a','4') }, { CODEC_ID_QDM2, MKTAG('Q','D','M','2') }, -- cgit v1.2.3 From e1e22851c15b2b88de111353f53fe4c94431f883 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 10 Nov 2011 09:19:09 +0100 Subject: AVOptions: don't return an invalid option when option list is empty --- libavutil/opt.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libavutil/opt.c b/libavutil/opt.c index aa76301740..7c53024d25 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -56,9 +56,10 @@ const AVOption *av_next_option(void *obj, const AVOption *last) const AVOption *av_opt_next(void *obj, const AVOption *last) { - if (last && last[1].name) return ++last; - else if (last) return NULL; - else return (*(AVClass**)obj)->option; + AVClass *class = *(AVClass**)obj; + if (!last && class->option[0].name) return class->option; + if (last && last[1].name) return ++last; + return NULL; } static int read_number(const AVOption *o, void *dst, double *num, int *den, int64_t *intnum) -- cgit v1.2.3 From b01f5ba2070e022e6cf6c1fa8410367e90e33b60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 10 Nov 2011 18:21:17 +0200 Subject: http: Print an error message for Authorization Required, too MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The error was hidden before, to avoid showing an error on the first request where no auth has been provided, when the server indicates which authentication method to use. Now the error is printed if an authentication method was used, but failed. Signed-off-by: Martin Storsjö --- libavformat/http.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavformat/http.c b/libavformat/http.c index 83ffc0b60e..093bb822dc 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -236,7 +236,8 @@ static int process_line(URLContext *h, char *line, int line_count, /* error codes are 4xx and 5xx, but regard 401 as a success, so we * don't abort until all headers have been parsed. */ - if (s->http_code >= 400 && s->http_code < 600 && s->http_code != 401) { + if (s->http_code >= 400 && s->http_code < 600 && (s->http_code != 401 + || s->auth_state.auth_type != HTTP_AUTH_NONE)) { end += strspn(end, SPACE_CHARS); av_log(h, AV_LOG_WARNING, "HTTP error %d %s\n", s->http_code, end); -- cgit v1.2.3 From b911518d1c17223aa7fb83ace08b2bd41c203da0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 11 Nov 2011 11:21:42 +0200 Subject: http: Handle proxy authentication MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tested with both Basic and Digest authentication, and tested with both proxy authentication and authentication for the requested resource at the same time. Signed-off-by: Martin Storsjö --- libavformat/http.c | 75 ++++++++++++++++++++++++++++++++++---------------- libavformat/httpauth.c | 2 +- 2 files changed, 53 insertions(+), 24 deletions(-) diff --git a/libavformat/http.c b/libavformat/http.c index 093bb822dc..a8a76882dd 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -47,6 +47,7 @@ typedef struct { int64_t off, filesize; char location[MAX_URL_SIZE]; HTTPAuthState auth_state; + HTTPAuthState proxy_auth_state; char *headers; int willclose; /**< Set if the server correctly handles Connection: close and will close the connection after feeding us the content. */ int chunked_post; @@ -71,25 +72,29 @@ static const AVClass flavor ## _context_class = {\ HTTP_CLASS(http); HTTP_CLASS(https); -static int http_connect(URLContext *h, const char *path, const char *hoststr, - const char *auth, int *new_location); +static int http_connect(URLContext *h, const char *path, const char *local_path, + const char *hoststr, const char *auth, + const char *proxyauth, int *new_location); void ff_http_init_auth_state(URLContext *dest, const URLContext *src) { memcpy(&((HTTPContext*)dest->priv_data)->auth_state, &((HTTPContext*)src->priv_data)->auth_state, sizeof(HTTPAuthState)); + memcpy(&((HTTPContext*)dest->priv_data)->proxy_auth_state, + &((HTTPContext*)src->priv_data)->proxy_auth_state, + sizeof(HTTPAuthState)); } /* return non zero if error */ static int http_open_cnx(URLContext *h) { - const char *path, *proxy_path, *lower_proto = "tcp"; + const char *path, *proxy_path, *lower_proto = "tcp", *local_path; char hostname[1024], hoststr[1024], proto[10]; - char auth[1024]; + char auth[1024], proxyauth[1024]; char path1[1024]; - char buf[1024]; + char buf[1024], urlbuf[1024]; int port, use_proxy, err, location_changed = 0, redirects = 0; - HTTPAuthType cur_auth_type; + HTTPAuthType cur_auth_type, cur_proxy_auth_type; HTTPContext *s = h->priv_data; URLContext *hd = NULL; @@ -105,15 +110,19 @@ static int http_open_cnx(URLContext *h) path1, sizeof(path1), s->location); ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL); + if (path1[0] == '\0') + path = "/"; + else + path = path1; + local_path = path; if (use_proxy) { - av_url_split(NULL, 0, auth, sizeof(auth), hostname, sizeof(hostname), &port, - NULL, 0, proxy_path); - path = s->location; - } else { - if (path1[0] == '\0') - path = "/"; - else - path = path1; + /* Reassemble the request URL without auth string - we don't + * want to leak the auth to the proxy. */ + ff_url_join(urlbuf, sizeof(urlbuf), proto, NULL, hostname, port, "%s", + path1); + path = urlbuf; + av_url_split(NULL, 0, proxyauth, sizeof(proxyauth), + hostname, sizeof(hostname), &port, NULL, 0, proxy_path); } if (!strcmp(proto, "https")) { lower_proto = "tls"; @@ -130,7 +139,8 @@ static int http_open_cnx(URLContext *h) s->hd = hd; cur_auth_type = s->auth_state.auth_type; - if (http_connect(h, path, hoststr, auth, &location_changed) < 0) + cur_proxy_auth_type = s->auth_state.auth_type; + if (http_connect(h, path, local_path, hoststr, auth, proxyauth, &location_changed) < 0) goto fail; if (s->http_code == 401) { if (cur_auth_type == HTTP_AUTH_NONE && s->auth_state.auth_type != HTTP_AUTH_NONE) { @@ -139,6 +149,14 @@ static int http_open_cnx(URLContext *h) } else goto fail; } + if (s->http_code == 407) { + if (cur_proxy_auth_type == HTTP_AUTH_NONE && + s->proxy_auth_state.auth_type != HTTP_AUTH_NONE) { + ffurl_close(hd); + goto redo; + } else + goto fail; + } if ((s->http_code == 301 || s->http_code == 302 || s->http_code == 303 || s->http_code == 307) && location_changed == 1) { /* url moved, get next */ @@ -237,7 +255,8 @@ static int process_line(URLContext *h, char *line, int line_count, /* error codes are 4xx and 5xx, but regard 401 as a success, so we * don't abort until all headers have been parsed. */ if (s->http_code >= 400 && s->http_code < 600 && (s->http_code != 401 - || s->auth_state.auth_type != HTTP_AUTH_NONE)) { + || s->auth_state.auth_type != HTTP_AUTH_NONE) && + (s->http_code != 407 || s->proxy_auth_state.auth_type != HTTP_AUTH_NONE)) { end += strspn(end, SPACE_CHARS); av_log(h, AV_LOG_WARNING, "HTTP error %d %s\n", s->http_code, end); @@ -278,6 +297,8 @@ static int process_line(URLContext *h, char *line, int line_count, ff_http_auth_handle_header(&s->auth_state, tag, p); } else if (!av_strcasecmp (tag, "Authentication-Info")) { ff_http_auth_handle_header(&s->auth_state, tag, p); + } else if (!av_strcasecmp (tag, "Proxy-Authenticate")) { + ff_http_auth_handle_header(&s->proxy_auth_state, tag, p); } else if (!av_strcasecmp (tag, "Connection")) { if (!strcmp(p, "close")) s->willclose = 1; @@ -294,22 +315,27 @@ static inline int has_header(const char *str, const char *header) return av_stristart(str, header + 2, NULL) || av_stristr(str, header); } -static int http_connect(URLContext *h, const char *path, const char *hoststr, - const char *auth, int *new_location) +static int http_connect(URLContext *h, const char *path, const char *local_path, + const char *hoststr, const char *auth, + const char *proxyauth, int *new_location) { HTTPContext *s = h->priv_data; int post, err; char line[1024]; char headers[1024] = ""; - char *authstr = NULL; + char *authstr = NULL, *proxyauthstr = NULL; int64_t off = s->off; int len = 0; + const char *method; /* send http header */ post = h->flags & AVIO_FLAG_WRITE; - authstr = ff_http_auth_create_response(&s->auth_state, auth, path, - post ? "POST" : "GET"); + method = post ? "POST" : "GET"; + authstr = ff_http_auth_create_response(&s->auth_state, auth, local_path, + method); + proxyauthstr = ff_http_auth_create_response(&s->proxy_auth_state, proxyauth, + local_path, method); /* set default headers if needed */ if (!has_header(s->headers, "\r\nUser-Agent: ")) @@ -337,14 +363,17 @@ static int http_connect(URLContext *h, const char *path, const char *hoststr, "%s" "%s" "%s" + "%s%s" "\r\n", - post ? "POST" : "GET", + method, path, post && s->chunked_post ? "Transfer-Encoding: chunked\r\n" : "", headers, - authstr ? authstr : ""); + authstr ? authstr : "", + proxyauthstr ? "Proxy-" : "", proxyauthstr ? proxyauthstr : ""); av_freep(&authstr); + av_freep(&proxyauthstr); if (ffurl_write(s->hd, s->buffer, strlen(s->buffer)) < 0) return AVERROR(EIO); diff --git a/libavformat/httpauth.c b/libavformat/httpauth.c index 1dda1ac8f0..c8b8ace3c2 100644 --- a/libavformat/httpauth.c +++ b/libavformat/httpauth.c @@ -87,7 +87,7 @@ static void choose_qop(char *qop, int size) void ff_http_auth_handle_header(HTTPAuthState *state, const char *key, const char *value) { - if (!strcmp(key, "WWW-Authenticate")) { + if (!strcmp(key, "WWW-Authenticate") || !strcmp(key, "Proxy-Authenticate")) { const char *p; if (av_stristart(value, "Basic ", &p) && state->auth_type <= HTTP_AUTH_BASIC) { -- cgit v1.2.3 From b8a1b880ee155f4f27389f7f76a58a1d87eb7008 Mon Sep 17 00:00:00 2001 From: John Brooks Date: Wed, 9 Nov 2011 16:28:35 -0700 Subject: rtpdec: Simplify finalize_packet MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Martin Storsjö --- libavformat/rtpdec.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c index 1e6bd6eee7..a5ec1caf7a 100644 --- a/libavformat/rtpdec.c +++ b/libavformat/rtpdec.c @@ -421,7 +421,10 @@ static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestam { if (pkt->pts != AV_NOPTS_VALUE || pkt->dts != AV_NOPTS_VALUE) return; /* Timestamp already set by depacketizer */ - if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE && timestamp != RTP_NOTS_VALUE) { + if (timestamp == RTP_NOTS_VALUE) + return; + + if (s->last_rtcp_ntp_time != AV_NOPTS_VALUE) { int64_t addend; int delta_timestamp; @@ -433,8 +436,7 @@ static void finalize_packet(RTPDemuxContext *s, AVPacket *pkt, uint32_t timestam delta_timestamp; return; } - if (timestamp == RTP_NOTS_VALUE) - return; + if (!s->base_timestamp) s->base_timestamp = timestamp; pkt->pts = s->range_start_offset + timestamp - s->base_timestamp; -- cgit v1.2.3 From 124e56454dc9adbcc20fcf124785865549e04d7a Mon Sep 17 00:00:00 2001 From: Sean McGovern Date: Thu, 10 Nov 2011 19:16:58 -0500 Subject: swscale: add padding to conversion buffer. Altivec does unaligned reads from this buffer in hscale_altivec_real(), and can thus read up to 16 bytes beyond the end of the buffer. Therefore, add an extra 16 bytes of padding at the end of the conversion buffer. This fixes fate-lavfi-pixfmts_scale on AltiVec-enabled builds under valgrind. Signed-off-by: Ronald S. Bultje --- libswscale/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libswscale/utils.c b/libswscale/utils.c index 862b2736f6..51bec62717 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -871,7 +871,7 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) if (c->dstBpc == 16) dst_stride <<= 1; FF_ALLOC_OR_GOTO(c, c->formatConvBuffer, - FFALIGN(srcW, 16) * 2 * FFALIGN(c->srcBpc, 8) >> 3, + (FFALIGN(srcW, 16) * 2 * FFALIGN(c->srcBpc, 8) >> 3) + 16, fail); if (HAVE_MMX2 && cpu_flags & AV_CPU_FLAG_MMX2 && c->srcBpc == 8 && c->dstBpc <= 10) { c->canMMX2BeUsed= (dstW >=srcW && (dstW&31)==0 && (srcW&15)==0) ? 1 : 0; -- cgit v1.2.3 From a8a6da4a0e059b2aab66627a96b63c3632c477c2 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 29 Oct 2011 18:56:42 -0400 Subject: twinvq: check for allocation failure in init_mdct_win() --- libavcodec/twinvq.c | 76 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 29 deletions(-) diff --git a/libavcodec/twinvq.c b/libavcodec/twinvq.c index c7ce11d937..174cee7424 100644 --- a/libavcodec/twinvq.c +++ b/libavcodec/twinvq.c @@ -871,9 +871,9 @@ static int twin_decode_frame(AVCodecContext * avctx, void *data, /** * Init IMDCT and windowing tables */ -static av_cold void init_mdct_win(TwinContext *tctx) +static av_cold int init_mdct_win(TwinContext *tctx) { - int i,j; + int i, j, ret; const ModeTab *mtab = tctx->mtab; int size_s = mtab->size / mtab->fmode[FT_SHORT].sub; int size_m = mtab->size / mtab->fmode[FT_MEDIUM].sub; @@ -882,20 +882,29 @@ static av_cold void init_mdct_win(TwinContext *tctx) for (i = 0; i < 3; i++) { int bsize = tctx->mtab->size/tctx->mtab->fmode[i].sub; - ff_mdct_init(&tctx->mdct_ctx[i], av_log2(bsize) + 1, 1, - -sqrt(norm/bsize) / (1<<15)); + if ((ret = ff_mdct_init(&tctx->mdct_ctx[i], av_log2(bsize) + 1, 1, + -sqrt(norm/bsize) / (1<<15)))) + return ret; } - tctx->tmp_buf = av_malloc(mtab->size * sizeof(*tctx->tmp_buf)); + FF_ALLOC_OR_GOTO(tctx->avctx, tctx->tmp_buf, + mtab->size * sizeof(*tctx->tmp_buf), alloc_fail); - tctx->spectrum = av_malloc(2*mtab->size*channels*sizeof(float)); - tctx->curr_frame = av_malloc(2*mtab->size*channels*sizeof(float)); - tctx->prev_frame = av_malloc(2*mtab->size*channels*sizeof(float)); + FF_ALLOC_OR_GOTO(tctx->avctx, tctx->spectrum, + 2 * mtab->size * channels * sizeof(*tctx->spectrum), + alloc_fail); + FF_ALLOC_OR_GOTO(tctx->avctx, tctx->curr_frame, + 2 * mtab->size * channels * sizeof(*tctx->curr_frame), + alloc_fail); + FF_ALLOC_OR_GOTO(tctx->avctx, tctx->prev_frame, + 2 * mtab->size * channels * sizeof(*tctx->prev_frame), + alloc_fail); for (i = 0; i < 3; i++) { int m = 4*mtab->size/mtab->fmode[i].sub; double freq = 2*M_PI/m; - tctx->cos_tabs[i] = av_malloc((m/4)*sizeof(*tctx->cos_tabs)); + FF_ALLOC_OR_GOTO(tctx->avctx, tctx->cos_tabs[i], + (m / 4) * sizeof(*tctx->cos_tabs[i]), alloc_fail); for (j = 0; j <= m/8; j++) tctx->cos_tabs[i][j] = cos((2*j + 1)*freq); @@ -907,6 +916,10 @@ static av_cold void init_mdct_win(TwinContext *tctx) ff_init_ff_sine_windows(av_log2(size_m)); ff_init_ff_sine_windows(av_log2(size_s/2)); ff_init_ff_sine_windows(av_log2(mtab->size)); + + return 0; +alloc_fail: + return AVERROR(ENOMEM); } /** @@ -1068,8 +1081,28 @@ static av_cold void init_bitstream_params(TwinContext *tctx) construct_perm_table(tctx, frametype); } +static av_cold int twin_decode_close(AVCodecContext *avctx) +{ + TwinContext *tctx = avctx->priv_data; + int i; + + for (i = 0; i < 3; i++) { + ff_mdct_end(&tctx->mdct_ctx[i]); + av_free(tctx->cos_tabs[i]); + } + + + av_free(tctx->curr_frame); + av_free(tctx->spectrum); + av_free(tctx->prev_frame); + av_free(tctx->tmp_buf); + + return 0; +} + static av_cold int twin_decode_init(AVCodecContext *avctx) { + int ret; TwinContext *tctx = avctx->priv_data; int isampf = avctx->sample_rate/1000; int ibps = avctx->bit_rate/(1000 * avctx->channels); @@ -1099,7 +1132,11 @@ static av_cold int twin_decode_init(AVCodecContext *avctx) } dsputil_init(&tctx->dsp, avctx); - init_mdct_win(tctx); + if ((ret = init_mdct_win(tctx))) { + av_log(avctx, AV_LOG_ERROR, "Error initializing MDCT\n"); + twin_decode_close(avctx); + return ret; + } init_bitstream_params(tctx); memset_float(tctx->bark_hist[0][0], 0.1, FF_ARRAY_ELEMS(tctx->bark_hist)); @@ -1107,25 +1144,6 @@ static av_cold int twin_decode_init(AVCodecContext *avctx) return 0; } -static av_cold int twin_decode_close(AVCodecContext *avctx) -{ - TwinContext *tctx = avctx->priv_data; - int i; - - for (i = 0; i < 3; i++) { - ff_mdct_end(&tctx->mdct_ctx[i]); - av_free(tctx->cos_tabs[i]); - } - - - av_free(tctx->curr_frame); - av_free(tctx->spectrum); - av_free(tctx->prev_frame); - av_free(tctx->tmp_buf); - - return 0; -} - AVCodec ff_twinvq_decoder = { .name = "twinvq", .type = AVMEDIA_TYPE_AUDIO, -- cgit v1.2.3 From ca482ce4204fe198b2df1b41f3d15e883f3f1f0d Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 29 Oct 2011 19:24:55 -0400 Subject: vqf: do not set bits_per_coded_sample for TwinVQ. It is a lossy codec with varying quantization, so bits_per_coded_sample is not applicable. --- libavformat/vqf.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libavformat/vqf.c b/libavformat/vqf.c index 71dc1ae73d..4650a0b500 100644 --- a/libavformat/vqf.c +++ b/libavformat/vqf.c @@ -106,7 +106,6 @@ static int vqf_read_header(AVFormatContext *s, AVFormatParameters *ap) avio_skip(s->pb, len-12); st->codec->bit_rate = read_bitrate*1000; - st->codec->bits_per_coded_sample = 16; break; case MKTAG('N','A','M','E'): add_metadata(s, "title" , len, header_size); -- cgit v1.2.3 From 7b966566da24598a636a433a75a7842e272b18f6 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 30 Oct 2011 00:46:16 -0400 Subject: vqf/twinvq: pass vqf COMM chunk info in extradata This is needed because the twinvq decoder cannot rely on bit_rate to be set. The API documentation says that bit_rate is set by libavcodec, not by the user. --- libavcodec/twinvq.c | 18 ++++++++++++++++-- libavformat/vqf.c | 14 +++++++++++--- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/libavcodec/twinvq.c b/libavcodec/twinvq.c index 174cee7424..73eb7c1499 100644 --- a/libavcodec/twinvq.c +++ b/libavcodec/twinvq.c @@ -1104,17 +1104,31 @@ static av_cold int twin_decode_init(AVCodecContext *avctx) { int ret; TwinContext *tctx = avctx->priv_data; - int isampf = avctx->sample_rate/1000; - int ibps = avctx->bit_rate/(1000 * avctx->channels); + int isampf, ibps; tctx->avctx = avctx; avctx->sample_fmt = AV_SAMPLE_FMT_FLT; + if (!avctx->extradata || avctx->extradata_size < 12) { + av_log(avctx, AV_LOG_ERROR, "Missing or incomplete extradata\n"); + return AVERROR_INVALIDDATA; + } + avctx->channels = AV_RB32(avctx->extradata ) + 1; + avctx->bit_rate = AV_RB32(avctx->extradata + 4) * 1000; + isampf = AV_RB32(avctx->extradata + 8); + switch (isampf) { + case 44: avctx->sample_rate = 44100; break; + case 22: avctx->sample_rate = 22050; break; + case 11: avctx->sample_rate = 11025; break; + default: avctx->sample_rate = isampf * 1000; break; + } + if (avctx->channels > CHANNELS_MAX) { av_log(avctx, AV_LOG_ERROR, "Unsupported number of channels: %i\n", avctx->channels); return -1; } + ibps = avctx->bit_rate / (1000 * avctx->channels); switch ((isampf << 8) + ibps) { case (8 <<8) + 8: tctx->mtab = &mode_08_08; break; diff --git a/libavformat/vqf.c b/libavformat/vqf.c index 4650a0b500..f2c1d8f146 100644 --- a/libavformat/vqf.c +++ b/libavformat/vqf.c @@ -70,6 +70,7 @@ static int vqf_read_header(AVFormatContext *s, AVFormatParameters *ap) int header_size; int read_bitrate = 0; int size; + uint8_t comm_chunk[12]; if (!st) return AVERROR(ENOMEM); @@ -100,9 +101,10 @@ static int vqf_read_header(AVFormatContext *s, AVFormatParameters *ap) switch(chunk_tag){ case MKTAG('C','O','M','M'): - st->codec->channels = avio_rb32(s->pb) + 1; - read_bitrate = avio_rb32(s->pb); - rate_flag = avio_rb32(s->pb); + avio_read(s->pb, comm_chunk, 12); + st->codec->channels = AV_RB32(comm_chunk ) + 1; + read_bitrate = AV_RB32(comm_chunk + 4); + rate_flag = AV_RB32(comm_chunk + 8); avio_skip(s->pb, len-12); st->codec->bit_rate = read_bitrate*1000; @@ -192,6 +194,12 @@ static int vqf_read_header(AVFormatContext *s, AVFormatParameters *ap) c->frame_bit_len = st->codec->bit_rate*size/st->codec->sample_rate; av_set_pts_info(st, 64, 1, st->codec->sample_rate); + /* put first 12 bytes of COMM chunk in extradata */ + if (!(st->codec->extradata = av_malloc(12 + FF_INPUT_BUFFER_PADDING_SIZE))) + return AVERROR(ENOMEM); + st->codec->extradata_size = 12; + memcpy(st->codec->extradata, comm_chunk, 12); + return 0; } -- cgit v1.2.3 From 9d06037d48041ad8ccbae6c12aa9f3a313a89c4e Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sun, 30 Oct 2011 01:13:55 -0400 Subject: twinvq: add SSE/AVX optimized sum/difference stereo interleaving --- libavcodec/dsputil.c | 13 +++++++++++ libavcodec/dsputil.h | 17 +++++++++++++++ libavcodec/twinvq.c | 34 ++++++++++++++--------------- libavcodec/x86/dsputil_mmx.c | 7 ++++++ libavcodec/x86/dsputil_yasm.asm | 48 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 101 insertions(+), 18 deletions(-) diff --git a/libavcodec/dsputil.c b/libavcodec/dsputil.c index 182063ca2b..91238578b6 100644 --- a/libavcodec/dsputil.c +++ b/libavcodec/dsputil.c @@ -2509,6 +2509,18 @@ static void butterflies_float_c(float *restrict v1, float *restrict v2, } } +static void butterflies_float_interleave_c(float *dst, const float *src0, + const float *src1, int len) +{ + int i; + for (i = 0; i < len; i++) { + float f1 = src0[i]; + float f2 = src1[i]; + dst[2*i ] = f1 + f2; + dst[2*i + 1] = f1 - f2; + } +} + static float scalarproduct_float_c(const float *v1, const float *v2, int len) { float p = 0.0; @@ -3036,6 +3048,7 @@ av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx) c->vector_clip_int32 = vector_clip_int32_c; c->scalarproduct_float = scalarproduct_float_c; 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; diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h index acb2041460..98b7b1eeaa 100644 --- a/libavcodec/dsputil.h +++ b/libavcodec/dsputil.h @@ -453,6 +453,23 @@ typedef struct DSPContext { */ void (*butterflies_float)(float *restrict v1, float *restrict v2, int len); + /** + * Calculate the sum and difference of two vectors of floats and interleave + * results into a separate output vector of floats, with each sum + * positioned before the corresponding difference. + * + * @param dst output vector + * constraints: 16-byte aligned + * @param src0 first input vector + * constraints: 32-byte aligned + * @param src1 second input vector + * constraints: 32-byte aligned + * @param len number of elements in the input + * constraints: multiple of 8 + */ + void (*butterflies_float_interleave)(float *dst, const float *src0, + const float *src1, int len); + /* (I)DCT */ void (*fdct)(DCTELEM *block/* align 16*/); void (*fdct248)(DCTELEM *block/* align 16*/); diff --git a/libavcodec/twinvq.c b/libavcodec/twinvq.c index 73eb7c1499..a2851562ee 100644 --- a/libavcodec/twinvq.c +++ b/libavcodec/twinvq.c @@ -665,8 +665,9 @@ static void imdct_output(TwinContext *tctx, enum FrameType ftype, int wtype, float *out) { const ModeTab *mtab = tctx->mtab; + int size1, size2; float *prev_buf = tctx->prev_frame + tctx->last_block_pos[0]; - int i, j; + int i; for (i = 0; i < tctx->avctx->channels; i++) { imdct_and_window(tctx, ftype, wtype, @@ -675,27 +676,24 @@ static void imdct_output(TwinContext *tctx, enum FrameType ftype, int wtype, i); } + size2 = tctx->last_block_pos[0]; + size1 = mtab->size - size2; if (tctx->avctx->channels == 2) { - for (i = 0; i < mtab->size - tctx->last_block_pos[0]; i++) { - float f1 = prev_buf[ i]; - float f2 = prev_buf[2*mtab->size + i]; - out[2*i ] = f1 + f2; - out[2*i + 1] = f1 - f2; - } - for (j = 0; i < mtab->size; j++,i++) { - float f1 = tctx->curr_frame[ j]; - float f2 = tctx->curr_frame[2*mtab->size + j]; - out[2*i ] = f1 + f2; - out[2*i + 1] = f1 - f2; - } + tctx->dsp.butterflies_float_interleave(out, prev_buf, + &prev_buf[2*mtab->size], + size1); + + out += 2 * size1; + + tctx->dsp.butterflies_float_interleave(out, tctx->curr_frame, + &tctx->curr_frame[2*mtab->size], + size2); } else { - memcpy(out, prev_buf, - (mtab->size - tctx->last_block_pos[0]) * sizeof(*out)); + memcpy(out, prev_buf, size1 * sizeof(*out)); - out += mtab->size - tctx->last_block_pos[0]; + out += size1; - memcpy(out, tctx->curr_frame, - (tctx->last_block_pos[0]) * sizeof(*out)); + memcpy(out, tctx->curr_frame, size2 * sizeof(*out)); } } diff --git a/libavcodec/x86/dsputil_mmx.c b/libavcodec/x86/dsputil_mmx.c index dd6cbf51ad..f0de05a763 100644 --- a/libavcodec/x86/dsputil_mmx.c +++ b/libavcodec/x86/dsputil_mmx.c @@ -2424,6 +2424,11 @@ void ff_vector_clip_int32_int_sse2(int32_t *dst, const int32_t *src, int32_t min void ff_vector_clip_int32_sse4 (int32_t *dst, const int32_t *src, int32_t min, int32_t max, unsigned int len); +extern void ff_butterflies_float_interleave_sse(float *dst, const float *src0, + const float *src1, int len); +extern void ff_butterflies_float_interleave_avx(float *dst, const float *src0, + const float *src1, int len); + void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) { int mm_flags = av_get_cpu_flags(); @@ -2868,6 +2873,7 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) c->vector_clipf = vector_clipf_sse; #if HAVE_YASM c->scalarproduct_float = ff_scalarproduct_float_sse; + c->butterflies_float_interleave = ff_butterflies_float_interleave_sse; #endif } if (HAVE_AMD3DNOW && (mm_flags & AV_CPU_FLAG_3DNOW)) @@ -2925,6 +2931,7 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) c->put_h264_chroma_pixels_tab[0]= ff_put_h264_chroma_mc8_10_avx; c->avg_h264_chroma_pixels_tab[0]= ff_avg_h264_chroma_mc8_10_avx; } + c->butterflies_float_interleave = ff_butterflies_float_interleave_avx; } #endif } diff --git a/libavcodec/x86/dsputil_yasm.asm b/libavcodec/x86/dsputil_yasm.asm index 8e3cbdc03d..f2894cd501 100644 --- a/libavcodec/x86/dsputil_yasm.asm +++ b/libavcodec/x86/dsputil_yasm.asm @@ -1129,3 +1129,51 @@ VECTOR_CLIP_INT32 11, 1, 1, 0 %else VECTOR_CLIP_INT32 6, 1, 0, 0 %endif + +;----------------------------------------------------------------------------- +; void ff_butterflies_float_interleave(float *dst, const float *src0, +; const float *src1, int len); +;----------------------------------------------------------------------------- + +%macro BUTTERFLIES_FLOAT_INTERLEAVE 0 +cglobal butterflies_float_interleave, 4,4,3, dst, src0, src1, len +%ifdef ARCH_X86_64 + movsxd lenq, lend +%endif + test lenq, lenq + jz .end + shl lenq, 2 + lea src0q, [src0q + lenq] + lea src1q, [src1q + lenq] + lea dstq, [ dstq + 2*lenq] + neg lenq +.loop: + mova m0, [src0q + lenq] + mova m1, [src1q + lenq] + subps m2, m0, m1 + addps m0, m0, m1 + unpcklps m1, m0, m2 + unpckhps m0, m0, m2 +%if cpuflag(avx) + vextractf128 [dstq + 2*lenq ], m1, 0 + vextractf128 [dstq + 2*lenq + 16], m0, 0 + vextractf128 [dstq + 2*lenq + 32], m1, 1 + vextractf128 [dstq + 2*lenq + 48], m0, 1 +%else + mova [dstq + 2*lenq ], m1 + mova [dstq + 2*lenq + mmsize], m0 +%endif + add lenq, mmsize + jl .loop +%if mmsize == 32 + vzeroupper + RET +%endif +.end: + REP_RET +%endmacro + +INIT_XMM sse +BUTTERFLIES_FLOAT_INTERLEAVE +INIT_YMM avx +BUTTERFLIES_FLOAT_INTERLEAVE -- cgit v1.2.3 From e79da63282b354fb721ac4b763d268649f0efd76 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 2 Nov 2011 16:47:53 -0400 Subject: dpcm: remove unneeded buf_size==0 check. It is already checked in avcodec_decode_audio3() --- libavcodec/dpcm.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index 6ba8ab13ce..f6531db28b 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -179,9 +179,6 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, int *data_size, int stereo = s->channels - 1; int16_t *output_samples = data; - if (!buf_size) - return 0; - /* calculate output size */ switch(avctx->codec->id) { case CODEC_ID_ROQ_DPCM: -- cgit v1.2.3 From 8dbc6d03c0ad5fc2f8067f7a43209e2fcbb204b0 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 2 Nov 2011 16:49:38 -0400 Subject: dpcm: do not try to decode empty packets --- libavcodec/dpcm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index f6531db28b..abb2019306 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -198,7 +198,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, int *data_size, break; } out *= av_get_bytes_per_sample(avctx->sample_fmt); - if (out < 0) { + if (out <= 0) { av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); return AVERROR(EINVAL); } -- cgit v1.2.3 From befc473c0075ba5afbd38b8fb0c33cd07deec51d Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Wed, 2 Nov 2011 23:02:52 -0400 Subject: mpc7: only support stereo input. The Musepack SV7 reference encoder converts mono to stereo when encoding. --- libavcodec/mpc7.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libavcodec/mpc7.c b/libavcodec/mpc7.c index 60b9f525c2..576400d720 100644 --- a/libavcodec/mpc7.c +++ b/libavcodec/mpc7.c @@ -61,6 +61,13 @@ static av_cold int mpc7_decode_init(AVCodecContext * avctx) static VLC_TYPE hdr_table[1 << MPC7_HDR_BITS][2]; static VLC_TYPE quant_tables[7224][2]; + /* Musepack SV7 is always stereo */ + if (avctx->channels != 2) { + av_log_ask_for_sample(avctx, "Unsupported number of channels: %d\n", + avctx->channels); + return AVERROR_PATCHWELCOME; + } + if(avctx->extradata_size < 16){ av_log(avctx, AV_LOG_ERROR, "Too small extradata size (%i)!\n", avctx->extradata_size); return -1; @@ -88,7 +95,7 @@ static av_cold int mpc7_decode_init(AVCodecContext * avctx) c->frames_to_skip = 0; avctx->sample_fmt = AV_SAMPLE_FMT_S16; - avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; + avctx->channel_layout = AV_CH_LAYOUT_STEREO; if(vlc_initialized) return 0; av_log(avctx, AV_LOG_DEBUG, "Initing VLC\n"); -- cgit v1.2.3 From 5c210e2cb9d7fbdd6175e116502c8ce23267843c Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Thu, 3 Nov 2011 20:54:38 -0400 Subject: shorten: do not modify samples pointer when interleaving --- libavcodec/shorten.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c index f510bcc380..da36bd58eb 100644 --- a/libavcodec/shorten.c +++ b/libavcodec/shorten.c @@ -252,12 +252,13 @@ static int decode_wave_header(AVCodecContext *avctx, const uint8_t *header, return 0; } -static int16_t * interleave_buffer(int16_t *samples, int nchan, int blocksize, int32_t **buffer) { +static void interleave_buffer(int16_t *samples, int nchan, int blocksize, + int32_t **buffer) +{ int i, chan; for (i=0; ichannels, s->blocksize, s->decoded); + interleave_buffer(samples, s->channels, s->blocksize, s->decoded); *data_size = out_size; } } -- cgit v1.2.3 From b656c4d08e196424eb80b706e15d3c49b7c0af37 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Thu, 3 Nov 2011 22:48:15 -0400 Subject: tta: use an integer instead of a pointer to iterate output samples --- libavcodec/tta.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/tta.c b/libavcodec/tta.c index ed8d76bc1a..3e4adf0c11 100644 --- a/libavcodec/tta.c +++ b/libavcodec/tta.c @@ -402,7 +402,7 @@ static int tta_decode_frame(AVCodecContext *avctx, } else { // shift samples for 24-bit sample format int32_t *samples = data; - for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++) + for (i = 0; i < framelen * s->channels; i++) *samples++ <<= 8; // reset decode buffer s->decode_buffer = NULL; -- cgit v1.2.3 From c433a3f9a5ead7bd107384e20ea21de9f4c3f911 Mon Sep 17 00:00:00 2001 From: Derek Buitenhuis Date: Fri, 11 Nov 2011 14:46:19 -0500 Subject: VBLE Decoder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a decoder for the VBLE Lossless Codec, which still has a cult following. Used to be popular several years ago on doom9. Signed-off-by: Derek Buitenhuis Signed-off-by: Martin Storsjö --- Changelog | 1 + doc/general.texi | 1 + libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 1 + libavcodec/avcodec.h | 1 + libavcodec/vble.c | 248 +++++++++++++++++++++++++++++++++++++++++++++++++ libavcodec/version.h | 2 +- libavformat/riff.c | 1 + 8 files changed, 255 insertions(+), 1 deletion(-) create mode 100644 libavcodec/vble.c diff --git a/Changelog b/Changelog index 5387a6522f..a322c9d0d5 100644 --- a/Changelog +++ b/Changelog @@ -100,6 +100,7 @@ easier to use. The changes are: - Properly working defaults in libx264 wrapper, support for native presets. - Encrypted OMA files support - Discworld II BMV decoding support +- VBLE Decoder version 0.7: diff --git a/doc/general.texi b/doc/general.texi index 3187f2cc78..d2747c052c 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -520,6 +520,7 @@ following image formats are supported: @tab Codec used in DOS CD-ROM FlashBack game. @item Ut Video @tab @tab X @item V210 Quicktime Uncompressed 4:2:2 10-bit @tab X @tab X +@item VBLE Lossless Codec @tab @tab X @item VMware Screen Codec / VMware Video @tab @tab X @tab Codec used in videos captured by VMware. @item Westwood Studios VQA (Vector Quantized Animation) video @tab @tab X diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 5fabd8b7fc..76d5ce0707 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -383,6 +383,7 @@ OBJS-$(CONFIG_V210_DECODER) += v210dec.o OBJS-$(CONFIG_V210_ENCODER) += v210enc.o OBJS-$(CONFIG_V210X_DECODER) += v210x.o OBJS-$(CONFIG_VB_DECODER) += vb.o +OBJS-$(CONFIG_VBLE_DECODER) += vble.o OBJS-$(CONFIG_VC1_DECODER) += vc1dec.o vc1.o vc1data.o vc1dsp.o \ msmpeg4.o msmpeg4data.o \ intrax8.o intrax8dsp.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index e9be06398d..a4a2147f94 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -203,6 +203,7 @@ void avcodec_register_all(void) REGISTER_ENCDEC (V210, v210); REGISTER_DECODER (V210X, v210x); REGISTER_DECODER (VB, vb); + REGISTER_DECODER (VBLE, vble); REGISTER_DECODER (VC1, vc1); REGISTER_DECODER (VC1_VDPAU, vc1_vdpau); REGISTER_DECODER (VC1IMAGE, vc1image); diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 76562834ed..7d506a1f72 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -220,6 +220,7 @@ enum CodecID { #endif CODEC_ID_UTVIDEO, CODEC_ID_BMV_VIDEO, + CODEC_ID_VBLE, /* various PCM "codecs" */ CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs diff --git a/libavcodec/vble.c b/libavcodec/vble.c new file mode 100644 index 0000000000..436402ded4 --- /dev/null +++ b/libavcodec/vble.c @@ -0,0 +1,248 @@ +/* + * VBLE Decoder + * Copyright (c) 2011 Derek Buitenhuis + * + * 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 + */ + +/** + * @file + * VBLE Decoder + */ + +#define ALT_BITSTREAM_READER_LE + +#include "avcodec.h" +#include "get_bits.h" + +typedef struct { + AVCodecContext *avctx; + + int size; + int flags; + uint8_t *len; + uint8_t *val; +} VBLEContext; + +static uint8_t vble_read_reverse_unary(GetBitContext *gb) +{ + /* At most we need to read 9 bits total to get indices up to 8 */ + uint8_t val = show_bits(gb, 8); + + if (val) { + val = 7 - av_log2_16bit(av_reverse[val]); + skip_bits(gb, val + 1); + return val; + } else { + skip_bits(gb, 8); + if (get_bits1(gb)) + return 8; + } + + /* Return something larger than 8 on error */ + return UINT8_MAX; +} + +static int vble_unpack(VBLEContext *ctx, GetBitContext *gb) +{ + int i; + + /* Read all the lengths in first */ + for (i = 0; i < ctx->size; i++) { + ctx->len[i] = vble_read_reverse_unary(gb); + + if (ctx->len[i] == UINT8_MAX) + return -1; + } + + /* For any values that have length 0 */ + memset(ctx->val, 0, ctx->size); + + for (i = 0; i < ctx->size; i++) { + /* Check we have enough bits left */ + if (get_bits_left(gb) < ctx->len[i]) + return -1; + + /* get_bits can't take a length of 0 */ + if (ctx->len[i]) + ctx->val[i] = (1 << ctx->len[i]) + get_bits(gb, ctx->len[i]) - 1; + } + + return 0; +} + +static void vble_restore_plane(VBLEContext *ctx, int plane, int offset, + int width, int height) +{ + AVFrame *pic = ctx->avctx->coded_frame; + uint8_t *dst = pic->data[plane]; + uint8_t *val = ctx->val + offset; + uint8_t *len = ctx->len + offset; + uint8_t a, b, c; + int stride = pic->linesize[plane]; + int i, j; + + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) { + dst[j] = (val[j] >> 1) ^ -(val[j] & 1); + + /* Top line and left column are not predicted */ + if (!j) + continue; + + if (!i) { + dst[j] += dst[j - 1]; + continue; + } + + a = dst[j - 1]; + b = dst[j - stride]; + c = a + b - dst[j - 1 - stride]; + dst[j] += mid_pred(a, b, c); + } + dst += stride; + val += width; + len += width; + } +} + +static int vble_decode_frame(AVCodecContext *avctx, void *data, int *data_size, + AVPacket *avpkt) +{ + VBLEContext *ctx = avctx->priv_data; + AVFrame *pic = avctx->coded_frame; + GetBitContext gb; + const uint8_t *src = avpkt->data; + int version; + int offset = 0; + int width_uv = avctx->width / 2, height_uv = avctx->height / 2; + + pic->reference = 0; + + /* Clear buffer if need be */ + if (pic->data[0]) + avctx->release_buffer(avctx, pic); + + /* Allocate buffer */ + if (avctx->get_buffer(avctx, pic) < 0) { + av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n"); + return AVERROR(ENOMEM); + } + + /* Set flags */ + pic->key_frame = 1; + pic->pict_type = FF_I_TYPE; + + /* Version should always be 1 */ + version = AV_RL32(src); + + if (version != 1) { + av_log(avctx, AV_LOG_ERROR, "Unsupported VBLE Version: %d\n", version); + return AVERROR_INVALIDDATA; + } + + init_get_bits(&gb, src + 4, (avpkt->size - 4) * 8); + + /* Unpack */ + if (vble_unpack(ctx, &gb) < 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid Code\n"); + return AVERROR_INVALIDDATA; + } + + /* Restore planes. Should be almost identical to Huffyuv's. */ + vble_restore_plane(ctx, 0, offset, avctx->width, avctx->height); + + /* Chroma */ + if (!(ctx->flags & CODEC_FLAG_GRAY)) { + offset += avctx->width * avctx->height; + vble_restore_plane(ctx, 1, offset, width_uv, height_uv); + + offset += width_uv * height_uv; + vble_restore_plane(ctx, 2, offset, width_uv, height_uv); + } + + *data_size = sizeof(AVFrame); + *(AVFrame *)data = *pic; + + return avpkt->size; +} + +static av_cold int vble_decode_close(AVCodecContext *avctx) +{ + VBLEContext *ctx = avctx->priv_data; + AVFrame *pic = avctx->coded_frame; + + if (pic->data[0]) + avctx->release_buffer(avctx, pic); + + av_freep(&avctx->coded_frame); + av_freep(&ctx->len); + av_freep(&ctx->val); + + return 0; +} + +static av_always_inline int vble_error_close(AVCodecContext *avctx, + const char *message) +{ + av_log(avctx, AV_LOG_ERROR, message); + vble_decode_close(avctx); + return AVERROR(ENOMEM); +} + +static av_cold int vble_decode_init(AVCodecContext *avctx) +{ + VBLEContext *ctx = avctx->priv_data; + + /* Stash for later use */ + ctx->avctx = avctx; + ctx->flags = avctx->flags; + + avctx->pix_fmt = PIX_FMT_YUV420P; + avctx->bits_per_raw_sample = 8; + avctx->coded_frame = avcodec_alloc_frame(); + + if (!avctx->coded_frame) + return vble_error_close(avctx, "Could not allocate frame.\n"); + + ctx->size = avpicture_get_size(avctx->pix_fmt, + avctx->width, avctx->height); + + ctx->len = av_malloc(ctx->size * sizeof(*ctx->len)); + + if (!ctx->len) + return vble_error_close(avctx, "Could not allocate lengths buffer.\n"); + + ctx->val = av_malloc(ctx->size * sizeof(*ctx->val)); + + if (!ctx->val) + return vble_error_close(avctx, "Could not allocate values buffer.\n"); + + return 0; +} + +AVCodec ff_vble_decoder = { + .name = "vble", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_VBLE, + .priv_data_size = sizeof(VBLEContext), + .init = vble_decode_init, + .close = vble_decode_close, + .decode = vble_decode_frame, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("VBLE Lossless Codec"), +}; diff --git a/libavcodec/version.h b/libavcodec/version.h index c11f09c9d4..756ad1d223 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -21,7 +21,7 @@ #define AVCODEC_VERSION_H #define LIBAVCODEC_VERSION_MAJOR 53 -#define LIBAVCODEC_VERSION_MINOR 18 +#define LIBAVCODEC_VERSION_MINOR 19 #define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ diff --git a/libavformat/riff.c b/libavformat/riff.c index 8eed7ce28e..29c3803173 100644 --- a/libavformat/riff.c +++ b/libavformat/riff.c @@ -279,6 +279,7 @@ const AVCodecTag ff_codec_bmp_tags[] = { { CODEC_ID_UTVIDEO, MKTAG('U', 'L', 'R', 'G') }, { CODEC_ID_UTVIDEO, MKTAG('U', 'L', 'Y', '0') }, { CODEC_ID_UTVIDEO, MKTAG('U', 'L', 'Y', '2') }, + { CODEC_ID_VBLE, MKTAG('V', 'B', 'L', 'E') }, { CODEC_ID_NONE, 0 } }; -- cgit v1.2.3 From 29ae0565d98bb41e54fc74f74c330d3214825f47 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Fri, 11 Nov 2011 21:57:06 +0100 Subject: vble: remove vble_error_close It does not make much sense to factor the error handling to its own av_always_inline function. Fixes "format not a string literal and no format arguments" warning in the av_log. --- libavcodec/vble.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/libavcodec/vble.c b/libavcodec/vble.c index 436402ded4..9589b535ec 100644 --- a/libavcodec/vble.c +++ b/libavcodec/vble.c @@ -196,14 +196,6 @@ static av_cold int vble_decode_close(AVCodecContext *avctx) return 0; } -static av_always_inline int vble_error_close(AVCodecContext *avctx, - const char *message) -{ - av_log(avctx, AV_LOG_ERROR, message); - vble_decode_close(avctx); - return AVERROR(ENOMEM); -} - static av_cold int vble_decode_init(AVCodecContext *avctx) { VBLEContext *ctx = avctx->priv_data; @@ -216,21 +208,29 @@ static av_cold int vble_decode_init(AVCodecContext *avctx) avctx->bits_per_raw_sample = 8; avctx->coded_frame = avcodec_alloc_frame(); - if (!avctx->coded_frame) - return vble_error_close(avctx, "Could not allocate frame.\n"); + if (!avctx->coded_frame) { + av_log(avctx, AV_LOG_ERROR, "Could not allocate frame.\n"); + return AVERROR(ENOMEM); + } ctx->size = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height); ctx->len = av_malloc(ctx->size * sizeof(*ctx->len)); - if (!ctx->len) - return vble_error_close(avctx, "Could not allocate lengths buffer.\n"); + if (!ctx->len) { + av_log(avctx, AV_LOG_ERROR, "Could not allocate lengths buffer.\n"); + vble_decode_close(avctx); + return AVERROR(ENOMEM); + } ctx->val = av_malloc(ctx->size * sizeof(*ctx->val)); - if (!ctx->val) - return vble_error_close(avctx, "Could not allocate values buffer.\n"); + if (!ctx->val) { + av_log(avctx, AV_LOG_ERROR, "Could not allocate values buffer.\n"); + vble_decode_close(avctx); + return AVERROR(ENOMEM); + } return 0; } -- cgit v1.2.3