Merge remote-tracking branch 'qatar/master'
authorMichael Niedermayer <michaelni@gmx.at>
Thu, 9 Feb 2012 23:38:13 +0000 (00:38 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Fri, 10 Feb 2012 00:20:07 +0000 (01:20 +0100)
* qatar/master: (26 commits)
  eac3dec: replace undefined 1<<31 with INT32_MIN in noise generation
  yadif: specify array size outside DECLARE_ALIGNED
  prores: specify array size outside DECLARE_ALIGNED brackets.
  WavPack demuxer: set packet duration
  tta: use skip_bits_long()
  mxfdec: Ignore the last entry in Avid's index table segments
  mxfdec: Sanity-check SampleRate
  mxfdec: Handle small EditUnitByteCount
  mxfdec: Consider OPAtom files that do not have exactly one EC to be OP1a
  mxfdec: Don't crash in mxf_packet_timestamps() if current_edit_unit overflows
  mxfdec: Zero nb_ptses in mxf_compute_ptses_fake_index()
  mxfdec: Sanity check PreviousPartition
  mxfdec: Never seek back in local sets and KLVs
  mxfdec: Move the current_partition check inside mxf_read_header()
  mxfdec: Fix infinite loop in mxf_packet_timestamps()
  mxfdec: Check eof_reached in mxf_read_local_tags()
  mxfdec: Check for NULL component
  mxfdec: Make sure mxf->nb_index_tables > 0 in mxf_packet_timestamps()
  mxfdec: Make sure x < index_table->nb_ptses
  build: Add missing directories to DIRS declarations.
  ...

Conflicts:
doc/build_system.txt
doc/fate.texi
libavfilter/x86/yadif_template.c
libavformat/mxfdec.c
libavutil/Makefile
tests/fate/audio.mak
tests/fate/prores.mak
tests/fate/screen.mak
tests/fate/video.mak
tests/ref/fate/bethsoft-vid
tests/ref/fate/cscd
tests/ref/fate/dfa4
tests/ref/fate/nuv
tests/ref/fate/vp8-sign-bias
tests/ref/fate/wmv8-drm
tests/ref/lavf/gxf

Merged-by: Michael Niedermayer <michaelni@gmx.at>
35 files changed:
1  2 
doc/fate.texi
doc/ffserver.conf
doc/filters.texi
libavcodec/Makefile
libavcodec/arm/vp8.h
libavcodec/bfin/dsputil_bfin.c
libavcodec/bfin/fdct_bfin.S
libavcodec/bfin/idct_bfin.S
libavcodec/bfin/mpegvideo_bfin.c
libavcodec/bfin/pixels_bfin.S
libavcodec/bfin/vp3_bfin.c
libavcodec/bfin/vp3_idct_bfin.S
libavcodec/bytestream.h
libavcodec/eac3dec.c
libavcodec/ppc/idct_altivec.c
libavcodec/proresdec_lgpl.c
libavcodec/ps2/dsputil_mmi.c
libavcodec/ps2/idct_mmi.c
libavcodec/ps2/mpegvideo_mmi.c
libavcodec/rawenc.c
libavcodec/tta.c
libavcodec/x86/fdct_mmx.c
libavcodec/x86/fft.c
libavcodec/x86/fft_3dn2.c
libavcodec/x86/fft_sse.c
libavcodec/x86/idct_mmx_xvid.c
libavfilter/x86/yadif_template.c
libavformat/apetag.h
libavformat/mxfdec.c
libavformat/wv.c
libavutil/Makefile
libswscale/ppc/yuv2rgb_altivec.h
tests/fate/audio.mak
tests/fate/prores.mak
tests/fate/screen.mak

diff --cc doc/fate.texi
  
  @chapter Introduction
  
 -FATE provides a regression testsuite embedded within the Libav build system.
 -It can be run locally and optionally configured to send reports to a web
 -aggregator and viewer @url{http://fate.libav.org}.
 +  FATE is an extended regression suite on the client-side and a means
 +for results aggregation and presentation on the server-side.
  
 -It is advised to run FATE before submitting patches to the current codebase
 -and provide new tests when submitting patches to add additional features.
 +  The first part of this document explains how you can use FATE from
 +your FFmpeg source directory to test your ffmpeg binary. The second
 +part describes how you can run FATE to submit the results to FFmpeg's
 +FATE server.
  
 -@chapter Running FATE
 +  In any way you can have a look at the publicly viewable FATE results
 +by visiting this website:
  
 -@section Samples and References
 -In order to run, FATE needs a large amount of data (samples and references)
 -that is provided separately from the actual source distribution.
 +  @url{http://fate.ffmpeg.org/}
  
 -To inform the build system about the testsuite location, pass
 -@option{--samples=<path to the samples>} to @command{configure} or set the
 -@var{SAMPLES} Make variable or the @var{FATE_SAMPLES} environment variable
 -to a suitable value.
 +  This is especially recommended for all people contributing source
 +code to FFmpeg, as it can be seen if some test on some platform broke
 +with there recent contribution. This usually happens on the platforms
 +the developers could not test on.
  
 -The dataset is available through @command{rsync}, is possible to fetch
 -the current sample using the straight rsync command or through a specific
 -@ref{Makefile target}.
 +  The second part of this document describes how you can run FATE to
 +submit your results to FFmpeg's FATE server. If you want to submit your
 +results be sure to check that your combination of CPU, OS and compiler
 +is not already listed on the above mentioned website.
 +
 +  In the third part you can find a comprehensive listing of FATE makefile
 +targets and variables.
 +
 +
 +@chapter Using FATE from your FFmpeg source directory
 +
 +  If you want to run FATE on your machine you need to have the samples
 +in place. You can get the samples via the build target fate-rsync.
 +Use this command from the top-level source directory:
 +
 +@example
 +make fate-rsync SAMPLES=fate-suite/
 +make fate       SAMPLES=fate-suite/
 +@end example
 +
 +  The above commands set the samples location by passing a makefile
 +variable via command line. It is also possible to set the samples
 +location at source configuration time by invoking configure with
 +`--samples=<path to the samples directory>'. Afterwards you can
 +invoke the makefile targets without setting the SAMPLES makefile
 +variable. This is illustrated by the following commands:
  
  @example
 -# rsync -aL rsync://fate-suite.libav.org/fate-suite/ fate-suite
 +./configure --samples=fate-suite/
 +make fate-rsync
 +make fate
  @end example
  
 +  Yet another way to tell FATE about the location of the sample
 +directory is by making sure the environment variable FATE_SAMPLES
 +contains the path to your samples directory. This can be achieved
 +by e.g. putting that variable in your shell profile or by setting
 +it in your interactive session.
 +
  @example
 -# make fate-rsync SAMPLES=fate-suite
 +FATE_SAMPLES=fate-suite/ make fate
  @end example
  
 +@float NOTE
 +Do not put a '~' character in the samples path to indicate a home
 +directory. Because of shell nuances, this will cause FATE to fail.
 +@end float
 +
 +
 +@chapter Submitting the results to the FFmpeg result aggregation server
 +
 +  To submit your results to the server you should run fate through the
 +shell script tests/fate.sh from the FFmpeg sources. This script needs
 +to be invoked with a configuration file as its first argument.
 +
 +@example
 +tests/fate.sh /path/to/fate_config
 +@end example
 +
 +  A configuration file template with comments describing the individual
 +configuration variables can be found at @file{tests/fate_config.sh.template}.
 +
 +@ifhtml
 +  The mentioned configuration template is also available here:
 +@verbatiminclude ../tests/fate_config.sh.template
 +@end ifhtml
 +
 +  Create a configuration that suits your needs, based on the configuration
 +template. The `slot' configuration variable can be any string that is not
 +yet used, but it is suggested that you name it adhering to the following
 +pattern <arch>-<os>-<compiler>-<compiler version>. The configuration file
 +itself will be sourced in a shell script, therefore all shell features may
 +be used. This enables you to setup the environment as you need it for your
 +build.
 +
 +  For your first test runs the `fate_recv' variable should be empty or
 +commented out. This will run everything as normal except that it will omit
 +the submission of the results to the server. The following files should be
 +present in $workdir as specified in the configuration file:
 +
 +@itemize
 +    @item configure.log
 +    @item compile.log
 +    @item test.log
 +    @item report
 +    @item version
 +@end itemize
 +
 +  When you have everything working properly you can create an SSH key and
 +send its public part to the FATE server administrator.
 +
 +  Configure your SSH client to use public key authentication with that key
 +when connecting to the FATE server. Also do not forget to check the identity
 +of the server and to accept its host key. This can usually be achieved by
 +running your SSH client manually and killing it after you accepted the key.
 +The FATE server's fingerprint is:
 +
 +  b1:31:c8:79:3f:04:1d:f8:f2:23:26:5a:fd:55:fa:92
  
 -@chapter Manual Run
 -FATE regression test can be run through @command{make}.
 -Specific Makefile targets and Makefile variables are available:
 +  The only thing left is to automate the execution of the fate.sh script and
 +the synchronisation of the samples directory.
 +
 +
 +@chapter FATE makefile targets and variables
 +
 +@section Makefile targets
  
 -@anchor{Makefile target}
 -@section FATE Makefile targets
  @table @option
 -@item fate-list
 -List all fate/regression test targets.
  @item fate-rsync
 -Shortcut to download the fate test samples to the specified testsuite location.
 +    Download/synchronize sample files to the configured samples directory.
 +
 +@item fate-list
 +    Will list all fate/regression test targets.
 +
  @item fate
 -Run the FATE test suite (requires the fate-suite dataset).
 +    Run the FATE test suite (requires the fate-suite dataset).
  @end table
  
 -@section Fate Makefile variables
 +@section Makefile variables
 +
  @table @option
  @item V
 -Verbosity level, can be set to 0, 1 or 2.
 -@table @option
 -    @item 0
 -    show just the test arguments
 -    @item 1
 -    show just the command used in the test
 -    @item 2
 -    show everything
 -@end table
 +    Verbosity level, can be set to 0, 1 or 2.
 +    @itemize
 +        @item 0: show just the test arguments
 +        @item 1: show just the command used in the test
 +        @item 2: show everything
 +    @end itemize
 +
  @item SAMPLES
 -Specify or override the path to the FATE samples at make time, it has a
 -meaning only while running the regression tests.
 +    Specify or override the path to the FATE samples at make time, it has a
 +    meaning only while running the regression tests.
 +
  @item THREADS
 -Specify how many threads to use while running regression tests, it is
 -quite useful to detect thread-related regressions.
 +    Specify how many threads to use while running regression tests, it is
 +    quite useful to detect thread-related regressions.
  @end table
  
 +Example:
  @example
 -    make V=1 SAMPLES=/var/fate/samples THREADS=2 fate
 -@end example
 -
 -@chapter Automated Tests
 -In order to automatically testing specific configurations, e.g. multiple
 -compilers, @command{tests/fate.sh} is provided.
 -
 -This shell script builds Libav, runs the regression tests and prepares a
 -report that can be sent to @url{fate.libav.org} or directly examined locally.
 -
 -@section Testing Profiles
 -The configuration file passed to @command{fate.sh} is shell scripts as well.
 -
 -It must provide at least a @var{slot} identifier, the @var{repo} from
 -which fetch the sources, the @var{samples} directory, a @var{workdir} with
 -enough space to build and run all the tests.
 -Optional submit command @var{fate_recv} and a @var{comment} to describe
 -the testing profile are available.
 -
 -Additional optional parameter to tune the Libav building and reporting process
 -can be passed.
 -
 -@example
 -slot=                                   # some unique identifier
 -repo=git://git.libav.org/libav.git      # the source repository
 -samples=/path/to/fate/samples
 -workdir=                                # directory in which to do all the work
 -fate_recv="ssh -T fate@@fate.libav.org"  # command to submit report
 -comment=                                # optional description
 -
 -# the following are optional and map to configure options
 -arch=
 -cpu=
 -cross_prefix=
 -cc=
 -target_os=
 -sysroot=
 -target_exec=
 -target_path=
 -extra_cflags=
 -extra_ldflags=
 -extra_libs=
 -extra_conf=     # extra configure options not covered above
 -
 -#make=          # name of GNU make if not 'make'
 -makeopts=       # extra options passed to 'make'
 -#tar=           # command to create a tar archive from its arguments on
 -                # stdout, defaults to 'tar c'
 -@end example
 -
 -@section Submitting Reports
 -In order to send reports you need to create an @command{ssh} key and send it
 -to @email{root@@libav.org}.
 -The current server fingerprint is @var{a4:99:d7:d3:1c:92:0d:56:d6:d5:61:be:01:ae:7d:e6}
 +make V=1 SAMPLES=/var/fate/samples THREADS=2 fate
- @end example
++@end example
index 2171170,0000000..d10ac5b
mode 100644,000000..100644
--- /dev/null
@@@ -1,377 -1,0 +1,375 @@@
 +# Port on which the server is listening. You must select a different
 +# port from your standard HTTP web server if it is running on the same
 +# computer.
 +Port 8090
 +
 +# Address on which the server is bound. Only useful if you have
 +# several network interfaces.
 +BindAddress 0.0.0.0
 +
 +# Number of simultaneous HTTP connections that can be handled. It has
 +# to be defined *before* the MaxClients parameter, since it defines the
 +# MaxClients maximum limit.
 +MaxHTTPConnections 2000
 +
 +# Number of simultaneous requests that can be handled. Since FFServer
 +# is very fast, it is more likely that you will want to leave this high
 +# and use MaxBandwidth, below.
 +MaxClients 1000
 +
 +# This the maximum amount of kbit/sec that you are prepared to
 +# consume when streaming to clients.
 +MaxBandwidth 1000
 +
 +# Access log file (uses standard Apache log file format)
 +# '-' is the standard output.
 +CustomLog -
 +
 +# Suppress that if you want to launch ffserver as a daemon.
 +NoDaemon
 +
 +
 +##################################################################
 +# Definition of the live feeds. Each live feed contains one video
 +# and/or audio sequence coming from an ffmpeg encoder or another
 +# ffserver. This sequence may be encoded simultaneously with several
 +# codecs at several resolutions.
 +
 +<Feed feed1.ffm>
 +
 +# You must use 'ffmpeg' to send a live feed to ffserver. In this
 +# example, you can type:
 +#
 +# ffmpeg http://localhost:8090/feed1.ffm
 +
 +# ffserver can also do time shifting. It means that it can stream any
 +# previously recorded live stream. The request should contain:
 +# "http://xxxx?date=[YYYY-MM-DDT][[HH:]MM:]SS[.m...]".You must specify
 +# a path where the feed is stored on disk. You also specify the
 +# maximum size of the feed, where zero means unlimited. Default:
 +# File=/tmp/feed_name.ffm FileMaxSize=5M
 +File /tmp/feed1.ffm
 +FileMaxSize 200K
 +
 +# You could specify
 +# ReadOnlyFile /saved/specialvideo.ffm
 +# This marks the file as readonly and it will not be deleted or updated.
 +
 +# Specify launch in order to start ffmpeg automatically.
 +# First ffmpeg must be defined with an appropriate path if needed,
 +# after that options can follow, but avoid adding the http:// field
 +#Launch ffmpeg
 +
 +# Only allow connections from localhost to the feed.
 +ACL allow 127.0.0.1
 +
 +</Feed>
 +
 +
 +##################################################################
 +# Now you can define each stream which will be generated from the
 +# original audio and video stream. Each format has a filename (here
 +# 'test1.mpg'). FFServer will send this stream when answering a
 +# request containing this filename.
 +
 +<Stream test1.mpg>
 +
 +# coming from live feed 'feed1'
 +Feed feed1.ffm
 +
 +# Format of the stream : you can choose among:
 +# mpeg       : MPEG-1 multiplexed video and audio
 +# mpegvideo  : only MPEG-1 video
 +# mp2        : MPEG-2 audio (use AudioCodec to select layer 2 and 3 codec)
 +# ogg        : Ogg format (Vorbis audio codec)
 +# rm         : RealNetworks-compatible stream. Multiplexed audio and video.
 +# ra         : RealNetworks-compatible stream. Audio only.
 +# mpjpeg     : Multipart JPEG (works with Netscape without any plugin)
 +# jpeg       : Generate a single JPEG image.
 +# asf        : ASF compatible streaming (Windows Media Player format).
 +# swf        : Macromedia Flash compatible stream
 +# avi        : AVI format (MPEG-4 video, MPEG audio sound)
 +Format mpeg
 +
 +# Bitrate for the audio stream. Codecs usually support only a few
 +# different bitrates.
 +AudioBitRate 32
 +
 +# Number of audio channels: 1 = mono, 2 = stereo
 +AudioChannels 1
 +
 +# Sampling frequency for audio. When using low bitrates, you should
 +# lower this frequency to 22050 or 11025. The supported frequencies
 +# depend on the selected audio codec.
 +AudioSampleRate 44100
 +
 +# Bitrate for the video stream
 +VideoBitRate 64
 +
 +# Ratecontrol buffer size
 +VideoBufferSize 40
 +
 +# Number of frames per second
 +VideoFrameRate 3
 +
 +# Size of the video frame: WxH (default: 160x128)
 +# The following abbreviations are defined: sqcif, qcif, cif, 4cif, qqvga,
 +# qvga, vga, svga, xga, uxga, qxga, sxga, qsxga, hsxga, wvga, wxga, wsxga,
 +# wuxga, woxga, wqsxga, wquxga, whsxga, whuxga, cga, ega, hd480, hd720,
 +# hd1080
 +VideoSize 160x128
 +
 +# Transmit only intra frames (useful for low bitrates, but kills frame rate).
 +#VideoIntraOnly
 +
 +# If non-intra only, an intra frame is transmitted every VideoGopSize
 +# frames. Video synchronization can only begin at an intra frame.
 +VideoGopSize 12
 +
 +# More MPEG-4 parameters
 +# VideoHighQuality
 +# Video4MotionVector
 +
 +# Choose your codecs:
 +#AudioCodec mp2
 +#VideoCodec mpeg1video
 +
 +# Suppress audio
 +#NoAudio
 +
 +# Suppress video
 +#NoVideo
 +
 +#VideoQMin 3
 +#VideoQMax 31
 +
 +# Set this to the number of seconds backwards in time to start. Note that
 +# most players will buffer 5-10 seconds of video, and also you need to allow
 +# for a keyframe to appear in the data stream.
 +#Preroll 15
 +
 +# ACL:
 +
 +# You can allow ranges of addresses (or single addresses)
 +#ACL ALLOW <first address> <last address>
 +
 +# You can deny ranges of addresses (or single addresses)
 +#ACL DENY <first address> <last address>
 +
 +# You can repeat the ACL allow/deny as often as you like. It is on a per
 +# stream basis. The first match defines the action. If there are no matches,
 +# then the default is the inverse of the last ACL statement.
 +#
 +# Thus 'ACL allow localhost' only allows access from localhost.
 +# 'ACL deny 1.0.0.0 1.255.255.255' would deny the whole of network 1 and
 +# allow everybody else.
 +
 +</Stream>
 +
 +
 +##################################################################
 +# Example streams
 +
 +
 +# Multipart JPEG
 +
 +#<Stream test.mjpg>
 +#Feed feed1.ffm
 +#Format mpjpeg
 +#VideoFrameRate 2
 +#VideoIntraOnly
 +#NoAudio
 +#Strict -1
 +#</Stream>
 +
 +
 +# Single JPEG
 +
 +#<Stream test.jpg>
 +#Feed feed1.ffm
 +#Format jpeg
 +#VideoFrameRate 2
 +#VideoIntraOnly
 +##VideoSize 352x240
 +#NoAudio
 +#Strict -1
 +#</Stream>
 +
 +
 +# Flash
 +
 +#<Stream test.swf>
 +#Feed feed1.ffm
 +#Format swf
 +#VideoFrameRate 2
 +#VideoIntraOnly
 +#NoAudio
 +#</Stream>
 +
 +
 +# ASF compatible
 +
 +<Stream test.asf>
 +Feed feed1.ffm
 +Format asf
 +VideoFrameRate 15
 +VideoSize 352x240
 +VideoBitRate 256
 +VideoBufferSize 40
 +VideoGopSize 30
 +AudioBitRate 64
 +StartSendOnKey
 +</Stream>
 +
 +
 +# MP3 audio
 +
 +#<Stream test.mp3>
 +#Feed feed1.ffm
 +#Format mp2
 +#AudioCodec mp3
 +#AudioBitRate 64
 +#AudioChannels 1
 +#AudioSampleRate 44100
 +#NoVideo
 +#</Stream>
 +
 +
 +# Ogg Vorbis audio
 +
 +#<Stream test.ogg>
 +#Feed feed1.ffm
 +#Title "Stream title"
 +#AudioBitRate 64
 +#AudioChannels 2
 +#AudioSampleRate 44100
 +#NoVideo
 +#</Stream>
 +
 +
 +# Real with audio only at 32 kbits
 +
 +#<Stream test.ra>
 +#Feed feed1.ffm
 +#Format rm
 +#AudioBitRate 32
 +#NoVideo
 +#NoAudio
 +#</Stream>
 +
 +
 +# Real with audio and video at 64 kbits
 +
 +#<Stream test.rm>
 +#Feed feed1.ffm
 +#Format rm
 +#AudioBitRate 32
 +#VideoBitRate 128
 +#VideoFrameRate 25
 +#VideoGopSize 25
 +#NoAudio
 +#</Stream>
 +
 +
 +##################################################################
 +# A stream coming from a file: you only need to set the input
 +# filename and optionally a new format. Supported conversions:
 +#    AVI -> ASF
 +
 +#<Stream file.rm>
 +#File "/usr/local/httpd/htdocs/tlive.rm"
 +#NoAudio
 +#</Stream>
 +
 +#<Stream file.asf>
 +#File "/usr/local/httpd/htdocs/test.asf"
 +#NoAudio
 +#Author "Me"
 +#Copyright "Super MegaCorp"
 +#Title "Test stream from disk"
 +#Comment "Test comment"
 +#</Stream>
 +
 +
 +##################################################################
 +# RTSP examples
 +#
 +# You can access this stream with the RTSP URL:
 +#   rtsp://localhost:5454/test1-rtsp.mpg
 +#
 +# A non-standard RTSP redirector is also created. Its URL is:
 +#   http://localhost:8090/test1-rtsp.rtsp
 +
 +#<Stream test1-rtsp.mpg>
 +#Format rtp
 +#File "/usr/local/httpd/htdocs/test1.mpg"
 +#</Stream>
 +
 +
 +# Transcode an incoming live feed to another live feed,
 +# using libx264 and video presets
 +
 +#<Stream live.h264>
 +#Format rtp
 +#Feed feed1.ffm
 +#VideoCodec libx264
 +#VideoFrameRate 24
 +#VideoBitRate 100
 +#VideoSize 480x272
 +#AVPresetVideo default
 +#AVPresetVideo baseline
 +#AVOptionVideo flags +global_header
 +#
 +#AudioCodec libfaac
 +#AudioBitRate 32
 +#AudioChannels 2
 +#AudioSampleRate 22050
 +#AVOptionAudio flags +global_header
 +#</Stream>
 +
 +##################################################################
 +# SDP/multicast examples
 +#
 +# If you want to send your stream in multicast, you must set the
 +# multicast address with MulticastAddress. The port and the TTL can
 +# also be set.
 +#
 +# An SDP file is automatically generated by ffserver by adding the
 +# 'sdp' extension to the stream name (here
 +# http://localhost:8090/test1-sdp.sdp). You should usually give this
 +# file to your player to play the stream.
 +#
 +# The 'NoLoop' option can be used to avoid looping when the stream is
 +# terminated.
 +
 +#<Stream test1-sdp.mpg>
 +#Format rtp
 +#File "/usr/local/httpd/htdocs/test1.mpg"
 +#MulticastAddress 224.124.0.1
 +#MulticastPort 5000
 +#MulticastTTL 16
 +#NoLoop
 +#</Stream>
 +
 +
 +##################################################################
 +# Special streams
 +
 +# Server status
 +
 +<Stream stat.html>
 +Format status
 +
 +# Only allow local people to get the status
 +ACL allow localhost
 +ACL allow 192.168.0.0 192.168.255.255
 +
 +#FaviconURL http://pond1.gladstonefamily.net:8080/favicon.ico
 +</Stream>
 +
 +
 +# Redirect index.html to the appropriate site
 +
 +<Redirect index.html>
 +URL http://www.ffmpeg.org/
 +</Redirect>
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 5fe4775,0000000..33653de
mode 100644,000000..100644
--- /dev/null
@@@ -1,706 -1,0 +1,706 @@@
-     DECLARE_ALIGNED(16, DCTELEM, blocks[8 * 4 * 64]);
 +/*
 + * Apple ProRes compatible decoder
 + *
 + * Copyright (c) 2010-2011 Maxim Poliakovski
 + *
 + * 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
 + * This is a decoder for Apple ProRes 422 SD/HQ/LT/Proxy and ProRes 4444.
 + * It is used for storing and editing high definition video data in Apple's Final Cut Pro.
 + *
 + * @see http://wiki.multimedia.cx/index.php?title=Apple_ProRes
 + */
 +
 +#define LONG_BITSTREAM_READER // some ProRes vlc codes require up to 28 bits to be read at once
 +
 +#include <stdint.h>
 +
 +#include "libavutil/intmath.h"
 +#include "avcodec.h"
 +#include "proresdsp.h"
 +#include "get_bits.h"
 +
 +typedef struct {
 +    const uint8_t *index;            ///< pointers to the data of this slice
 +    int slice_num;
 +    int x_pos, y_pos;
 +    int slice_width;
-     DECLARE_ALIGNED(16, int16_t, qmat_luma_scaled[64]);
-     DECLARE_ALIGNED(16, int16_t, qmat_chroma_scaled[64]);
++    DECLARE_ALIGNED(16, DCTELEM, blocks)[8 * 4 * 64];
 +} ProresThreadData;
 +
 +typedef struct {
 +    ProresDSPContext dsp;
 +    AVFrame    picture;
 +    ScanTable  scantable;
 +    int        scantable_type;           ///< -1 = uninitialized, 0 = progressive, 1/2 = interlaced
 +
 +    int        frame_type;               ///< 0 = progressive, 1 = top-field first, 2 = bottom-field first
 +    int        pic_format;               ///< 2 = 422, 3 = 444
 +    uint8_t    qmat_luma[64];            ///< dequantization matrix for luma
 +    uint8_t    qmat_chroma[64];          ///< dequantization matrix for chroma
 +    int        qmat_changed;             ///< 1 - global quantization matrices changed
 +    int        prev_slice_sf;            ///< scalefactor of the previous decoded slice
++    DECLARE_ALIGNED(16, int16_t, qmat_luma_scaled)[64];
++    DECLARE_ALIGNED(16, int16_t, qmat_chroma_scaled)[64];
 +    int        total_slices;            ///< total number of slices in a picture
 +    ProresThreadData *slice_data;
 +    int        pic_num;
 +    int        chroma_factor;
 +    int        mb_chroma_factor;
 +    int        num_chroma_blocks;       ///< number of chrominance blocks in a macroblock
 +    int        num_x_slices;
 +    int        num_y_slices;
 +    int        slice_width_factor;
 +    int        slice_height_factor;
 +    int        num_x_mbs;
 +    int        num_y_mbs;
 +    int        alpha_info;
 +} ProresContext;
 +
 +
 +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;
 +
 +    ctx->total_slices     = 0;
 +    ctx->slice_data       = NULL;
 +
 +    avctx->bits_per_raw_sample = PRORES_BITS_PER_SAMPLE;
 +    ff_proresdsp_init(&ctx->dsp, avctx);
 +
 +    avctx->coded_frame = &ctx->picture;
 +    avcodec_get_frame_defaults(&ctx->picture);
 +    ctx->picture.type      = AV_PICTURE_TYPE_I;
 +    ctx->picture.key_frame = 1;
 +
 +    ctx->scantable_type = -1;   // set scantable type to uninitialized
 +    memset(ctx->qmat_luma, 4, 64);
 +    memset(ctx->qmat_chroma, 4, 64);
 +    ctx->prev_slice_sf = 0;
 +
 +    return 0;
 +}
 +
 +
 +static int decode_frame_header(ProresContext *ctx, const uint8_t *buf,
 +                               const int data_size, AVCodecContext *avctx)
 +{
 +    int hdr_size, version, width, height, flags;
 +    const uint8_t *ptr;
 +
 +    hdr_size = AV_RB16(buf);
 +    if (hdr_size > data_size) {
 +        av_log(avctx, AV_LOG_ERROR, "frame data too small\n");
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    version = AV_RB16(buf + 2);
 +    if (version >= 2) {
 +        av_log(avctx, AV_LOG_ERROR,
 +               "unsupported header version: %d\n", version);
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    width  = AV_RB16(buf + 8);
 +    height = AV_RB16(buf + 10);
 +    if (width != avctx->width || height != avctx->height) {
 +        av_log(avctx, AV_LOG_ERROR,
 +               "picture dimension changed: old: %d x %d, new: %d x %d\n",
 +               avctx->width, avctx->height, width, height);
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    ctx->frame_type = (buf[12] >> 2) & 3;
 +    if (ctx->frame_type > 2) {
 +        av_log(avctx, AV_LOG_ERROR,
 +               "unsupported frame type: %d\n", ctx->frame_type);
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    ctx->chroma_factor     = (buf[12] >> 6) & 3;
 +    ctx->mb_chroma_factor  = ctx->chroma_factor + 2;
 +    ctx->num_chroma_blocks = (1 << ctx->chroma_factor) >> 1;
 +    switch (ctx->chroma_factor) {
 +    case 2:
 +        avctx->pix_fmt = PIX_FMT_YUV422P10;
 +        break;
 +    case 3:
 +        avctx->pix_fmt = PIX_FMT_YUV444P10;
 +        break;
 +    default:
 +        av_log(avctx, AV_LOG_ERROR,
 +               "unsupported picture format: %d\n", ctx->pic_format);
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    if (ctx->scantable_type != ctx->frame_type) {
 +        if (!ctx->frame_type)
 +            ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable,
 +                              progressive_scan);
 +        else
 +            ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable,
 +                              interlaced_scan);
 +        ctx->scantable_type = ctx->frame_type;
 +    }
 +
 +    if (ctx->frame_type) {      /* if interlaced */
 +        ctx->picture.interlaced_frame = 1;
 +        ctx->picture.top_field_first  = ctx->frame_type & 1;
 +    }
 +
 +    ctx->alpha_info = buf[17] & 0xf;
 +    if (ctx->alpha_info)
 +        av_log_missing_feature(avctx, "alpha channel", 0);
 +
 +    ctx->qmat_changed = 0;
 +    ptr   = buf + 20;
 +    flags = buf[19];
 +    if (flags & 2) {
 +        if (ptr - buf > hdr_size - 64) {
 +            av_log(avctx, AV_LOG_ERROR, "header data too small\n");
 +            return AVERROR_INVALIDDATA;
 +        }
 +        if (memcmp(ctx->qmat_luma, ptr, 64)) {
 +            memcpy(ctx->qmat_luma, ptr, 64);
 +            ctx->qmat_changed = 1;
 +        }
 +        ptr += 64;
 +    } else {
 +        memset(ctx->qmat_luma, 4, 64);
 +        ctx->qmat_changed = 1;
 +    }
 +
 +    if (flags & 1) {
 +        if (ptr - buf > hdr_size - 64) {
 +            av_log(avctx, AV_LOG_ERROR, "header data too small\n");
 +            return -1;
 +        }
 +        if (memcmp(ctx->qmat_chroma, ptr, 64)) {
 +            memcpy(ctx->qmat_chroma, ptr, 64);
 +            ctx->qmat_changed = 1;
 +        }
 +    } else {
 +        memset(ctx->qmat_chroma, 4, 64);
 +        ctx->qmat_changed = 1;
 +    }
 +
 +    return hdr_size;
 +}
 +
 +
 +static int decode_picture_header(ProresContext *ctx, const uint8_t *buf,
 +                                 const int data_size, AVCodecContext *avctx)
 +{
 +    int   i, hdr_size, pic_data_size, num_slices;
 +    int   slice_width_factor, slice_height_factor;
 +    int   remainder, num_x_slices;
 +    const uint8_t *data_ptr, *index_ptr;
 +
 +    hdr_size = data_size > 0 ? buf[0] >> 3 : 0;
 +    if (hdr_size < 8 || hdr_size > data_size) {
 +        av_log(avctx, AV_LOG_ERROR, "picture header too small\n");
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    pic_data_size = AV_RB32(buf + 1);
 +    if (pic_data_size > data_size) {
 +        av_log(avctx, AV_LOG_ERROR, "picture data too small\n");
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    slice_width_factor  = buf[7] >> 4;
 +    slice_height_factor = buf[7] & 0xF;
 +    if (slice_width_factor > 3 || slice_height_factor) {
 +        av_log(avctx, AV_LOG_ERROR,
 +               "unsupported slice dimension: %d x %d\n",
 +               1 << slice_width_factor, 1 << slice_height_factor);
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    ctx->slice_width_factor  = slice_width_factor;
 +    ctx->slice_height_factor = slice_height_factor;
 +
 +    ctx->num_x_mbs = (avctx->width + 15) >> 4;
 +    ctx->num_y_mbs = (avctx->height +
 +                      (1 << (4 + ctx->picture.interlaced_frame)) - 1) >>
 +                     (4 + ctx->picture.interlaced_frame);
 +
 +    remainder    = ctx->num_x_mbs & ((1 << slice_width_factor) - 1);
 +    num_x_slices = (ctx->num_x_mbs >> slice_width_factor) + (remainder & 1) +
 +                   ((remainder >> 1) & 1) + ((remainder >> 2) & 1);
 +
 +    num_slices = num_x_slices * ctx->num_y_mbs;
 +    if (num_slices != AV_RB16(buf + 5)) {
 +        av_log(avctx, AV_LOG_ERROR, "invalid number of slices\n");
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    if (ctx->total_slices != num_slices) {
 +        av_freep(&ctx->slice_data);
 +        ctx->slice_data = av_malloc((num_slices + 1) * sizeof(ctx->slice_data[0]));
 +        if (!ctx->slice_data)
 +            return AVERROR(ENOMEM);
 +        ctx->total_slices = num_slices;
 +    }
 +
 +    if (hdr_size + num_slices * 2 > data_size) {
 +        av_log(avctx, AV_LOG_ERROR, "slice table too small\n");
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    /* parse slice table allowing quick access to the slice data */
 +    index_ptr = buf + hdr_size;
 +    data_ptr = index_ptr + num_slices * 2;
 +
 +    for (i = 0; i < num_slices; i++) {
 +        ctx->slice_data[i].index = data_ptr;
 +        data_ptr += AV_RB16(index_ptr + i * 2);
 +    }
 +    ctx->slice_data[i].index = data_ptr;
 +
 +    if (data_ptr > buf + data_size) {
 +        av_log(avctx, AV_LOG_ERROR, "out of slice data\n");
 +        return -1;
 +    }
 +
 +    return pic_data_size;
 +}
 +
 +
 +/**
 + * Read an unsigned rice/exp golomb codeword.
 + */
 +static inline int decode_vlc_codeword(GetBitContext *gb, uint8_t codebook)
 +{
 +    unsigned int rice_order, exp_order, switch_bits;
 +    unsigned int buf, code;
 +    int log, prefix_len, len;
 +
 +    OPEN_READER(re, gb);
 +    UPDATE_CACHE(re, gb);
 +    buf = GET_CACHE(re, gb);
 +
 +    /* number of prefix bits to switch between Rice and expGolomb */
 +    switch_bits = (codebook & 3) + 1;
 +    rice_order  = codebook >> 5;        /* rice code order */
 +    exp_order   = (codebook >> 2) & 7;  /* exp golomb code order */
 +
 +    log = 31 - av_log2(buf); /* count prefix bits (zeroes) */
 +
 +    if (log < switch_bits) { /* ok, we got a rice code */
 +        if (!rice_order) {
 +            /* shortcut for faster decoding of rice codes without remainder */
 +            code = log;
 +            LAST_SKIP_BITS(re, gb, log + 1);
 +        } else {
 +            prefix_len = log + 1;
 +            code = (log << rice_order) + NEG_USR32(buf << prefix_len, rice_order);
 +            LAST_SKIP_BITS(re, gb, prefix_len + rice_order);
 +        }
 +    } else { /* otherwise we got a exp golomb code */
 +        len  = (log << 1) - switch_bits + exp_order + 1;
 +        code = NEG_USR32(buf, len) - (1 << exp_order) + (switch_bits << rice_order);
 +        LAST_SKIP_BITS(re, gb, len);
 +    }
 +
 +    CLOSE_READER(re, gb);
 +
 +    return code;
 +}
 +
 +#define LSB2SIGN(x) (-((x) & 1))
 +#define TOSIGNED(x) (((x) >> 1) ^ LSB2SIGN(x))
 +
 +#define FIRST_DC_CB 0xB8 // rice_order = 5, exp_golomb_order = 6, switch_bits = 0
 +
 +static uint8_t dc_codebook[4] = {
 +    0x04, // rice_order = 0, exp_golomb_order = 1, switch_bits = 0
 +    0x28, // rice_order = 1, exp_golomb_order = 2, switch_bits = 0
 +    0x4D, // rice_order = 2, exp_golomb_order = 3, switch_bits = 1
 +    0x70  // rice_order = 3, exp_golomb_order = 4, switch_bits = 0
 +};
 +
 +
 +/**
 + * Decode DC coefficients for all blocks in a slice.
 + */
 +static inline void decode_dc_coeffs(GetBitContext *gb, DCTELEM *out,
 +                                    int nblocks)
 +{
 +    DCTELEM prev_dc;
 +    int     i, sign;
 +    int16_t delta;
 +    unsigned int code;
 +
 +    code   = decode_vlc_codeword(gb, FIRST_DC_CB);
 +    out[0] = prev_dc = TOSIGNED(code);
 +
 +    out   += 64; /* move to the DC coeff of the next block */
 +    delta  = 3;
 +
 +    for (i = 1; i < nblocks; i++, out += 64) {
 +        code = decode_vlc_codeword(gb, dc_codebook[FFMIN(FFABS(delta), 3)]);
 +
 +        sign     = -(((delta >> 15) & 1) ^ (code & 1));
 +        delta    = (((code + 1) >> 1) ^ sign) - sign;
 +        prev_dc += delta;
 +        out[0]   = prev_dc;
 +    }
 +}
 +
 +
 +static uint8_t ac_codebook[7] = {
 +    0x04, // rice_order = 0, exp_golomb_order = 1, switch_bits = 0
 +    0x28, // rice_order = 1, exp_golomb_order = 2, switch_bits = 0
 +    0x4C, // rice_order = 2, exp_golomb_order = 3, switch_bits = 0
 +    0x05, // rice_order = 0, exp_golomb_order = 1, switch_bits = 1
 +    0x29, // rice_order = 1, exp_golomb_order = 2, switch_bits = 1
 +    0x06, // rice_order = 0, exp_golomb_order = 1, switch_bits = 2
 +    0x0A, // rice_order = 0, exp_golomb_order = 2, switch_bits = 2
 +};
 +
 +/**
 + * Lookup tables for adaptive switching between codebooks
 + * according with previous run/level value.
 + */
 +static uint8_t run_to_cb_index[16] =
 +    { 5, 5, 3, 3, 0, 4, 4, 4, 4, 1, 1, 1, 1, 1, 1, 2 };
 +
 +static uint8_t lev_to_cb_index[10] = { 0, 6, 3, 5, 0, 1, 1, 1, 1, 2 };
 +
 +
 +/**
 + * Decode AC coefficients for all blocks in a slice.
 + */
 +static inline void decode_ac_coeffs(GetBitContext *gb, DCTELEM *out,
 +                                    int blocks_per_slice,
 +                                    int plane_size_factor,
 +                                    const uint8_t *scan)
 +{
 +    int pos, block_mask, run, level, sign, run_cb_index, lev_cb_index;
 +    int max_coeffs, bits_left;
 +
 +    /* set initial prediction values */
 +    run   = 4;
 +    level = 2;
 +
 +    max_coeffs = blocks_per_slice << 6;
 +    block_mask = blocks_per_slice - 1;
 +
 +    for (pos = blocks_per_slice - 1; pos < max_coeffs;) {
 +        run_cb_index = run_to_cb_index[FFMIN(run, 15)];
 +        lev_cb_index = lev_to_cb_index[FFMIN(level, 9)];
 +
 +        bits_left = get_bits_left(gb);
 +        if (bits_left <= 0 || (bits_left <= 8 && !show_bits(gb, bits_left)))
 +            return;
 +
 +        run = decode_vlc_codeword(gb, ac_codebook[run_cb_index]);
 +
 +        bits_left = get_bits_left(gb);
 +        if (bits_left <= 0 || (bits_left <= 8 && !show_bits(gb, bits_left)))
 +            return;
 +
 +        level = decode_vlc_codeword(gb, ac_codebook[lev_cb_index]) + 1;
 +
 +        pos += run + 1;
 +        if (pos >= max_coeffs)
 +            break;
 +
 +        sign = get_sbits(gb, 1);
 +        out[((pos & block_mask) << 6) + scan[pos >> plane_size_factor]] =
 +            (level ^ sign) - sign;
 +    }
 +}
 +
 +
 +/**
 + * Decode a slice plane (luma or chroma).
 + */
 +static void decode_slice_plane(ProresContext *ctx, ProresThreadData *td,
 +                               const uint8_t *buf,
 +                               int data_size, uint16_t *out_ptr,
 +                               int linesize, int mbs_per_slice,
 +                               int blocks_per_mb, int plane_size_factor,
 +                               const int16_t *qmat)
 +{
 +    GetBitContext gb;
 +    DCTELEM *block_ptr;
 +    int mb_num, blocks_per_slice;
 +
 +    blocks_per_slice = mbs_per_slice * blocks_per_mb;
 +
 +    memset(td->blocks, 0, 8 * 4 * 64 * sizeof(*td->blocks));
 +
 +    init_get_bits(&gb, buf, data_size << 3);
 +
 +    decode_dc_coeffs(&gb, td->blocks, blocks_per_slice);
 +
 +    decode_ac_coeffs(&gb, td->blocks, blocks_per_slice,
 +                     plane_size_factor, ctx->scantable.permutated);
 +
 +    /* inverse quantization, inverse transform and output */
 +    block_ptr = td->blocks;
 +
 +    for (mb_num = 0; mb_num < mbs_per_slice; mb_num++, out_ptr += blocks_per_mb * 4) {
 +        ctx->dsp.idct_put(out_ptr,                    linesize, block_ptr, qmat);
 +        block_ptr += 64;
 +        if (blocks_per_mb > 2) {
 +            ctx->dsp.idct_put(out_ptr + 8,            linesize, block_ptr, qmat);
 +            block_ptr += 64;
 +        }
 +        ctx->dsp.idct_put(out_ptr + linesize * 4,     linesize, block_ptr, qmat);
 +        block_ptr += 64;
 +        if (blocks_per_mb > 2) {
 +            ctx->dsp.idct_put(out_ptr + linesize * 4 + 8, linesize, block_ptr, qmat);
 +            block_ptr += 64;
 +        }
 +    }
 +}
 +
 +
 +static int decode_slice(AVCodecContext *avctx, void *tdata)
 +{
 +    ProresThreadData *td = tdata;
 +    ProresContext *ctx = avctx->priv_data;
 +    int mb_x_pos  = td->x_pos;
 +    int mb_y_pos  = td->y_pos;
 +    int pic_num   = ctx->pic_num;
 +    int slice_num = td->slice_num;
 +    int mbs_per_slice = td->slice_width;
 +    const uint8_t *buf;
 +    uint8_t *y_data, *u_data, *v_data;
 +    AVFrame *pic = avctx->coded_frame;
 +    int i, sf, slice_width_factor;
 +    int slice_data_size, hdr_size, y_data_size, u_data_size, v_data_size;
 +    int y_linesize, u_linesize, v_linesize;
 +
 +    buf             = ctx->slice_data[slice_num].index;
 +    slice_data_size = ctx->slice_data[slice_num + 1].index - buf;
 +
 +    slice_width_factor = av_log2(mbs_per_slice);
 +
 +    y_data     = pic->data[0];
 +    u_data     = pic->data[1];
 +    v_data     = pic->data[2];
 +    y_linesize = pic->linesize[0];
 +    u_linesize = pic->linesize[1];
 +    v_linesize = pic->linesize[2];
 +
 +    if (pic->interlaced_frame) {
 +        if (!(pic_num ^ pic->top_field_first)) {
 +            y_data += y_linesize;
 +            u_data += u_linesize;
 +            v_data += v_linesize;
 +        }
 +        y_linesize <<= 1;
 +        u_linesize <<= 1;
 +        v_linesize <<= 1;
 +    }
 +
 +    if (slice_data_size < 6) {
 +        av_log(avctx, AV_LOG_ERROR, "slice data too small\n");
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    /* parse slice header */
 +    hdr_size    = buf[0] >> 3;
 +    y_data_size = AV_RB16(buf + 2);
 +    u_data_size = AV_RB16(buf + 4);
 +    v_data_size = hdr_size > 7 ? AV_RB16(buf + 6) :
 +        slice_data_size - y_data_size - u_data_size - hdr_size;
 +
 +    if (hdr_size + y_data_size + u_data_size + v_data_size > slice_data_size ||
 +        v_data_size < 0 || hdr_size < 6) {
 +        av_log(avctx, AV_LOG_ERROR, "invalid data size\n");
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    sf = av_clip(buf[1], 1, 224);
 +    sf = sf > 128 ? (sf - 96) << 2 : sf;
 +
 +    /* scale quantization matrixes according with slice's scale factor */
 +    /* TODO: this can be SIMD-optimized a lot */
 +    if (ctx->qmat_changed || sf != ctx->prev_slice_sf) {
 +        ctx->prev_slice_sf = sf;
 +        for (i = 0; i < 64; i++) {
 +            ctx->qmat_luma_scaled[ctx->dsp.idct_permutation[i]]   = ctx->qmat_luma[i]   * sf;
 +            ctx->qmat_chroma_scaled[ctx->dsp.idct_permutation[i]] = ctx->qmat_chroma[i] * sf;
 +        }
 +    }
 +
 +    /* decode luma plane */
 +    decode_slice_plane(ctx, td, buf + hdr_size, y_data_size,
 +                       (uint16_t*) (y_data + (mb_y_pos << 4) * y_linesize +
 +                                    (mb_x_pos << 5)), y_linesize,
 +                       mbs_per_slice, 4, slice_width_factor + 2,
 +                       ctx->qmat_luma_scaled);
 +
 +    /* decode U chroma plane */
 +    decode_slice_plane(ctx, td, buf + hdr_size + y_data_size, u_data_size,
 +                       (uint16_t*) (u_data + (mb_y_pos << 4) * u_linesize +
 +                                    (mb_x_pos << ctx->mb_chroma_factor)),
 +                       u_linesize, mbs_per_slice, ctx->num_chroma_blocks,
 +                       slice_width_factor + ctx->chroma_factor - 1,
 +                       ctx->qmat_chroma_scaled);
 +
 +    /* decode V chroma plane */
 +    decode_slice_plane(ctx, td, buf + hdr_size + y_data_size + u_data_size,
 +                       v_data_size,
 +                       (uint16_t*) (v_data + (mb_y_pos << 4) * v_linesize +
 +                                    (mb_x_pos << ctx->mb_chroma_factor)),
 +                       v_linesize, mbs_per_slice, ctx->num_chroma_blocks,
 +                       slice_width_factor + ctx->chroma_factor - 1,
 +                       ctx->qmat_chroma_scaled);
 +
 +    return 0;
 +}
 +
 +
 +static int decode_picture(ProresContext *ctx, int pic_num,
 +                          AVCodecContext *avctx)
 +{
 +    int slice_num, slice_width, x_pos, y_pos;
 +
 +    slice_num = 0;
 +
 +    ctx->pic_num = pic_num;
 +    for (y_pos = 0; y_pos < ctx->num_y_mbs; y_pos++) {
 +        slice_width = 1 << ctx->slice_width_factor;
 +
 +        for (x_pos = 0; x_pos < ctx->num_x_mbs && slice_width;
 +             x_pos += slice_width) {
 +            while (ctx->num_x_mbs - x_pos < slice_width)
 +                slice_width >>= 1;
 +
 +            ctx->slice_data[slice_num].slice_num   = slice_num;
 +            ctx->slice_data[slice_num].x_pos       = x_pos;
 +            ctx->slice_data[slice_num].y_pos       = y_pos;
 +            ctx->slice_data[slice_num].slice_width = slice_width;
 +
 +            slice_num++;
 +        }
 +    }
 +
 +    return avctx->execute(avctx, decode_slice,
 +                          ctx->slice_data, NULL, slice_num,
 +                          sizeof(ctx->slice_data[0]));
 +}
 +
 +
 +#define FRAME_ID MKBETAG('i', 'c', 'p', 'f')
 +#define MOVE_DATA_PTR(nbytes) buf += (nbytes); buf_size -= (nbytes)
 +
 +static int decode_frame(AVCodecContext *avctx, void *data, int *data_size,
 +                        AVPacket *avpkt)
 +{
 +    ProresContext *ctx = avctx->priv_data;
 +    AVFrame *picture   = avctx->coded_frame;
 +    const uint8_t *buf = avpkt->data;
 +    int buf_size       = avpkt->size;
 +    int frame_hdr_size, pic_num, pic_data_size;
 +
 +    /* check frame atom container */
 +    if (buf_size < 28 || buf_size < AV_RB32(buf) ||
 +        AV_RB32(buf + 4) != FRAME_ID) {
 +        av_log(avctx, AV_LOG_ERROR, "invalid frame\n");
 +        return AVERROR_INVALIDDATA;
 +    }
 +
 +    MOVE_DATA_PTR(8);
 +
 +    frame_hdr_size = decode_frame_header(ctx, buf, buf_size, avctx);
 +    if (frame_hdr_size < 0)
 +        return AVERROR_INVALIDDATA;
 +
 +    MOVE_DATA_PTR(frame_hdr_size);
 +
 +    if (picture->data[0])
 +        avctx->release_buffer(avctx, picture);
 +
 +    picture->reference = 0;
 +    if (avctx->get_buffer(avctx, picture) < 0)
 +        return -1;
 +
 +    for (pic_num = 0; ctx->picture.interlaced_frame - pic_num + 1; pic_num++) {
 +        pic_data_size = decode_picture_header(ctx, buf, buf_size, avctx);
 +        if (pic_data_size < 0)
 +            return AVERROR_INVALIDDATA;
 +
 +        if (decode_picture(ctx, pic_num, avctx))
 +            return -1;
 +
 +        MOVE_DATA_PTR(pic_data_size);
 +    }
 +
 +    *data_size       = sizeof(AVPicture);
 +    *(AVFrame*) data = *avctx->coded_frame;
 +
 +    return avpkt->size;
 +}
 +
 +
 +static av_cold int decode_close(AVCodecContext *avctx)
 +{
 +    ProresContext *ctx = avctx->priv_data;
 +
 +    if (ctx->picture.data[0])
 +        avctx->release_buffer(avctx, &ctx->picture);
 +
 +    av_freep(&ctx->slice_data);
 +
 +    return 0;
 +}
 +
 +
 +AVCodec ff_prores_lgpl_decoder = {
 +    .name           = "prores_lgpl",
 +    .type           = AVMEDIA_TYPE_VIDEO,
 +    .id             = CODEC_ID_PRORES,
 +    .priv_data_size = sizeof(ProresContext),
 +    .init           = decode_init,
 +    .close          = decode_close,
 +    .decode         = decode_frame,
 +    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS,
 +    .long_name      = NULL_IF_CONFIG_SMALL("Apple ProRes (iCodec Pro)")
 +};
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -413,32 -399,21 +411,32 @@@ static int tta_decode_frame(AVCodecCont
  
      if (get_bits_left(&s->gb) < 32)
          return -1;
-     skip_bits(&s->gb, 32); // frame crc
+     skip_bits_long(&s->gb, 32); // frame crc
  
 -    // convert to output buffer
 -    if (s->bps == 2) {
 -        int16_t *samples = (int16_t *)s->frame.data[0];
 -        for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++)
 -            *samples++ = *p;
 -    } else {
 -        // shift samples for 24-bit sample format
 -        int32_t *samples = (int32_t *)s->frame.data[0];
 -        for (i = 0; i < framelen * s->channels; i++)
 -            *samples++ <<= 8;
 -        // reset decode buffer
 -        s->decode_buffer = NULL;
 -    }
 +        // convert to output buffer
 +        switch(s->bps) {
 +            case 1: {
 +                uint8_t *samples = (uint8_t *)s->frame.data[0];
 +                for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++)
 +                    *samples++ = *p + 0x80;
 +                break;
 +            }
 +            case 2: {
 +                uint16_t *samples = (int16_t *)s->frame.data[0];
 +                for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++)
 +                    *samples++ = *p;
 +                break;
 +            }
 +            case 3: {
 +                // shift samples for 24-bit sample format
 +                int32_t *samples = (int32_t *)s->frame.data[0];
 +                for (p = s->decode_buffer; p < s->decode_buffer + (framelen * s->channels); p++)
 +                    *samples++ <<= 8;
 +                // reset decode buffer
 +                s->decode_buffer = NULL;
 +                break;
 +            }
 +        }
  
      *got_frame_ptr   = 1;
      *(AVFrame *)data = s->frame;
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
@@@ -251,8 -251,9 +251,9 @@@ static int wv_read_packet(AVFormatConte
      int ret;
      int size, ver, off;
      int64_t pos;
+     uint32_t block_samples;
  
 -    if (s->pb->eof_reached)
 +    if (url_feof(s->pb))
          return AVERROR(EIO);
      if(wc->block_parsed){
          if(wv_read_block_header(s, s->pb, 0) < 0)
@@@ -81,14 -76,11 +81,14 @@@ OBJS-$(ARCH_ARM) += arm/cpu.
  OBJS-$(ARCH_PPC) += ppc/cpu.o
  OBJS-$(ARCH_X86) += x86/cpu.o
  
 -TESTPROGS = adler32 aes avstring base64 cpu crc des eval fifo lfg lls \
 -            md5 opt parseutils rational sha tree
 +
 +TESTPROGS = adler32 aes avstring base64 cpu crc des eval file fifo lfg lls \
 +            md5 opt pca parseutils rational sha tree
  TESTPROGS-$(HAVE_LZO1X_999_COMPRESS) += lzo
  
- DIRS = arm bfin sh4 x86
 +TOOLS = ffeval
 +
+ DIRS = arm avr32 bfin mips ppc sh4 tomi x86
  
  ARCH_HEADERS = bswap.h intmath.h intreadwrite.h timer.h
  
Simple merge
@@@ -28,8 -28,5 +28,8 @@@ fate-nellymoser: CMD = pcm -i $(SAMPLES
  fate-nellymoser: CMP = oneoff
  fate-nellymoser: REF = $(SAMPLES)/nellymoser/nellymoser.pcm
  
 -FATE_TESTS += fate-ws_snd
 +FATE_AUDIO += fate-ws_snd
  fate-ws_snd: CMD = md5 -i $(SAMPLES)/vqa/ws_snd.vqa -f s16le
- fate-audio: $(FATE_AUDIO)
 +
 +FATE_TESTS += $(FATE_AUDIO)
++fate-audio: $(FATE_AUDIO)
@@@ -7,9 -7,8 +7,8 @@@ FATE_PRORES = fate-prores-42
  FATE_TESTS += $(FATE_PRORES)
  fate-prores: $(FATE_PRORES)
  
 -fate-prores-422:       CMD = framecrc -vsync 0 -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_422.mov -pix_fmt yuv422p10le
 -fate-prores-422_hq:    CMD = framecrc -vsync 0 -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_422_HQ.mov -pix_fmt yuv422p10le
 -fate-prores-422_lt:    CMD = framecrc -vsync 0 -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_422_LT.mov -pix_fmt yuv422p10le
 -fate-prores-422_proxy: CMD = framecrc -vsync 0 -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_422_Proxy.mov -pix_fmt yuv422p10le
 -fate-prores-alpha:     CMD = framecrc -vsync 0 -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_with_Alpha.mov -pix_fmt yuv444p10le
 +fate-prores-422:       CMD = framecrc -flags +bitexact -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_422.mov -pix_fmt yuv422p10le
 +fate-prores-422_hq:    CMD = framecrc -flags +bitexact -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_422_HQ.mov -pix_fmt yuv422p10le
 +fate-prores-422_lt:    CMD = framecrc -flags +bitexact -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_422_LT.mov -pix_fmt yuv422p10le
 +fate-prores-422_proxy: CMD = framecrc -flags +bitexact -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_422_Proxy.mov -pix_fmt yuv422p10le
 +fate-prores-alpha:     CMD = framecrc -flags +bitexact -i $(SAMPLES)/prores/Sequence_1-Apple_ProRes_with_Alpha.mov -pix_fmt yuv444p10le
@@@ -1,7 -1,8 +1,8 @@@
 -FATE_TESTS += fate-cscd
+ # FIXME dropped frames in this test because of coarse timebase
 +FATE_SCREEN += fate-cscd
  fate-cscd: CMD = framecrc -i $(SAMPLES)/CSCD/sample_video.avi -an -pix_fmt rgb24
  
 -FATE_TESTS += fate-dxtory
 +FATE_SCREEN += fate-dxtory
  fate-dxtory: CMD = framecrc -i $(SAMPLES)/dxtory/dxtory_mic.avi
  
  FATE_FRAPS += fate-fraps-v0