summaryrefslogtreecommitdiffstats
path: root/contrib/ffmpeg
diff options
context:
space:
mode:
authorkonablend <[email protected]>2009-03-01 17:03:11 +0000
committerkonablend <[email protected]>2009-03-01 17:03:11 +0000
commit4dbce6b69967c1e14092637aa95b6c31855a81fc (patch)
tree516c17095967698eeb419c70ce72dbd2c11bf754 /contrib/ffmpeg
parentc47939541ccec1e5e57753b16b28baed2613f586 (diff)
BuildSystem: conversion from jam-based to make-based system.
KNOWN ISSUES: 1. OSX + Xcode builds do not support parallel builds; attempting to use them may cause unbounded number of jobs. However, disabling via configure --disable-xcode avoids the issue. 2. OSX ppc binary produces binary which has audio-scan problems. 3. OSX ppc64 binary has not been runtime tested. ADDED: 00-BuildUserGuide.txt contrib/*/module.* doc/ make/ libhb/module.* test/module.* macos/module.* gtk/module.* DROPPED: BUILD BuildContribDarwin.sh DownloadMacOsXContribBinaries.sh Jamfile Jamrules MacOsXContribBinariesVersion.txt Makefile Makefile.config jam libhb/Jamefile libhb/Makefile test/BUILDSHARED test/Makefile contrib/Jamfile contrib/Makefile contrib/patch-ffmpeg.patch contrib/patch-x264-idr.patch contrib/patch-x264-linux.patch RENAMED: contrib/*.patch -> contrib/MODULE/[AP]??-*.patch macosx/HandBrake.plist -> macosx/Info.plist MODIFIED: libhb/decavcodec.c Patched to use cleaner include "libavcodec/audioconvert". Second part to support this cleanup is ffmpeg A02-audioconvert.patch . MODIFIED: libhb/hb.c MODIFIED: libhb/hb.h MODIFIED: libhb/muxmkv.c MODIFIED: libhb/muxmp4.c MODIFIED: libhb/update.c Patched to use "project.h" for project metadata. Renamed HB_BUILD -> HB_PROJECT_BUILD. Renamed HB_VERSION -> HB_PROJECT_VERSION. MODIFIED: test/test.c: Patched HandBrakeCLI to support I/O on Mac OS X ZFS filesystems. Reference r1803 as similar patch for HandBrake.app . Unpatched behavior is crash/buserror when using ZFS. MODIFIED: macosx/Growl.framework/ Upgraded 0.7.6 (i386,ppc) -> 1.1.2 (i386,x86_64,ppc,ppc64). New architectures facilitate x86_64 and ppc64 builds. MODIFIED: macosx/HandBrake.xcodeproj/ Bumped compatibilty mode from 2.4 -> 3.1 . Dumped old configurations Deployment, Developer. Added configurations standard, sebug as replacements. Added standard.i386, standard.x86_64, standard.ppc, standard.ppc64 . for explicit architecture build. All configurations settings cleaned up and normalized. Build output directories adjusted to support new build system. git-svn-id: svn://svn.handbrake.fr/HandBrake/trunk@2180 b64f7644-9d1e-0410-96f1-a4d463321fa5
Diffstat (limited to 'contrib/ffmpeg')
-rw-r--r--contrib/ffmpeg/A00-latm.patch886
-rw-r--r--contrib/ffmpeg/A01-mpegleak.patch56
-rw-r--r--contrib/ffmpeg/A02-audioconvert.patch12
-rw-r--r--contrib/ffmpeg/P00-cygwin.patch15
-rw-r--r--contrib/ffmpeg/P01-sunos.patch25
-rw-r--r--contrib/ffmpeg/P02-darwin-h264dsp-crash.patch13
-rw-r--r--contrib/ffmpeg/module.defs32
-rw-r--r--contrib/ffmpeg/module.rules2
8 files changed, 1041 insertions, 0 deletions
diff --git a/contrib/ffmpeg/A00-latm.patch b/contrib/ffmpeg/A00-latm.patch
new file mode 100644
index 000000000..a286f4c19
--- /dev/null
+++ b/contrib/ffmpeg/A00-latm.patch
@@ -0,0 +1,886 @@
+diff -Naur ffmpeg.orig/libavcodec/Makefile ffmpeg/libavcodec/Makefile
+--- ffmpeg.orig/libavcodec/Makefile 2008-12-01 01:40:36.000000000 -0500
++++ ffmpeg/libavcodec/Makefile 2009-02-21 08:25:13.000000000 -0500
+@@ -338,7 +338,7 @@
+ OBJS-$(CONFIG_LIBDIRAC_DECODER) += libdiracdec.o
+ OBJS-$(CONFIG_LIBDIRAC_ENCODER) += libdiracenc.o libdirac_libschro.o
+ OBJS-$(CONFIG_LIBFAAC) += libfaac.o
+-OBJS-$(CONFIG_LIBFAAD) += libfaad.o
++OBJS-$(CONFIG_LIBFAAD) += libfaad.o latmaac.o
+ OBJS-$(CONFIG_LIBGSM) += libgsm.o
+ OBJS-$(CONFIG_LIBMP3LAME) += libmp3lame.o
+ OBJS-$(CONFIG_LIBSCHROEDINGER_DECODER) += libschroedingerdec.o libschroedinger.o libdirac_libschro.o
+@@ -350,7 +350,7 @@
+ OBJS-$(CONFIG_LIBXVID) += libxvidff.o libxvid_rc.o
+
+ # parsers
+-OBJS-$(CONFIG_AAC_PARSER) += aac_parser.o aac_ac3_parser.o mpeg4audio.o
++OBJS-$(CONFIG_AAC_PARSER) += aac_parser.o aac_ac3_parser.o mpeg4audio.o latm_parser.o
+ OBJS-$(CONFIG_AC3_PARSER) += ac3_parser.o ac3tab.o aac_ac3_parser.o
+ OBJS-$(CONFIG_CAVSVIDEO_PARSER) += cavs_parser.o
+ OBJS-$(CONFIG_DCA_PARSER) += dca_parser.o
+diff -Naur ffmpeg.orig/libavcodec/allcodecs.c ffmpeg/libavcodec/allcodecs.c
+--- ffmpeg.orig/libavcodec/allcodecs.c 2008-12-01 01:40:36.000000000 -0500
++++ ffmpeg/libavcodec/allcodecs.c 2009-02-21 08:25:13.000000000 -0500
+@@ -291,6 +291,7 @@
+ REGISTER_ENCDEC (LIBDIRAC, libdirac);
+ REGISTER_ENCODER (LIBFAAC, libfaac);
+ REGISTER_DECODER (LIBFAAD, libfaad);
++ REGISTER_DECODER (LIBFAAD, libfaad2);
+ REGISTER_ENCDEC (LIBGSM, libgsm);
+ REGISTER_ENCDEC (LIBGSM_MS, libgsm_ms);
+ REGISTER_ENCODER (LIBMP3LAME, libmp3lame);
+@@ -303,6 +304,7 @@
+
+ /* parsers */
+ REGISTER_PARSER (AAC, aac);
++ REGISTER_PARSER (AAC, aac_latm);
+ REGISTER_PARSER (AC3, ac3);
+ REGISTER_PARSER (CAVSVIDEO, cavsvideo);
+ REGISTER_PARSER (DCA, dca);
+diff -Naur ffmpeg.orig/libavcodec/avcodec.h ffmpeg/libavcodec/avcodec.h
+--- ffmpeg.orig/libavcodec/avcodec.h 2008-12-01 01:40:36.000000000 -0500
++++ ffmpeg/libavcodec/avcodec.h 2009-02-21 08:25:13.000000000 -0500
+@@ -264,6 +264,7 @@
+ CODEC_ID_MP2= 0x15000,
+ CODEC_ID_MP3, ///< preferred ID for decoding MPEG audio layer 1, 2 or 3
+ CODEC_ID_AAC,
++ CODEC_ID_AAC_LATM,
+ CODEC_ID_AC3,
+ CODEC_ID_DTS,
+ CODEC_ID_VORBIS,
+diff -Naur ffmpeg.orig/libavcodec/latm_parser.c ffmpeg/libavcodec/latm_parser.c
+--- ffmpeg.orig/libavcodec/latm_parser.c 1969-12-31 19:00:00.000000000 -0500
++++ ffmpeg/libavcodec/latm_parser.c 2009-02-21 08:25:13.000000000 -0500
+@@ -0,0 +1,128 @@
++/*
++ * LATM parser
++ * Copyright (c) 2008 Paul Kendall <[email protected]>
++ *
++ * This file is part of FFmpeg.
++ *
++ * FFmpeg is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * FFmpeg is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++/**
++ * @file latm_parser.c
++ * LATM parser
++ */
++
++#include "parser.h"
++
++#define LATM_HEADER 0x56e000 // 0x2b7 (11 bits)
++#define LATM_MASK 0xFFE000 // top 11 bits
++#define LATM_SIZE_MASK 0x001FFF // bottom 13 bits
++
++typedef struct LATMParseContext{
++ ParseContext pc;
++ int count;
++} LATMParseContext;
++
++/**
++ * finds the end of the current frame in the bitstream.
++ * @return the position of the first byte of the next frame, or -1
++ */
++static int latm_find_frame_end(AVCodecParserContext *s1, const uint8_t *buf,
++ int buf_size) {
++ LATMParseContext *s = s1->priv_data;
++ ParseContext *pc = &s->pc;
++ int pic_found, i;
++ uint32_t state;
++
++ pic_found = pc->frame_start_found;
++ state = pc->state;
++
++ i = 0;
++ if(!pic_found){
++ for(i=0; i<buf_size; i++){
++ state = (state<<8) | buf[i];
++ if((state & LATM_MASK) == LATM_HEADER){
++ i++;
++ s->count = - i;
++ pic_found=1;
++ break;
++ }
++ }
++ }
++
++ if(pic_found){
++ /* EOF considered as end of frame */
++ if (buf_size == 0)
++ return 0;
++ if((state & LATM_SIZE_MASK) - s->count <= buf_size) {
++ pc->frame_start_found = 0;
++ pc->state = -1;
++ return (state & LATM_SIZE_MASK) - s->count;
++ }
++ }
++
++ s->count += buf_size;
++ pc->frame_start_found = pic_found;
++ pc->state = state;
++ return END_NOT_FOUND;
++}
++
++static int latm_parse(AVCodecParserContext *s1,
++ AVCodecContext *avctx,
++ const uint8_t **poutbuf, int *poutbuf_size,
++ const uint8_t *buf, int buf_size)
++{
++ LATMParseContext *s = s1->priv_data;
++ ParseContext *pc = &s->pc;
++ int next;
++
++ if(s1->flags & PARSER_FLAG_COMPLETE_FRAMES){
++ next = buf_size;
++ }else{
++ next = latm_find_frame_end(s1, buf, buf_size);
++
++ if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
++ *poutbuf = NULL;
++ *poutbuf_size = 0;
++ return buf_size;
++ }
++ }
++ *poutbuf = buf;
++ *poutbuf_size = buf_size;
++ return next;
++}
++
++static int latm_split(AVCodecContext *avctx,
++ const uint8_t *buf, int buf_size)
++{
++ int i;
++ uint32_t state= -1;
++
++ for(i=0; i<buf_size; i++){
++ state= (state<<8) | buf[i];
++ if((state & LATM_MASK) == LATM_HEADER)
++ return i-2;
++ }
++ return 0;
++}
++
++AVCodecParser aac_latm_parser = {
++ { CODEC_ID_AAC_LATM },
++ sizeof(LATMParseContext),
++ NULL,
++ latm_parse,
++ ff_parse_close,
++ latm_split,
++};
+diff -Naur ffmpeg.orig/libavcodec/latmaac.c ffmpeg/libavcodec/latmaac.c
+--- ffmpeg.orig/libavcodec/latmaac.c 1969-12-31 19:00:00.000000000 -0500
++++ ffmpeg/libavcodec/latmaac.c 2009-02-21 08:25:13.000000000 -0500
+@@ -0,0 +1,624 @@
++/*
++ * copyright (c) 2008 Paul Kendall <[email protected]>
++ *
++ * This file is part of FFmpeg.
++ *
++ * FFmpeg is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Lesser General Public
++ * License as published by the Free Software Foundation; either
++ * version 2.1 of the License, or (at your option) any later version.
++ *
++ * FFmpeg is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
++ * Lesser General Public License for more details.
++ *
++ * You should have received a copy of the GNU Lesser General Public
++ * License along with FFmpeg; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
++ */
++
++/**
++ * @file latmaac.c
++ * LATM wrapped AAC decoder
++ */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <math.h>
++#include <sys/types.h>
++
++#include "parser.h"
++#include "bitstream.h"
++#include "mpeg4audio.h"
++#include "neaacdec.h"
++
++#define min(a,b) ((a)<(b) ? (a) : (b))
++
++
++/*
++ Note: This decoder filter is intended to decode LATM streams transferred
++ in MPEG transport streams which are only supposed to contain one program.
++ To do a more complex LATM demuxing a separate LATM demuxer should be used.
++*/
++
++#define AAC_NONE 0 // mode not detected (or indicated in mediatype)
++#define AAC_LATM 1 // LATM packets (ISO/IEC 14496-3 1.7.3 Multiplex layer)
++
++#define SYNC_LATM 0x2b7 // 11 bits
++
++#define MAX_SIZE 8*1024
++
++typedef struct AACConfig
++{
++ uint8_t extra[64]; // should be way enough
++ int extrasize;
++
++ int audioObjectType;
++ int samplingFrequencyIndex;
++ int samplingFrequency;
++ int channelConfiguration;
++ int channels;
++} AACConfig;
++
++typedef struct AACParser
++{
++ AACConfig config;
++ uint8_t frameLengthType;
++ uint16_t muxSlotLengthBytes;
++
++ uint8_t audio_mux_version;
++ uint8_t audio_mux_version_A;
++ int taraFullness;
++ uint8_t config_crc;
++ int64_t other_data_bits;
++
++ int mode;
++ int offset; // byte offset in "buf" buffer
++ uint8_t buf[MAX_SIZE]; // allocated buffer
++ int count; // number of bytes written in buffer
++} AACParser;
++
++typedef struct AACDecoder
++{
++ AACParser *parser;
++ faacDecHandle aac_decoder;
++ int open;
++ uint32_t in_samplerate;
++ uint8_t in_channels;
++} AACDecoder;
++
++typedef struct {
++ AACDecoder* decoder;
++} FAACContext;
++
++static inline int64_t latm_get_value(GetBitContext *b)
++{
++ uint8_t bytesForValue = get_bits(b, 2);
++ int64_t value = 0;
++ int i;
++ for (i=0; i<=bytesForValue; i++) {
++ value <<= 8;
++ value |= get_bits(b, 8);
++ }
++ return value;
++}
++
++static void readGASpecificConfig(struct AACConfig *cfg, GetBitContext *b, PutBitContext *o)
++{
++ int framelen_flag = get_bits(b, 1);
++ put_bits(o, 1, framelen_flag);
++ int dependsOnCoder = get_bits(b, 1);
++ put_bits(o, 1, dependsOnCoder);
++ int ext_flag;
++ int delay;
++ int layerNr;
++
++ if (dependsOnCoder) {
++ delay = get_bits(b, 14);
++ put_bits(o, 14, delay);
++ }
++ ext_flag = get_bits(b, 1);
++ put_bits(o, 1, ext_flag);
++ if (!cfg->channelConfiguration) {
++ // program config element
++ // TODO:
++ }
++
++ if (cfg->audioObjectType == 6 || cfg->audioObjectType == 20) {
++ layerNr = get_bits(b, 3);
++ put_bits(o, 3, layerNr);
++ }
++ if (ext_flag) {
++ if (cfg->audioObjectType == 22) {
++ skip_bits(b, 5); // numOfSubFrame
++ skip_bits(b, 11); // layer_length
++
++ put_bits(o, 16, 0);
++ }
++ if (cfg->audioObjectType == 17 ||
++ cfg->audioObjectType == 19 ||
++ cfg->audioObjectType == 20 ||
++ cfg->audioObjectType == 23) {
++
++ skip_bits(b, 3); // stuff
++ put_bits(o, 3, 0);
++ }
++
++ skip_bits(b, 1); // extflag3
++ put_bits(o, 1, 0);
++ }
++}
++
++static int readAudioSpecificConfig(struct AACConfig *cfg, GetBitContext *b)
++{
++ PutBitContext o;
++ init_put_bits(&o, cfg->extra, sizeof(cfg->extra));
++
++ // returns the number of bits read
++ int ret = 0;
++ int sbr_present = -1;
++
++ // object
++ cfg->audioObjectType = get_bits(b, 5);
++ put_bits(&o, 5, cfg->audioObjectType);
++ if (cfg->audioObjectType == 31) {
++ uint8_t n = get_bits(b, 6);
++ put_bits(&o, 6, n);
++ cfg->audioObjectType = 32 + n;
++ }
++
++ cfg->samplingFrequencyIndex = get_bits(b, 4);
++ cfg->samplingFrequency = ff_mpeg4audio_sample_rates[cfg->samplingFrequencyIndex];
++ put_bits(&o, 4, cfg->samplingFrequencyIndex);
++ if (cfg->samplingFrequencyIndex == 0x0f) {
++ uint32_t f = get_bits_long(b, 24);
++ put_bits(&o, 24, f);
++ cfg->samplingFrequency = f;
++ }
++ cfg->channelConfiguration = get_bits(b, 4);
++ put_bits(&o, 4, cfg->channelConfiguration);
++ cfg->channels = ff_mpeg4audio_channels[cfg->channelConfiguration];
++
++ if (cfg->audioObjectType == 5) {
++ sbr_present = 1;
++
++ // TODO: parsing !!!!!!!!!!!!!!!!
++ }
++
++ switch (cfg->audioObjectType) {
++ case 1:
++ case 2:
++ case 3:
++ case 4:
++ case 6:
++ case 7:
++ case 17:
++ case 19:
++ case 20:
++ case 21:
++ case 22:
++ case 23:
++ readGASpecificConfig(cfg, b, &o);
++ break;
++ }
++
++ if (sbr_present == -1) {
++ if (cfg->samplingFrequency <= 24000) {
++ cfg->samplingFrequency *= 2;
++ }
++ }
++
++ // count the extradata
++ ret = put_bits_count(&o);
++ align_put_bits(&o);
++ flush_put_bits(&o);
++ cfg->extrasize = (ret + 7) >> 3;
++ return ret;
++}
++
++static void readStreamMuxConfig(struct AACParser *parser, GetBitContext *b)
++{
++ parser->audio_mux_version_A = 0;
++ parser->audio_mux_version = get_bits(b, 1);
++ if (parser->audio_mux_version == 1) { // audioMuxVersion
++ parser->audio_mux_version_A = get_bits(b, 1);
++ }
++
++ if (parser->audio_mux_version_A == 0) {
++ if (parser->audio_mux_version == 1) {
++ parser->taraFullness = latm_get_value(b);
++ }
++ get_bits(b, 1); // allStreamSameTimeFraming = 1
++ get_bits(b, 6); // numSubFrames = 0
++ get_bits(b, 4); // numPrograms = 0
++
++ // for each program
++ get_bits(b, 3); // numLayer = 0
++
++ // for each layer
++ if (parser->audio_mux_version == 0) {
++ // audio specific config.
++ readAudioSpecificConfig(&parser->config, b);
++ } else {
++ int ascLen = latm_get_value(b);
++ ascLen -= readAudioSpecificConfig(&parser->config, b);
++
++ // fill bits
++ while (ascLen > 16) {
++ skip_bits(b, 16);
++ ascLen -= 16;
++ }
++ skip_bits(b, ascLen);
++ }
++
++ // these are not needed... perhaps
++ int frame_length_type = get_bits(b, 3);
++ parser->frameLengthType = frame_length_type;
++ if (frame_length_type == 0) {
++ get_bits(b, 8);
++ } else if (frame_length_type == 1) {
++ get_bits(b, 9);
++ } else if (frame_length_type == 3 ||
++ frame_length_type == 4 ||
++ frame_length_type == 5) {
++ int celp_table_index = get_bits(b, 6);
++ } else if (frame_length_type == 6 ||
++ frame_length_type == 7) {
++ int hvxc_table_index = get_bits(b, 1);
++ }
++
++ // other data
++ parser->other_data_bits = 0;
++ if (get_bits(b, 1)) {
++ // other data present
++ if (parser->audio_mux_version == 1) {
++ parser->other_data_bits = latm_get_value(b);
++ } else {
++ // other data not present
++ parser->other_data_bits = 0;
++ int esc, tmp;
++ do {
++ parser->other_data_bits <<= 8;
++ esc = get_bits(b, 1);
++ tmp = get_bits(b, 8);
++ parser->other_data_bits |= tmp;
++ } while (esc);
++ }
++ }
++
++ // CRC
++ if (get_bits(b, 1)) {
++ parser->config_crc = get_bits(b, 8);
++ }
++ } else {
++ // tbd
++ }
++}
++
++static void readPayloadLengthInfo(struct AACParser *parser, GetBitContext *b)
++{
++ uint8_t tmp;
++ if (parser->frameLengthType == 0) {
++ parser->muxSlotLengthBytes = 0;
++ do {
++ tmp = get_bits(b, 8);
++ parser->muxSlotLengthBytes += tmp;
++ } while (tmp == 255);
++ } else {
++ if (parser->frameLengthType == 5 ||
++ parser->frameLengthType == 7 ||
++ parser->frameLengthType == 3) {
++ get_bits(b, 2);
++ }
++ }
++}
++
++static void readAudioMuxElement(struct AACParser *parser, GetBitContext *b, uint8_t *payload, int *payloadsize)
++{
++ uint8_t use_same_mux = get_bits(b, 1);
++ if (!use_same_mux) {
++ readStreamMuxConfig(parser, b);
++ }
++
++ if (parser->audio_mux_version_A == 0) {
++ int j;
++
++ readPayloadLengthInfo(parser, b);
++
++ // copy data
++ for (j=0; j<parser->muxSlotLengthBytes; j++) {
++ *payload++ = get_bits(b, 8);
++ }
++ *payloadsize = parser->muxSlotLengthBytes;
++
++ // ignore otherdata
++ } else {
++ // TBD
++ }
++}
++
++static int readAudioSyncStream(struct AACParser *parser, GetBitContext *b, int size, uint8_t *payload, int *payloadsize)
++{
++ // ISO/IEC 14496-3 Table 1.28 - Syntax of AudioMuxElement()
++ if (get_bits(b, 11) != 0x2b7) return -1; // not LATM
++ int muxlength = get_bits(b, 13);
++
++ if (3+muxlength > size) return 0; // not enough data
++
++ readAudioMuxElement(parser, b, payload, payloadsize);
++
++ // we don't parse anything else here...
++ return (3+muxlength);
++}
++
++
++static void flush_buf(struct AACParser *parser, int offset) {
++ int bytes_to_flush = min(parser->count, offset);
++ int left = (parser->count - bytes_to_flush);
++
++ if (bytes_to_flush > 0) {
++ if (left > 0) {
++ memcpy(parser->buf, parser->buf+bytes_to_flush, left);
++ parser->count = left;
++ } else {
++ parser->count = 0;
++ }
++ }
++}
++
++static struct AACParser *latm_create_parser()
++{
++ struct AACParser *parser = (struct AACParser *)av_malloc(sizeof(struct AACParser));
++ memset(parser, 0, sizeof(struct AACParser));
++ return parser;
++}
++
++static void latm_destroy_parser(struct AACParser *parser)
++{
++ av_free(parser);
++}
++
++static void latm_flush(struct AACParser *parser)
++{
++ parser->offset = 0;
++ parser->count = 0;
++}
++
++static void latm_write_data(struct AACParser *parser, uint8_t *data, int len)
++{
++ // buffer overflow check... just ignore the data before
++ if (parser->count + len > MAX_SIZE) {
++ flush_buf(parser, parser->offset);
++ parser->offset = 0;
++ if (parser->count + len > MAX_SIZE) {
++ int to_flush = (parser->count+len) - MAX_SIZE;
++ flush_buf(parser, to_flush);
++ }
++ }
++
++ // append data
++ memcpy(parser->buf+parser->count, data, len);
++ parser->count += len;
++}
++
++static int latm_parse_packet(struct AACParser *parser, uint8_t *data, int maxsize)
++{
++ /*
++ Return value is either number of bytes parsed or
++ -1 when failed.
++ 0 = need more data.
++ */
++
++ uint8_t *start = parser->buf + parser->offset;
++ int bytes = parser->count - parser->offset;
++ GetBitContext b;
++ init_get_bits(&b, start, bytes);
++
++ if (parser->mode == AAC_LATM) {
++ int outsize = 0;
++ int ret = readAudioSyncStream(parser, &b, bytes, data, &outsize);
++
++ if (ret < 0) return -1;
++ if (ret == 0) return 0;
++
++ // update the offset
++ parser->offset += ret;
++ return outsize;
++ }
++
++ // check for syncwords
++ while (bytes > 2) {
++ if (show_bits(&b, 11) == SYNC_LATM) {
++ // we must parse config first...
++ int outsize = 0;
++
++ // check if there is a complete packet available...
++ int ret = readAudioSyncStream(parser, &b, bytes, data, &outsize);
++ if (ret < 0) return -1;
++ if (ret == 0) return 0;
++ parser->offset += ret;
++
++ parser->mode = AAC_LATM;
++ return outsize;
++ }
++ skip_bits(&b, 8);
++ parser->offset++;
++ bytes--;
++ }
++ return 0;
++}
++
++static void aac_filter_close(AACDecoder *decoder)
++{
++ if (decoder->aac_decoder) {
++ NeAACDecClose(decoder->aac_decoder);
++ decoder->aac_decoder = NULL;
++ }
++ decoder->open = 0;
++}
++
++static int aac_decoder_open(AACDecoder *decoder)
++{
++ if (decoder->aac_decoder) return 0;
++
++ decoder->aac_decoder = NeAACDecOpen();
++ if (!decoder->aac_decoder) return -1;
++
++ // are we going to initialize from decoder specific info ?
++ if (decoder->parser->config.extrasize > 0) {
++ char ret = NeAACDecInit2(decoder->aac_decoder, (unsigned char*)decoder->parser->config.extra, decoder->parser->config.extrasize, &decoder->in_samplerate, &decoder->in_channels);
++ if (ret < 0) {
++ aac_filter_close(decoder); // gone wrong ?
++ return -1;
++ }
++ decoder->open = 1;
++ } else {
++ // we'll open the decoder later...
++ decoder->open = 0;
++ }
++ return 0;
++}
++
++AACDecoder *aac_filter_create()
++{
++ AACDecoder *decoder = (AACDecoder *)av_malloc(sizeof(AACDecoder));
++ decoder->parser = latm_create_parser();
++ decoder->aac_decoder = NULL;
++ decoder->open = 0;
++ return (void *)decoder;
++}
++
++void aac_filter_destroy(AACDecoder *decoder)
++{
++ aac_filter_close(decoder);
++ latm_destroy_parser(decoder->parser);
++ av_free(decoder);
++}
++
++int aac_filter_receive(AACDecoder *decoder, void *out, int *out_size, uint8_t *data, int size)
++{
++ uint8_t tempbuf[32*1024];
++ int ret;
++ int consumed = size;
++ int decoded;
++ int max_size = *out_size;
++
++ *out_size = 0;
++
++ //-------------------------------------------------------------------------
++ // Multiplex Parsing
++ //-------------------------------------------------------------------------
++
++ latm_write_data(decoder->parser, data, size);
++
++ do {
++ ret = latm_parse_packet(decoder->parser, tempbuf, sizeof(tempbuf));
++ if (ret < 0) {
++ latm_flush(decoder->parser);
++ return consumed;
++ }
++ if (ret == 0) return consumed;
++
++ data = tempbuf;
++ size = ret;
++
++ //-------------------------------------------------------------------------
++ // Initialize decoder (if necessary)
++ //-------------------------------------------------------------------------
++ if (!decoder->open) {
++ aac_filter_close(decoder);
++ if (decoder->parser->mode == AAC_LATM) {
++ ret = aac_decoder_open(decoder);
++ if (ret < 0) return consumed;
++ }
++
++ if(!decoder->open) return consumed;
++ }
++
++ //-------------------------------------------------------------------------
++ // Decode samples
++ //-------------------------------------------------------------------------
++ NeAACDecFrameInfo info;
++ void *buf = NeAACDecDecode(decoder->aac_decoder, &info, data, size);
++
++ if (buf) {
++ decoder->in_samplerate = info.samplerate;
++ decoder->in_channels = info.channels;
++
++ //---------------------------------------------------------------------
++ // Deliver decoded samples
++ //---------------------------------------------------------------------
++
++ // kram dekoduje 16-bit. my vypustame 16-bit. takze by to malo byt okej
++ decoded = info.samples * sizeof(short);
++
++ // napraskame tam sample
++ *out_size += decoded;
++ if(*out_size > max_size) {
++ av_log(NULL, AV_LOG_ERROR, "overflow!\n");
++ } else {
++ memcpy(out, buf, decoded);
++ out = (unsigned char *)out + decoded;
++ }
++ } else {
++ // need more data
++ break;
++ }
++
++ } while (1); // decode all packets
++ return consumed;
++}
++
++void aac_filter_getinfo(AACDecoder *decoder, int *sample_rate, int *channels)
++{
++ if(!decoder->open) return;
++ *sample_rate = decoder->in_samplerate;
++ *channels = decoder->in_channels;
++}
++
++static int faac_decode_init(AVCodecContext *avctx)
++{
++ FAACContext *s = avctx->priv_data;
++ avctx->frame_size = 360;
++ avctx->sample_rate = 48000;
++ avctx->channels = 2;
++ avctx->bit_rate = 8192 * 8 * avctx->sample_rate / avctx->frame_size;
++ s->decoder = aac_filter_create();
++ return 0;
++}
++
++static int faac_decode_frame(AVCodecContext *avctx,
++ void *data, int *data_size,
++ uint8_t *buf, int buf_size)
++{
++ FAACContext *s = avctx->priv_data;
++ int ret;
++
++ if (s->decoder == NULL) faac_decode_init(avctx);
++ ret = aac_filter_receive(s->decoder, data, data_size, buf, buf_size);
++ aac_filter_getinfo(s->decoder, &(avctx->sample_rate), &(avctx->channels));
++ return ret;
++}
++
++static int faac_decode_end(AVCodecContext *avctx)
++{
++ FAACContext *s = avctx->priv_data;
++ if(s->decoder != NULL) {
++ aac_filter_destroy(s->decoder);
++ }
++ return 0;
++}
++
++AVCodec libfaad2_decoder = {
++ .name = "AAC_LATM",
++ .type = CODEC_TYPE_AUDIO,
++ .id = CODEC_ID_AAC_LATM,
++ .priv_data_size = sizeof (FAACContext),
++ .init = faac_decode_init,
++ .close = faac_decode_end,
++ .decode = faac_decode_frame,
++ .long_name = "AAC over LATM",
++};
++
+diff -Naur ffmpeg.orig/libavformat/mpeg.c ffmpeg/libavformat/mpeg.c
+--- ffmpeg.orig/libavformat/mpeg.c 2008-10-02 12:03:00.000000000 -0400
++++ ffmpeg/libavformat/mpeg.c 2009-02-21 08:25:13.000000000 -0500
+@@ -281,7 +281,7 @@
+ /* find matching stream */
+ if (!((startcode >= 0x1c0 && startcode <= 0x1df) ||
+ (startcode >= 0x1e0 && startcode <= 0x1ef) ||
+- (startcode == 0x1bd) || (startcode == 0x1fd)))
++ (startcode == 0x1bd) || (startcode == 0x1fa) || (startcode == 0x1fd)))
+ goto redo;
+ if (ppos) {
+ *ppos = url_ftell(s->pb) - 4;
+@@ -441,6 +441,9 @@
+ } else if(es_type == STREAM_TYPE_AUDIO_AAC){
+ codec_id = CODEC_ID_AAC;
+ type = CODEC_TYPE_AUDIO;
++ } else if(es_type == STREAM_TYPE_AUDIO_AAC_LATM){
++ codec_id = CODEC_ID_AAC_LATM;
++ type = CODEC_TYPE_AUDIO;
+ } else if(es_type == STREAM_TYPE_VIDEO_MPEG4){
+ codec_id = CODEC_ID_MPEG4;
+ type = CODEC_TYPE_VIDEO;
+diff -Naur ffmpeg.orig/libavformat/mpeg.h ffmpeg/libavformat/mpeg.h
+--- ffmpeg.orig/libavformat/mpeg.h 2008-08-31 03:39:47.000000000 -0400
++++ ffmpeg/libavformat/mpeg.h 2009-02-21 08:25:13.000000000 -0500
+@@ -53,6 +53,7 @@
+ #define STREAM_TYPE_PRIVATE_DATA 0x06
+ #define STREAM_TYPE_AUDIO_AAC 0x0f
+ #define STREAM_TYPE_VIDEO_MPEG4 0x10
++#define STREAM_TYPE_AUDIO_AAC_LATM 0x11
+ #define STREAM_TYPE_VIDEO_H264 0x1b
+
+ #define STREAM_TYPE_AUDIO_AC3 0x81
+diff -Naur ffmpeg.orig/libavformat/mpegts.c ffmpeg/libavformat/mpegts.c
+--- ffmpeg.orig/libavformat/mpegts.c 2008-10-02 12:28:58.000000000 -0400
++++ ffmpeg/libavformat/mpegts.c 2009-02-21 08:25:13.000000000 -0500
+@@ -625,6 +625,7 @@
+ case STREAM_TYPE_VIDEO_VC1:
+ case STREAM_TYPE_VIDEO_DIRAC:
+ case STREAM_TYPE_AUDIO_AAC:
++ case STREAM_TYPE_AUDIO_AAC_LATM:
+ case STREAM_TYPE_AUDIO_AC3:
+ case STREAM_TYPE_AUDIO_DTS:
+ case STREAM_TYPE_AUDIO_HDMV_DTS:
+@@ -847,7 +848,7 @@
+ code = pes->header[3] | 0x100;
+ if (!((code >= 0x1c0 && code <= 0x1df) ||
+ (code >= 0x1e0 && code <= 0x1ef) ||
+- (code == 0x1bd) || (code == 0x1fd)))
++ (code == 0x1bd) || (code == 0x1fa) || (code == 0x1fd)))
+ goto skip;
+ if (!pes->st) {
+ /* allocate stream */
+@@ -968,6 +969,10 @@
+ codec_type = CODEC_TYPE_AUDIO;
+ codec_id = CODEC_ID_AAC;
+ break;
++ case STREAM_TYPE_AUDIO_AAC_LATM:
++ codec_type = CODEC_TYPE_AUDIO;
++ codec_id = CODEC_ID_AAC_LATM;
++ break;
+ case STREAM_TYPE_AUDIO_AC3:
+ codec_type = CODEC_TYPE_AUDIO;
+ codec_id = CODEC_ID_AC3;
+diff -Naur ffmpeg.orig/libavformat/mpegts.h ffmpeg/libavformat/mpegts.h
+--- ffmpeg.orig/libavformat/mpegts.h 2008-08-31 03:39:47.000000000 -0400
++++ ffmpeg/libavformat/mpegts.h 2009-02-21 08:25:13.000000000 -0500
+@@ -50,6 +50,7 @@
+ #define STREAM_TYPE_PRIVATE_DATA 0x06
+ #define STREAM_TYPE_AUDIO_AAC 0x0f
+ #define STREAM_TYPE_VIDEO_MPEG4 0x10
++#define STREAM_TYPE_AUDIO_AAC_LATM 0x11
+ #define STREAM_TYPE_VIDEO_H264 0x1b
+ #define STREAM_TYPE_VIDEO_VC1 0xea
+ #define STREAM_TYPE_VIDEO_DIRAC 0xd1
diff --git a/contrib/ffmpeg/A01-mpegleak.patch b/contrib/ffmpeg/A01-mpegleak.patch
new file mode 100644
index 000000000..36179ba57
--- /dev/null
+++ b/contrib/ffmpeg/A01-mpegleak.patch
@@ -0,0 +1,56 @@
+diff -Naur ffmpeg.orig/libavcodec/h264.c ffmpeg/libavcodec/h264.c
+--- ffmpeg.orig/libavcodec/h264.c 2008-12-01 11:24:19.000000000 -0500
++++ ffmpeg/libavcodec/h264.c 2009-02-21 08:23:58.000000000 -0500
+@@ -3298,7 +3298,7 @@
+ * stream. Need to discard one frame. Prevents overrun of the
+ * short_ref and long_ref buffers.
+ */
+- av_log(h->s.avctx, AV_LOG_ERROR,
++ av_log(h->s.avctx, AV_LOG_DEBUG,
+ "number of reference frames exceeds max (probably "
+ "corrupt input), discarding one\n");
+
+@@ -7556,7 +7556,7 @@
+
+ if(!(s->flags2 & CODEC_FLAG2_CHUNKS) && !s->current_picture_ptr){
+ if (avctx->skip_frame >= AVDISCARD_NONREF || s->hurry_up) return 0;
+- av_log(avctx, AV_LOG_ERROR, "no frame!\n");
++ av_log(avctx, AV_LOG_DEBUG, "no frame!\n");
+ return -1;
+ }
+
+diff -Naur ffmpeg.orig/libavcodec/mpegvideo.c ffmpeg/libavcodec/mpegvideo.c
+--- ffmpeg.orig/libavcodec/mpegvideo.c 2008-10-01 20:27:09.000000000 -0400
++++ ffmpeg/libavcodec/mpegvideo.c 2009-02-21 08:23:58.000000000 -0500
+@@ -779,19 +779,18 @@
+ }
+
+ av_log(s->avctx, AV_LOG_FATAL, "Internal error, picture buffer overflow\n");
+- /* We could return -1, but the codec would crash trying to draw into a
+- * non-existing frame anyway. This is safer than waiting for a random crash.
+- * Also the return of this is never useful, an encoder must only allocate
+- * as much as allowed in the specification. This has no relationship to how
+- * much libavcodec could allocate (and MAX_PICTURE_COUNT is always large
+- * enough for such valid streams).
+- * Plus, a decoder has to check stream validity and remove frames if too
+- * many reference frames are around. Waiting for "OOM" is not correct at
+- * all. Similarly, missing reference frames have to be replaced by
+- * interpolated/MC frames, anything else is a bug in the codec ...
+- */
+- abort();
+- return -1;
++ /* XXX there seems to be a leak caused by h264 in mpeg transport
++ * streams: Over-the-air streams have a lot of errors. A picture
++ * may be marked as referenced but the actual references get lost
++ * so it never gets released. We take care of that here by releasing
++ * the oldest we have & reusing its slot. */
++ int oldest=0;
++ for(i=0; i<MAX_PICTURE_COUNT; i++){
++ if (s->picture[i].coded_picture_number < s->picture[oldest].coded_picture_number)
++ oldest = i;
++ }
++ s->avctx->release_buffer(s->avctx, (AVFrame*)&s->picture[oldest]);
++ return oldest;
+ }
+
+ static void update_noise_reduction(MpegEncContext *s){
diff --git a/contrib/ffmpeg/A02-audioconvert.patch b/contrib/ffmpeg/A02-audioconvert.patch
new file mode 100644
index 000000000..5062e3439
--- /dev/null
+++ b/contrib/ffmpeg/A02-audioconvert.patch
@@ -0,0 +1,12 @@
+diff -Naur ffmpeg.orig/libavcodec/Makefile ffmpeg/libavcodec/Makefile
+--- ffmpeg.orig/libavcodec/Makefile 2008-12-01 01:40:36.000000000 -0500
++++ ffmpeg/libavcodec/Makefile 2009-02-23 07:03:23.000000000 -0500
+@@ -3,7 +3,7 @@
+ NAME = avcodec
+ FFLIBS = avutil
+
+-HEADERS = avcodec.h opt.h
++HEADERS = avcodec.h opt.h audioconvert.h
+
+ OBJS = allcodecs.o \
+ audioconvert.o \
diff --git a/contrib/ffmpeg/P00-cygwin.patch b/contrib/ffmpeg/P00-cygwin.patch
new file mode 100644
index 000000000..b6ca99f26
--- /dev/null
+++ b/contrib/ffmpeg/P00-cygwin.patch
@@ -0,0 +1,15 @@
+diff -Naur ffmpeg/libavcodec/mpegaudiodec.c ffmpeg-patched/libavcodec/mpegaudiodec.c
+--- ffmpeg/libavcodec/mpegaudiodec.c 2006-09-23 14:22:06.000000000 -0400
++++ ffmpeg-patched/libavcodec/mpegaudiodec.c 2007-01-01 18:31:51.156250000 -0500
+@@ -401,9 +401,9 @@
+ for(i=0; i<512*16; i++){
+ int exponent= (i>>4);
+ double f= pow(i&15, 4.0 / 3.0) * pow(2, (exponent-400)*0.25 + FRAC_BITS + 5);
+- expval_table[exponent][i&15]= llrint(f);
++ expval_table[exponent][i&15]= lrint(f);
+ if((i&15)==1)
+- exp_table[exponent]= llrint(f);
++ exp_table[exponent]= lrint(f);
+ }
+
+ for(i=0;i<7;i++) {
diff --git a/contrib/ffmpeg/P01-sunos.patch b/contrib/ffmpeg/P01-sunos.patch
new file mode 100644
index 000000000..f5cd7d726
--- /dev/null
+++ b/contrib/ffmpeg/P01-sunos.patch
@@ -0,0 +1,25 @@
+--- ffmpeg/configure Sat Jun 7 03:19:09 2008
++++ ffmpeg.solaris/configure Thu Jun 19 12:10:48 2008
+@@ -50,6 +50,9 @@
+ exit 1
+ fi
+
++# Solaris must use the xpg4 version of grep
++PATH=/usr/xpg4/bin:$PATH
++
+ show_help(){
+ echo "Usage: configure [options]"
+ echo "Options: [defaults in brackets after descriptions]"
+@@ -1585,8 +1588,11 @@
+ check_cc <<EOF || die "endian test failed"
+ unsigned int endian = 'B' << 24 | 'I' << 16 | 'G' << 8 | 'E';
+ EOF
+-od -A n -t x1 $TMPO | grep -q '42 *49 *47 *45' && enable bigendian
++#od -A n -t x1 $TMPO | grep -q '42 *49 *47 *45' && enable bigendian
++/usr/bin/tr -cd "BIGE" < $TMPO | grep -q 'B *I *G *E' && enable bigendian
+
++echo "BIGE=$bigendian"
++
+ # ---
+ # check availability of some header files
+
diff --git a/contrib/ffmpeg/P02-darwin-h264dsp-crash.patch b/contrib/ffmpeg/P02-darwin-h264dsp-crash.patch
new file mode 100644
index 000000000..53b5cf09d
--- /dev/null
+++ b/contrib/ffmpeg/P02-darwin-h264dsp-crash.patch
@@ -0,0 +1,13 @@
+Index: ffmpeg/libavcodec/i386/dsputil_mmx.c
+===================================================================
+--- ffmpeg/libavcodec/i386/dsputil_mmx.c (revision 14508)
++++ ffmpeg/libavcodec/i386/dsputil_mmx.c (working copy)
+@@ -2626,6 +2626,8 @@
+ H264_QPEL_FUNCS(3, 2, sse2);
+ H264_QPEL_FUNCS(3, 3, sse2);
+ }
++#undef H264_QPEL_FUNCS
++#define H264_QPEL_FUNCS(x, y, CPU)
+ #ifdef HAVE_SSSE3
+ if(mm_flags & MM_SSSE3){
+ H264_QPEL_FUNCS(1, 0, ssse3);
diff --git a/contrib/ffmpeg/module.defs b/contrib/ffmpeg/module.defs
new file mode 100644
index 000000000..b41291018
--- /dev/null
+++ b/contrib/ffmpeg/module.defs
@@ -0,0 +1,32 @@
+$(eval $(call import.MODULE.defs,FFMPEG,ffmpeg,FAAD2))
+$(eval $(call import.CONTRIB.defs,FFMPEG))
+
+FFMPEG.FETCH.url = http://download.m0k.org/handbrake/contrib/ffmpeg-r15974.tar.gz
+FFMPEG.EXTRACT.tarbase = ffmpeg
+
+FFMPEG.CONFIGURE.deps =
+FFMPEG.CONFIGURE.env =
+FFMPEG.CONFIGURE.host =
+
+FFMPEG.CONFIGURE.extra = \
+ --disable-bsfs \
+ --disable-encoders \
+ --disable-ffmpeg \
+ --disable-ffserver \
+ --disable-muxers \
+ --disable-vhook \
+ --enable-encoder=ac3 \
+ --enable-encoder=mpeg4 \
+ --enable-encoder=snow \
+ --enable-gpl \
+ --enable-libfaad \
+ --enable-muxer=ipod \
+ --enable-pthreads \
+ --enable-swscale \
+ --cc="$(GCC.gcc)" \
+ --extra-cflags="$(call fn.ARGS,FFMPEG.GCC,*archs) -I$(call fn.ABSOLUTE,$(CONTRIB.build/)include)" \
+ --extra-ldflags="$(call fn.ARGS,FFMPEG.GCC,*archs) -L$(call fn.ABSOLUTE,$(CONTRIB.build/)lib)"
+
+ifeq ($(BUILD.cross),1)
+ FFMPEG.CONFIGURE.extra += --enable-cross-compile --arch=$(FFMPEG.GCC.archs)
+endif
diff --git a/contrib/ffmpeg/module.rules b/contrib/ffmpeg/module.rules
new file mode 100644
index 000000000..7f475b3ec
--- /dev/null
+++ b/contrib/ffmpeg/module.rules
@@ -0,0 +1,2 @@
+$(eval $(call import.MODULE.rules,FFMPEG))
+$(eval $(call import.CONTRIB.rules,FFMPEG))