diff options
-rw-r--r-- | Changelog | 3 | ||||
-rwxr-xr-x | configure | 2 | ||||
-rw-r--r-- | doc/general.texi | 1 | ||||
-rw-r--r-- | ffplay.c | 29 | ||||
-rw-r--r-- | libavcodec/8svx.c | 4 | ||||
-rw-r--r-- | libavcodec/Makefile | 3 | ||||
-rw-r--r-- | libavcodec/allcodecs.c | 3 | ||||
-rw-r--r-- | libavcodec/proresdec.c | 632 | ||||
-rw-r--r-- | libavcodec/version.h | 2 | ||||
-rw-r--r-- | libavformat/Makefile | 1 | ||||
-rw-r--r-- | libavformat/allformats.c | 2 | ||||
-rw-r--r-- | libavformat/iff.c | 3 | ||||
-rw-r--r-- | libavformat/isom.c | 2 | ||||
-rw-r--r-- | libavformat/rawdec.c | 12 | ||||
-rw-r--r-- | libavformat/rtmpproto.c | 61 | ||||
-rw-r--r-- | libavformat/version.h | 2 | ||||
-rw-r--r-- | libavutil/eval.c | 2 | ||||
-rwxr-xr-x | tests/fate.sh | 4 | ||||
-rw-r--r-- | tests/ref/fate/eval | 4 |
19 files changed, 85 insertions, 687 deletions
@@ -47,7 +47,7 @@ easier to use. The changes are: - ashowinfo filter added - Windows Media Image decoder - amovie source added -- LATM muxer +- LATM muxer/demuxer - Speex encoder via libspeex - JSON output in ffprobe - WTV muxer @@ -58,6 +58,7 @@ easier to use. The changes are: - aconvert audio filter added - audio support to lavfi input device added - libcdio-paranoia input device for audio CD grabbing +- Apple ProRes decoder version 0.8: @@ -1415,7 +1415,7 @@ nellymoser_decoder_select="mdct sinewin" nellymoser_encoder_select="mdct sinewin" png_decoder_select="zlib" png_encoder_select="zlib" -prores_decoder_deps="version2 gpl" +prores_gpl_decoder_deps="version2 gpl" qcelp_decoder_select="lsp" qdm2_decoder_select="mdct rdft mpegaudiodsp" ra_144_encoder_select="lpc" diff --git a/doc/general.texi b/doc/general.texi index 85b65c5daa..768db21ae1 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -347,6 +347,7 @@ following image formats are supported: @tab Used in Chinese MP3 players. @item ANSI/ASCII art @tab @tab X @item Apple MJPEG-B @tab @tab X +@item Apple ProRes @tab @tab X @item Apple QuickDraw @tab @tab X @tab fourcc: qdrw @item Asus v1 @tab X @tab X @@ -1994,10 +1994,15 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr) AVCodecContext *dec= is->audio_st->codec; int n, len1, data_size; double pts; + int new_packet = 0; + int flush_complete = 0; for(;;) { /* NOTE: the audio packet can contain several frames */ - while (pkt_temp->size > 0) { + while (pkt_temp->size > 0 || (!pkt_temp->data && new_packet)) { + if (flush_complete) + break; + new_packet = 0; data_size = sizeof(is->audio_buf1); len1 = avcodec_decode_audio3(dec, (int16_t *)is->audio_buf1, &data_size, @@ -2010,8 +2015,13 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr) pkt_temp->data += len1; pkt_temp->size -= len1; - if (data_size <= 0) + + if (data_size <= 0) { + /* stop sending empty packets if the decoder is finished */ + if (!pkt_temp->data && dec->codec->capabilities & CODEC_CAP_DELAY) + flush_complete = 1; continue; + } if (dec->sample_fmt != is->audio_src_fmt) { if (is->reformat_ctx) @@ -2072,12 +2082,11 @@ static int audio_decode_frame(VideoState *is, double *pts_ptr) } /* read next packet */ - if (packet_queue_get(&is->audioq, pkt, 1) < 0) + if ((new_packet = packet_queue_get(&is->audioq, pkt, 1)) < 0) return -1; - if(pkt->data == flush_pkt.data){ + + if (pkt->data == flush_pkt.data) avcodec_flush_buffers(dec); - continue; - } pkt_temp->data = pkt->data; pkt_temp->size = pkt->size; @@ -2508,6 +2517,14 @@ static int read_thread(void *arg) pkt->stream_index= is->video_stream; packet_queue_put(&is->videoq, pkt); } + if (is->audio_stream >= 0 && + is->audio_st->codec->codec->capabilities & CODEC_CAP_DELAY) { + av_init_packet(pkt); + pkt->data = NULL; + pkt->size = 0; + pkt->stream_index = is->audio_stream; + packet_queue_put(&is->audioq, pkt); + } SDL_Delay(10); if(is->audioq.size + is->videoq.size + is->subtitleq.size ==0){ if(loop!=1 && (!loop || --loop)){ diff --git a/libavcodec/8svx.c b/libavcodec/8svx.c index 3864d61857..5c68d347e2 100644 --- a/libavcodec/8svx.c +++ b/libavcodec/8svx.c @@ -121,6 +121,10 @@ static int eightsvx_decode_frame(AVCodecContext *avctx, void *data, int *data_si int buf_size = avpkt->size; int n = esc->samples_size; + if (buf_size < 2) { + av_log(avctx, AV_LOG_ERROR, "packet size is too small\n"); + return AVERROR(EINVAL); + } if (!(deinterleaved_samples = av_mallocz(n))) return AVERROR(ENOMEM); diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 408317ebfc..3503f4b48c 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -309,7 +309,8 @@ OBJS-$(CONFIG_PNG_DECODER) += png.o pngdec.o OBJS-$(CONFIG_PNG_ENCODER) += png.o pngenc.o OBJS-$(CONFIG_PPM_DECODER) += pnmdec.o pnm.o OBJS-$(CONFIG_PPM_ENCODER) += pnmenc.o pnm.o -OBJS-$(CONFIG_PRORES_DECODER) += proresdec.o +OBJS-$(CONFIG_PRORES_GPL_DECODER) += proresdec_gpl.o +OBJS-$(CONFIG_PRORES_LGPL_DECODER) += proresdec_lgpl.o OBJS-$(CONFIG_PTX_DECODER) += ptx.o OBJS-$(CONFIG_QCELP_DECODER) += qcelpdec.o celp_math.o \ celp_filters.o acelp_vectors.o \ diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index a714e9529f..fb6094291c 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -172,7 +172,8 @@ void avcodec_register_all(void) REGISTER_DECODER (PICTOR, pictor); REGISTER_ENCDEC (PNG, png); REGISTER_ENCDEC (PPM, ppm); - REGISTER_DECODER (PRORES, prores); + REGISTER_DECODER (PRORES_GPL, prores_gpl); + REGISTER_DECODER (PRORES_LGPL, prores_lgpl); REGISTER_DECODER (PTX, ptx); REGISTER_DECODER (QDRAW, qdraw); REGISTER_DECODER (QPEG, qpeg); diff --git a/libavcodec/proresdec.c b/libavcodec/proresdec.c deleted file mode 100644 index fc7a55bfc8..0000000000 --- a/libavcodec/proresdec.c +++ /dev/null @@ -1,632 +0,0 @@ -/* - * Copyright (c) 2010-2011 Maxim Poliakovski - * Copyright (c) 2010-2011 Elvis Presley - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; - * version 2 of the License. - * - * 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 - * General Public License for more details. - * - * You should have received a copy of the GNU 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 - */ - -/** - * @file libavcodec/proresdec.c - * Known FOURCCs: 'apch' (HQ), 'apcn' (SD), 'apcs' (LT), 'acpo' (Proxy), 'ap4c' (4444) - */ - -//#define DEBUG - -#define A32_BITSTREAM_READER - -#include "avcodec.h" -#include "get_bits.h" -#include "dsputil.h" -#include "simple_idct.h" - -typedef struct { - const uint8_t *data; - unsigned mb_x; - unsigned mb_y; - unsigned mb_count; - unsigned data_size; -} SliceContext; - -typedef struct { - AVFrame frame; - DSPContext dsp; - int frame_type; ///< 0 = progressive, 1 = tff, 2 = bff - uint8_t qmat_luma[64]; - uint8_t qmat_chroma[64]; - SliceContext *slices; - int slice_count; ///< number of slices in the current picture - unsigned mb_width; ///< width of the current picture in mb - unsigned mb_height; ///< height of the current picture in mb - uint8_t progressive_scan[64]; - uint8_t interlaced_scan[64]; - const uint8_t *scan; - int first_field; - void (*idct_put)(DCTELEM *, uint8_t *restrict, int); -} ProresContext; - -static void permute(uint8_t *dst, const uint8_t *src, const uint8_t permutation[64]) -{ - int i; - for (i = 0; i < 64; i++) - dst[i] = permutation[src[i]]; -} - -static av_always_inline void put_pixels(const DCTELEM *block, uint8_t *restrict pixels, int stride) -{ - int16_t *p = (int16_t*)pixels; - int i, j; - - stride >>= 1; - for(i = 0; i < 8; i++) { - for (j = 0; j < 8; j++) { - p[j] = av_clip(block[j], 4, 1019); - } - p += stride; - block += 8; - } -} - -static void idct_put(DCTELEM *block, uint8_t *restrict pixels, int stride) -{ - ff_simple_idct_10(block); - put_pixels(block, pixels, stride); -} - -static const uint8_t progressive_scan[64] = { - 0, 1, 8, 9, 2, 3, 10, 11, - 16, 17, 24, 25, 18, 19, 26, 27, - 4, 5, 12, 20, 13, 6, 7, 14, - 21, 28, 29, 22, 15, 23, 30, 31, - 32, 33, 40, 48, 41, 34, 35, 42, - 49, 56, 57, 50, 43, 36, 37, 44, - 51, 58, 59, 52, 45, 38, 39, 46, - 53, 60, 61, 54, 47, 55, 62, 63 -}; - -static const uint8_t interlaced_scan[64] = { - 0, 8, 1, 9, 16, 24, 17, 25, - 2, 10, 3, 11, 18, 26, 19, 27, - 32, 40, 33, 34, 41, 48, 56, 49, - 42, 35, 43, 50, 57, 58, 51, 59, - 4, 12, 5, 6, 13, 20, 28, 21, - 14, 7, 15, 22, 29, 36, 44, 37, - 30, 23, 31, 38, 45, 52, 60, 53, - 46, 39, 47, 54, 61, 62, 55, 63, -}; - -static av_cold int decode_init(AVCodecContext *avctx) -{ - ProresContext *ctx = avctx->priv_data; - - avctx->bits_per_raw_sample = 10; - - dsputil_init(&ctx->dsp, avctx); - - avctx->coded_frame = &ctx->frame; - ctx->frame.type = FF_I_TYPE; - ctx->frame.key_frame = 1; - - ctx->idct_put = idct_put; - memcpy(ctx->progressive_scan, progressive_scan, sizeof(progressive_scan)); - memcpy(ctx->interlaced_scan, interlaced_scan, sizeof(interlaced_scan)); - - return 0; -} - -static int decode_frame_header(ProresContext *ctx, const uint8_t *buf, - const int data_size, AVCodecContext *avctx) -{ - int hdr_size, width, height, flags; - int version; - const uint8_t *ptr; - const uint8_t *scan; - - hdr_size = AV_RB16(buf); - av_dlog(avctx, "header size %d\n", hdr_size); - if (hdr_size > data_size) { - av_log(avctx, AV_LOG_ERROR, "error, wrong header size\n"); - return -1; - } - - version = AV_RB16(buf + 2); - av_dlog(avctx, "%.4s version %d\n", buf+4, version); - if (version > 1) { - av_log(avctx, AV_LOG_ERROR, "unsupported version: %d\n", version); - return -1; - } - - width = AV_RB16(buf + 8); - height = AV_RB16(buf + 10); - if (width != avctx->width || height != avctx->height) { - av_log(avctx, AV_LOG_ERROR, "picture resolution change: %dx%d -> %dx%d\n", - avctx->width, avctx->height, width, height); - return -1; - } - - ctx->frame_type = (buf[12] >> 2) & 3; - - av_dlog(avctx, "frame type %d\n", ctx->frame_type); - - if (ctx->frame_type == 0) { - scan = progressive_scan; - ctx->scan = ctx->progressive_scan; // permuted - } else { - scan = interlaced_scan; - ctx->scan = ctx->interlaced_scan; // permuted - ctx->frame.interlaced_frame = 1; - ctx->frame.top_field_first = ctx->frame_type == 1; - } - - avctx->pix_fmt = ((buf[12] & 0xC0) == 0xC0) ? PIX_FMT_YUV444P10 : PIX_FMT_YUV422P10; - - ptr = buf + 20; - flags = buf[19]; - av_dlog(avctx, "flags %x\n", flags); - - if (flags & 2) { - permute(ctx->qmat_luma, scan, ptr); - ptr += 64; - } else { - memset(ctx->qmat_luma, 4, 64); - } - - if (flags & 1) { - permute(ctx->qmat_chroma, scan, ptr); - } else { - memset(ctx->qmat_chroma, 4, 64); - } - - return hdr_size; -} - -static int decode_picture_header(AVCodecContext *avctx, const uint8_t *buf, const int buf_size) -{ - ProresContext *ctx = avctx->priv_data; - int i, hdr_size, slice_count; - unsigned pic_data_size; - int log2_slice_mb_width, log2_slice_mb_height; - int slice_mb_count, mb_x, mb_y; - const uint8_t *data_ptr, *index_ptr; - - hdr_size = buf[0] >> 3; - if (hdr_size < 8 || hdr_size > buf_size) { - av_log(avctx, AV_LOG_ERROR, "error, wrong picture header size\n"); - return -1; - } - - pic_data_size = AV_RB32(buf + 1); - if (pic_data_size > buf_size) { - av_log(avctx, AV_LOG_ERROR, "error, wrong picture data size\n"); - return -1; - } - - log2_slice_mb_width = buf[7] >> 4; - log2_slice_mb_height = buf[7] & 0xF; - if (log2_slice_mb_width > 3 || log2_slice_mb_height) { - av_log(avctx, AV_LOG_ERROR, "unsupported slice resolution: %dx%d\n", - 1 << log2_slice_mb_width, 1 << log2_slice_mb_height); - return -1; - } - - ctx->mb_width = (avctx->width + 15) >> 4; - ctx->mb_height = (avctx->height + 15) >> 4; - - slice_count = AV_RB16(buf + 5); - - if (ctx->slice_count != slice_count || !ctx->slices) { - av_freep(&ctx->slices); - ctx->slices = av_mallocz(slice_count * sizeof(*ctx->slices)); - if (!ctx->slices) - return AVERROR(ENOMEM); - ctx->slice_count = slice_count; - } - - if (!slice_count) - return AVERROR(EINVAL); - - if (hdr_size + slice_count*2 > buf_size) { - av_log(avctx, AV_LOG_ERROR, "error, wrong slice count\n"); - return -1; - } - - // parse slice information - index_ptr = buf + hdr_size; - data_ptr = index_ptr + slice_count*2; - - slice_mb_count = 1 << log2_slice_mb_width; - mb_x = 0; - mb_y = 0; - - for (i = 0; i < slice_count; i++) { - SliceContext *slice = &ctx->slices[i]; - - slice->data = data_ptr; - data_ptr += AV_RB16(index_ptr + i*2); - - while (ctx->mb_width - mb_x < slice_mb_count) - slice_mb_count >>= 1; - - slice->mb_x = mb_x; - slice->mb_y = mb_y; - slice->mb_count = slice_mb_count; - slice->data_size = data_ptr - slice->data; - - if (slice->data_size < 6) { - av_log(avctx, AV_LOG_ERROR, "error, wrong slice data size\n"); - return -1; - } - - mb_x += slice_mb_count; - if (mb_x == ctx->mb_width) { - slice_mb_count = 1 << log2_slice_mb_width; - mb_x = 0; - mb_y++; - } - if (data_ptr > buf + buf_size) { - av_log(avctx, AV_LOG_ERROR, "error, slice out of bounds\n"); - return -1; - } - } - - return pic_data_size; -} - -#define DECODE_CODEWORD(val, codebook) \ - do { \ - unsigned int rice_order, exp_order, switch_bits; \ - unsigned int q, buf, bits; \ - \ - UPDATE_CACHE(re, gb); \ - buf = GET_CACHE(re, gb); \ - \ - /* number of bits to switch between rice and exp golomb */ \ - switch_bits = codebook & 3; \ - rice_order = codebook >> 5; \ - exp_order = (codebook >> 2) & 7; \ - \ - q = 31-av_log2(buf); \ - \ - if (q > switch_bits) { /* exp golomb */ \ - bits = exp_order - switch_bits + (q<<1); \ - val = SHOW_UBITS(re, gb, bits) - (1 << exp_order) + \ - ((switch_bits + 1) << rice_order); \ - SKIP_BITS(re, gb, bits); \ - } else if (rice_order) { \ - SKIP_BITS(re, gb, q+1); \ - val = (q << rice_order) + SHOW_UBITS(re, gb, rice_order); \ - SKIP_BITS(re, gb, rice_order); \ - } else { \ - val = q; \ - SKIP_BITS(re, gb, q+1); \ - } \ - } while (0); \ - -#define TOSIGNED(x) (((x) >> 1) ^ (-((x) & 1))) - -#define FIRST_DC_CB 0xB8 - -static const uint8_t dc_codebook[7] = { 0x04, 0x28, 0x28, 0x4D, 0x4D, 0x70, 0x70}; - -static av_always_inline void decode_dc_coeffs(GetBitContext *gb, DCTELEM *out, - int blocks_per_slice, const int *qmat) -{ - DCTELEM prev_dc; - int code, i, sign; - - OPEN_READER(re, gb); - - DECODE_CODEWORD(code, FIRST_DC_CB); - prev_dc = TOSIGNED(code); - out[0] = 4096 + ((prev_dc * qmat[0]) >> 2); - - out += 64; // dc coeff for the next block - - code = 5; - sign = 0; - for (i = 1; i < blocks_per_slice; i++, out += 64) { - DECODE_CODEWORD(code, dc_codebook[FFMIN(code, 6)]); - if(code) sign ^= -(code & 1); - else sign = 0; - prev_dc += (((code + 1) >> 1) ^ sign) - sign; - out[0] = 4096 + ((prev_dc * qmat[0]) >> 2); - } - CLOSE_READER(re, gb); -} - -// adaptive codebook switching lut according to previous run/level values -static const uint8_t run_to_cb[16] = { 0x06, 0x06, 0x05, 0x05, 0x04, 0x29, 0x29, 0x29, 0x29, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x4C }; -static const uint8_t lev_to_cb[10] = { 0x04, 0x0A, 0x05, 0x06, 0x04, 0x28, 0x28, 0x28, 0x28, 0x4C }; - -static av_always_inline void decode_ac_coeffs(AVCodecContext *avctx, GetBitContext *gb, - DCTELEM *out, int blocks_per_slice, - const int *qmat) -{ - ProresContext *ctx = avctx->priv_data; - int block_mask, sign; - unsigned pos, run, level; - int max_coeffs, i, bits_left; - int log2_block_count = av_log2(blocks_per_slice); - - OPEN_READER(re, gb); - - run = 4; - level = 2; - - max_coeffs = 64 << log2_block_count; - block_mask = blocks_per_slice - 1; - - for (pos = block_mask;;) { - bits_left = gb->size_in_bits - (((uint8_t*)re_buffer_ptr - gb->buffer)*8 - 32 + re_bit_count); - if (!bits_left || (bits_left < 32 && !SHOW_UBITS(re, gb, bits_left))) - break; - - DECODE_CODEWORD(run, run_to_cb[FFMIN(run, 15)]); - pos += run + 1; - if (pos >= max_coeffs) { - av_log(avctx, AV_LOG_ERROR, "ac tex damaged %d, %d\n", pos, max_coeffs); - return; - } - - DECODE_CODEWORD(level, lev_to_cb[FFMIN(level, 9)]); - level += 1; - - i = pos >> log2_block_count; - - sign = SHOW_SBITS(re, gb, 1); - SKIP_BITS(re, gb, 1); - out[((pos & block_mask) << 6) + ctx->scan[i]] = (((level ^ sign) - sign) * qmat[i]) >> 2; - } - - CLOSE_READER(re, gb); -} - -static void decode_slice_luma(AVCodecContext *avctx, SliceContext *slice, - uint8_t *dst, int dst_stride, - const uint8_t *buf, unsigned buf_size, - const int *qmat) -{ - ProresContext *ctx = avctx->priv_data; - LOCAL_ALIGNED_16(DCTELEM, blocks, [8*4*64]); - DCTELEM *block; - GetBitContext gb; - int i, blocks_per_slice = slice->mb_count<<2; - - for (i = 0; i < blocks_per_slice; i++) - ctx->dsp.clear_block(blocks+(i<<6)); - - init_get_bits(&gb, buf, buf_size << 3); - - decode_dc_coeffs(&gb, blocks, blocks_per_slice, qmat); - decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice, qmat); - - block = blocks; - - for (i = 0; i < slice->mb_count; i++) { - ctx->idct_put(block+(0<<6), dst, dst_stride); - ctx->idct_put(block+(1<<6), dst+16, dst_stride); - ctx->idct_put(block+(2<<6), dst+8*dst_stride, dst_stride); - ctx->idct_put(block+(3<<6), dst+8*dst_stride+16, dst_stride); - block += 4*64; - dst += 32; - } - -} - -static void decode_slice_chroma(AVCodecContext *avctx, SliceContext *slice, - uint8_t *dst, int dst_stride, - const uint8_t *buf, unsigned buf_size, - const int *qmat, int log2_blocks_per_mb) -{ - ProresContext *ctx = avctx->priv_data; - LOCAL_ALIGNED_16(DCTELEM, blocks, [8*4*64]); - DCTELEM *block; - GetBitContext gb; - int i, j, blocks_per_slice = slice->mb_count << log2_blocks_per_mb; - - for (i = 0; i < blocks_per_slice; i++) - ctx->dsp.clear_block(blocks+(i<<6)); - - init_get_bits(&gb, buf, buf_size << 3); - - decode_dc_coeffs(&gb, blocks, blocks_per_slice, qmat); - decode_ac_coeffs(avctx, &gb, blocks, blocks_per_slice, qmat); - - block = blocks; - for (i = 0; i < slice->mb_count; i++) { - for (j = 0; j < log2_blocks_per_mb; j++) { - ctx->idct_put(block+(0<<6), dst, dst_stride); - ctx->idct_put(block+(1<<6), dst+8*dst_stride, dst_stride); - block += 2*64; - dst += 16; - } - } -} - -static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int threadnr) -{ - ProresContext *ctx = avctx->priv_data; - SliceContext *slice = &ctx->slices[jobnr]; - const uint8_t *buf = slice->data; - AVFrame *pic = avctx->coded_frame; - int i, hdr_size, qscale, log2_chroma_blocks_per_mb; - int luma_stride, chroma_stride; - int y_data_size, u_data_size, v_data_size; - uint8_t *dest_y, *dest_u, *dest_v; - int qmat_luma_scaled[64]; - int qmat_chroma_scaled[64]; - int mb_x_shift; - - //av_log(avctx, AV_LOG_INFO, "slice %d mb width %d mb x %d y %d\n", - // jobnr, slice->mb_count, slice->mb_x, slice->mb_y); - - // slice header - hdr_size = buf[0] >> 3; - qscale = av_clip(buf[1], 1, 224); - qscale = qscale > 128 ? qscale - 96 << 2: qscale; - y_data_size = AV_RB16(buf + 2); - u_data_size = AV_RB16(buf + 4); - v_data_size = slice->data_size - y_data_size - u_data_size - hdr_size; - if (hdr_size > 7) v_data_size = AV_RB16(buf + 6); - - if (y_data_size < 0 || u_data_size < 0 || v_data_size < 0) { - av_log(avctx, AV_LOG_ERROR, "invalid plane data size\n"); - return -1; - } - - buf += hdr_size; - - for (i = 0; i < 64; i++) { - qmat_luma_scaled[i] = ctx->qmat_luma[i] * qscale; - qmat_chroma_scaled[i] = ctx->qmat_chroma[i] * qscale; - } - - if (ctx->frame_type == 0) { - luma_stride = pic->linesize[0]; - chroma_stride = pic->linesize[1]; - } else { - luma_stride = pic->linesize[0] << 1; - chroma_stride = pic->linesize[1] << 1; - } - - if (avctx->pix_fmt == PIX_FMT_YUV444P10) { - mb_x_shift = 5; - log2_chroma_blocks_per_mb = 2; - } else { - mb_x_shift = 4; - log2_chroma_blocks_per_mb = 1; - } - - dest_y = pic->data[0] + (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5); - dest_u = pic->data[1] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift); - dest_v = pic->data[2] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift); - - if (ctx->frame_type && ctx->first_field ^ ctx->frame.top_field_first) { - dest_y += pic->linesize[0]; - dest_u += pic->linesize[1]; - dest_v += pic->linesize[2]; - } - - decode_slice_luma(avctx, slice, dest_y, luma_stride, - buf, y_data_size, qmat_luma_scaled); - - if (!(avctx->flags & CODEC_FLAG_GRAY)) { - decode_slice_chroma(avctx, slice, dest_u, chroma_stride, - buf + y_data_size, u_data_size, - qmat_chroma_scaled, log2_chroma_blocks_per_mb); - decode_slice_chroma(avctx, slice, dest_v, chroma_stride, - buf + y_data_size + u_data_size, v_data_size, - qmat_chroma_scaled, log2_chroma_blocks_per_mb); - } - - return 0; -} - -static int decode_picture(AVCodecContext *avctx) -{ - ProresContext *ctx = avctx->priv_data; - int i, threads_ret[ctx->slice_count]; - - avctx->execute2(avctx, decode_slice_thread, NULL, threads_ret, ctx->slice_count); - - for (i = 0; i < ctx->slice_count; i++) - if (threads_ret[i] < 0) - return threads_ret[i]; - - return 0; -} - -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - AVPacket *avpkt) -{ - ProresContext *ctx = avctx->priv_data; - AVFrame *frame = avctx->coded_frame; - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - int frame_hdr_size, pic_size; - - if (buf_size < 28 || AV_RL32(buf + 4) != AV_RL32("icpf")) { - av_log(avctx, AV_LOG_ERROR, "invalid frame header\n"); - return -1; - } - - ctx->first_field = 1; - - buf += 8; - buf_size -= 8; - - frame_hdr_size = decode_frame_header(ctx, buf, buf_size, avctx); - if (frame_hdr_size < 0) - return -1; - - buf += frame_hdr_size; - buf_size -= frame_hdr_size; - - decode_picture: - pic_size = decode_picture_header(avctx, buf, buf_size); - if (pic_size < 0) { - av_log(avctx, AV_LOG_ERROR, "error decoding picture header\n"); - return -1; - } - - if (frame->data[0]) - avctx->release_buffer(avctx, frame); - - if (avctx->get_buffer(avctx, frame) < 0) - return -1; - - if (decode_picture(avctx)) { - av_log(avctx, AV_LOG_ERROR, "error decoding picture\n"); - return -1; - } - - buf += pic_size; - buf_size -= pic_size; - - if (ctx->frame_type && buf_size > 0 && ctx->first_field) { - ctx->first_field = 0; - goto decode_picture; - } - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = *frame; - - return avpkt->size; -} - -static av_cold int decode_close(AVCodecContext *avctx) -{ - ProresContext *ctx = avctx->priv_data; - - AVFrame *frame = avctx->coded_frame; - if (frame->data[0]) - avctx->release_buffer(avctx, frame); - av_freep(&ctx->slices); - - return 0; -} - -AVCodec ff_prores_decoder = { - .name = "prores", - .type = AVMEDIA_TYPE_VIDEO, - .id = CODEC_ID_PRORES, - .priv_data_size = sizeof(ProresContext), - .init = decode_init, - .close = decode_close, - .decode = decode_frame, - .long_name = NULL_IF_CONFIG_SMALL("ProRes"), - .capabilities = CODEC_CAP_SLICE_THREADS, -}; diff --git a/libavcodec/version.h b/libavcodec/version.h index bca20f6ad1..2bc5c9b70f 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 16 +#define LIBAVCODEC_VERSION_MINOR 17 #define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ diff --git a/libavformat/Makefile b/libavformat/Makefile index 635352961b..cc5a964d17 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -115,6 +115,7 @@ OBJS-$(CONFIG_IV8_DEMUXER) += iv8.o OBJS-$(CONFIG_IVF_DEMUXER) += ivfdec.o riff.o OBJS-$(CONFIG_IVF_MUXER) += ivfenc.o OBJS-$(CONFIG_JV_DEMUXER) += jvdec.o +OBJS-$(CONFIG_LATM_DEMUXER) += rawdec.o OBJS-$(CONFIG_LATM_MUXER) += latmenc.o OBJS-$(CONFIG_LMLM4_DEMUXER) += lmlm4.o OBJS-$(CONFIG_LOAS_DEMUXER) += loasdec.o diff --git a/libavformat/allformats.c b/libavformat/allformats.c index e725b37be5..ecc7c675b9 100644 --- a/libavformat/allformats.c +++ b/libavformat/allformats.c @@ -116,7 +116,7 @@ void av_register_all(void) REGISTER_DEMUXER (IV8, iv8); REGISTER_MUXDEMUX (IVF, ivf); REGISTER_DEMUXER (JV, jv); - REGISTER_MUXER (LATM, latm); + REGISTER_MUXDEMUX (LATM, latm); REGISTER_DEMUXER (LMLM4, lmlm4); REGISTER_DEMUXER (LOAS, loas); REGISTER_DEMUXER (LXF, lxf); diff --git a/libavformat/iff.c b/libavformat/iff.c index 9455d96817..ebc4798feb 100644 --- a/libavformat/iff.c +++ b/libavformat/iff.c @@ -85,7 +85,6 @@ typedef struct { uint64_t body_pos; uint32_t body_size; uint32_t sent_bytes; - uint32_t audio_frame_count; svx8_compression_type svx8_compression; bitmap_compression_type bitmap_compression; ///< delta compression method used unsigned bpp; ///< bits per plane to decode (differs from bits_per_coded_sample if HAM) @@ -313,7 +312,7 @@ static int iff_read_packet(AVFormatContext *s, int ret; if(iff->sent_bytes >= iff->body_size) - return AVERROR(EIO); + return AVERROR_EOF; if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { ret = av_get_packet(pb, pkt, iff->body_size); diff --git a/libavformat/isom.c b/libavformat/isom.c index 4f2166ae50..454f9523da 100644 --- a/libavformat/isom.c +++ b/libavformat/isom.c @@ -425,7 +425,7 @@ int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, AVIOContext len = ff_mp4_read_descr(fc, pb, &tag); if (tag == MP4DecSpecificDescrTag) { av_dlog(fc, "Specific MPEG4 header len=%d\n", len); - if((uint64_t)len > (1<<30)) + if (!len || (uint64_t)len > (1<<30)) return -1; av_free(st->codec->extradata); st->codec->extradata = av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE); diff --git a/libavformat/rawdec.c b/libavformat/rawdec.c index c02ad90aee..4fc48ed586 100644 --- a/libavformat/rawdec.c +++ b/libavformat/rawdec.c @@ -199,6 +199,18 @@ AVInputFormat ff_gsm_demuxer = { }; #endif +#if CONFIG_LATM_DEMUXER +AVInputFormat ff_latm_demuxer = { + .name = "latm", + .long_name = NULL_IF_CONFIG_SMALL("raw LOAS/LATM"), + .read_header = ff_raw_audio_read_header, + .read_packet = ff_raw_read_partial_packet, + .flags= AVFMT_GENERIC_INDEX, + .extensions = "latm", + .value = CODEC_ID_AAC_LATM, +}; +#endif + #if CONFIG_MJPEG_DEMUXER FF_DEF_RAWVIDEO_DEMUXER(mjpeg, "raw MJPEG video", NULL, "mjpg,mjpeg", CODEC_ID_MJPEG) #endif diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index 920ca44c34..ed483cf37f 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -72,6 +72,8 @@ typedef struct RTMPContext { uint32_t bytes_read; ///< number of bytes read from server uint32_t last_bytes_read; ///< number of bytes read last reported to server int skip_bytes; ///< number of bytes to skip from the input FLV stream in the next write call + uint8_t flv_header[11]; ///< partial incoming flv packet header + int flv_header_bytes; ///< number of initialized bytes in flv_header } RTMPContext; #define PLAYER_KEY_OPEN_PART_LEN 30 ///< length of partial key used for first client digest signing @@ -880,6 +882,7 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) rt->flv_size = 0; rt->flv_data = NULL; rt->flv_off = 0; + rt->skip_bytes = 13; } s->max_packet_size = rt->stream->max_packet_size; @@ -926,34 +929,29 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size) uint32_t ts; const uint8_t *buf_temp = buf; - if (rt->skip_bytes) { - int skip = FFMIN(rt->skip_bytes, size); - buf_temp += skip; - size_temp -= skip; - rt->skip_bytes -= skip; - if (size_temp <= 0) - return size; - } - - if (!rt->flv_off && size_temp < 11) { - av_log(s, AV_LOG_DEBUG, "FLV packet too small %d\n", size); - return 0; - } - do { - if (!rt->flv_off) { - //skip flv header - if (buf_temp[0] == 'F' && buf_temp[1] == 'L' && buf_temp[2] == 'V') { - buf_temp += 9 + 4; - size_temp -= 9 + 4; - } + if (rt->skip_bytes) { + int skip = FFMIN(rt->skip_bytes, size_temp); + buf_temp += skip; + size_temp -= skip; + rt->skip_bytes -= skip; + continue; + } + + if (rt->flv_header_bytes < 11) { + const uint8_t *header = rt->flv_header; + int copy = FFMIN(11 - rt->flv_header_bytes, size_temp); + bytestream_get_buffer(&buf_temp, rt->flv_header + rt->flv_header_bytes, copy); + rt->flv_header_bytes += copy; + size_temp -= copy; + if (rt->flv_header_bytes < 11) + break; - pkttype = bytestream_get_byte(&buf_temp); - pktsize = bytestream_get_be24(&buf_temp); - ts = bytestream_get_be24(&buf_temp); - ts |= bytestream_get_byte(&buf_temp) << 24; - bytestream_get_be24(&buf_temp); - size_temp -= 11; + pkttype = bytestream_get_byte(&header); + pktsize = bytestream_get_be24(&header); + ts = bytestream_get_be24(&header); + ts |= bytestream_get_byte(&header) << 24; + bytestream_get_be24(&header); rt->flv_size = pktsize; //force 12bytes header @@ -984,18 +982,13 @@ static int rtmp_write(URLContext *s, const uint8_t *buf, int size) } if (rt->flv_off == rt->flv_size) { - if (size_temp < 4) { - rt->skip_bytes = 4 - size_temp; - buf_temp += size_temp; - size_temp = 0; - } else { - bytestream_get_be32(&buf_temp); - size_temp -= 4; - } + rt->skip_bytes = 4; + ff_rtmp_packet_write(rt->stream, &rt->out_pkt, rt->chunk_size, rt->prev_pkt[1]); ff_rtmp_packet_destroy(&rt->out_pkt); rt->flv_size = 0; rt->flv_off = 0; + rt->flv_header_bytes = 0; } } while (buf_temp - buf < size); return size; diff --git a/libavformat/version.h b/libavformat/version.h index 2e4e50a865..cf988102f9 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -24,7 +24,7 @@ #include "libavutil/avutil.h" #define LIBAVFORMAT_VERSION_MAJOR 53 -#define LIBAVFORMAT_VERSION_MINOR 12 +#define LIBAVFORMAT_VERSION_MINOR 13 #define LIBAVFORMAT_VERSION_MICRO 0 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ diff --git a/libavutil/eval.c b/libavutil/eval.c index 4e2cb1095c..7ddb1f83c0 100644 --- a/libavutil/eval.c +++ b/libavutil/eval.c @@ -644,7 +644,7 @@ int main(int argc, char **argv) "ceil(123.123)", "ceil(-123.123)", "sqrt(1764)", - "sqrt(-1)", + "isnan(sqrt(-1))", "not(1)", "not(NAN)", "not(0)", diff --git a/tests/fate.sh b/tests/fate.sh index 9fd117c3bc..e04c8710d7 100755 --- a/tests/fate.sh +++ b/tests/fate.sh @@ -35,7 +35,7 @@ checkout(){ update()( cd ${src} || return case "$repo" in - git:*) git pull ;; + git:*) git pull --quiet ;; esac ) @@ -70,7 +70,7 @@ fate()( ) clean(){ - rm -r ${build} ${inst} + rm -rf ${build} ${inst} } report(){ diff --git a/tests/ref/fate/eval b/tests/ref/fate/eval index 3bc35db633..88d7e17bee 100644 --- a/tests/ref/fate/eval +++ b/tests/ref/fate/eval @@ -136,8 +136,8 @@ Evaluating 'ceil(-123.123)' Evaluating 'sqrt(1764)' 'sqrt(1764)' -> 42.000000 -Evaluating 'sqrt(-1)' -'sqrt(-1)' -> nan +Evaluating 'isnan(sqrt(-1))' +'isnan(sqrt(-1))' -> 1.000000 Evaluating 'not(1)' 'not(1)' -> 0.000000 |