Revision: 5390 Author: pebender Date: Mon Aug 31 10:02:57 2009 Log: - Added LATM AAC support to MythTV 0.21.
http://code.google.com/p/minimyth/source/detail?r=5390 Added: /trunk/gar-minimyth/script/myth-0.21/mythtv/files/mythtv-0.21-ticket-5487.patch Modified: /trunk/gar-minimyth/html/minimyth/document-changelog.txt /trunk/gar-minimyth/script/myth-0.21/mythtv/Makefile /trunk/gar-minimyth/script/myth-0.21/mythtv/checksums ======================================= --- /dev/null +++ /trunk/gar-minimyth/script/myth-0.21/mythtv/files/mythtv-0.21-ticket-5487.patch Mon Aug 31 10:02:57 2009 @@ -0,0 +1,882 @@ +diff -Naur mythtv-0.21-21399-old/libs/libavcodec/aac_parser.c mythtv-0.21-21399-new/libs/libavcodec/aac_parser.c +--- mythtv-0.21-21399-old/libs/libavcodec/aac_parser.c 2009-08-21 05:52:30.000000000 -0700 ++++ mythtv-0.21-21399-new/libs/libavcodec/aac_parser.c 2009-08-31 07:25:58.000000000 -0700 +@@ -28,12 +28,12 @@ + #define AAC_HEADER_SIZE 7 + + +-static const int aac_sample_rates[16] = { ++const int aac_sample_rates[16] = { + 96000, 88200, 64000, 48000, 44100, 32000, + 24000, 22050, 16000, 12000, 11025, 8000, 7350 + }; + +-static const int aac_channels[8] = { ++const int aac_channels[8] = { + 0, 1, 2, 3, 4, 5, 6, 8 + }; + +diff -Naur mythtv-0.21-21399-old/libs/libavcodec/allcodecs.c mythtv-0.21-21399-new/libs/libavcodec/allcodecs.c +--- mythtv-0.21-21399-old/libs/libavcodec/allcodecs.c 2009-08-31 07:25:39.000000000 -0700 ++++ mythtv-0.21-21399-new/libs/libavcodec/allcodecs.c 2009-08-31 07:25:58.000000000 -0700 +@@ -283,6 +283,7 @@ + REGISTER_ENCDEC (LIBAMR_WB, libamr_wb); + 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); +@@ -293,6 +294,7 @@ + + /* parsers */ + REGISTER_PARSER (AAC, aac); ++ REGISTER_PARSER (AAC, latm); + REGISTER_PARSER (AC3, ac3); + REGISTER_PARSER (CAVSVIDEO, cavsvideo); + REGISTER_PARSER (DCA, dca); +diff -Naur mythtv-0.21-21399-old/libs/libavcodec/avcodec.h mythtv-0.21-21399-new/libs/libavcodec/avcodec.h +--- mythtv-0.21-21399-old/libs/libavcodec/avcodec.h 2009-08-31 07:25:39.000000000 -0700 ++++ mythtv-0.21-21399-new/libs/libavcodec/avcodec.h 2009-08-31 07:25:58.000000000 -0700 +@@ -244,6 +244,7 @@ + #if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0) + CODEC_ID_MPEG4AAC, + #endif ++ CODEC_ID_AAC_LATM, + CODEC_ID_AC3, + CODEC_ID_DTS, + CODEC_ID_VORBIS, +diff -Naur mythtv-0.21-21399-old/libs/libavcodec/latmaac.c mythtv-0.21-21399-new/libs/libavcodec/latmaac.c +--- mythtv-0.21-21399-old/libs/libavcodec/latmaac.c 1969-12-31 16:00:00.000000000 -0800 ++++ mythtv-0.21-21399-new/libs/libavcodec/latmaac.c 2009-08-31 07:25:58.000000000 -0700 +@@ -0,0 +1,727 @@ ++/* ++ * 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 "neaacdec.h" ++ ++extern const int aac_sample_rates[16]; ++extern const uint8_t aac_channels[8]; ++ ++#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 = aac_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 = aac_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 * 8); ++ ++ 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; ++} ++ ++ ++ ++#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; ++} ++ ++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, ++}; ++ ++AVCodecParser latm_parser = { ++ { CODEC_ID_AAC_LATM }, ++ sizeof(LATMParseContext), ++ NULL, ++ latm_parse, ++ ff_parse_close, ++ latm_split, ++}; +diff -Naur mythtv-0.21-21399-old/libs/libavcodec/libavcodec.pro mythtv-0.21-21399-new/libs/libavcodec/libavcodec.pro +--- mythtv-0.21-21399-old/libs/libavcodec/libavcodec.pro 2009-08-31 07:25:39.000000000 -0700 ++++ mythtv-0.21-21399-new/libs/libavcodec/libavcodec.pro 2009-08-31 07:25:58.000000000 -0700 +@@ -317,7 +317,7 @@ + contains( CONFIG_LIBA52, yes ) { SOURCES *= liba52.c } + contains( CONFIG_LIBAMR, yes ) { SOURCES *= libamr.c } + contains( CONFIG_LIBFAAC, yes ) { SOURCES *= libfaac.c } +-contains( CONFIG_LIBFAAD, yes ) { SOURCES *= libfaad.c } ++contains( CONFIG_LIBFAAD, yes ) { SOURCES *= libfaad.c latmaac.c } + contains( CONFIG_LIBGSM, yes ) { SOURCES *= libgsm.c } + contains( CONFIG_LIBMP3LAME, yes ) { SOURCES *= libmp3lame.c } + contains( CONFIG_LIBTHEORA, yes ) { SOURCES *= libtheoraenc.c } +diff -Naur mythtv-0.21-21399-old/libs/libavcodec/libfaad.c mythtv-0.21-21399-new/libs/libavcodec/libfaad.c +--- mythtv-0.21-21399-old/libs/libavcodec/libfaad.c 2009-08-21 05:52:30.000000000 -0700 ++++ mythtv-0.21-21399-new/libs/libavcodec/libfaad.c 2009-08-31 07:25:58.000000000 -0700 +@@ -325,6 +325,7 @@ + + // FIXME - raw AAC files - maybe just one entry will be enough + AAC_CODEC(CODEC_ID_AAC, libfaad); ++AAC_CODEC(CODEC_ID_AAC_LATM, aac_latm); + #if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0) + // If it's mp4 file - usually embeded into Qt Mov + AAC_CODEC(CODEC_ID_MPEG4AAC, mpeg4aac); +diff -Naur mythtv-0.21-21399-old/libs/libavformat/mpeg.c mythtv-0.21-21399-new/libs/libavformat/mpeg.c +--- mythtv-0.21-21399-old/libs/libavformat/mpeg.c 2009-08-31 07:25:11.000000000 -0700 ++++ mythtv-0.21-21399-new/libs/libavformat/mpeg.c 2009-08-31 07:25:58.000000000 -0700 +@@ -448,6 +448,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 mythtv-0.21-21399-old/libs/libavformat/mpeg.h mythtv-0.21-21399-new/libs/libavformat/mpeg.h +--- mythtv-0.21-21399-old/libs/libavformat/mpeg.h 2009-08-21 05:52:31.000000000 -0700 ++++ mythtv-0.21-21399-new/libs/libavformat/mpeg.h 2009-08-31 07:25:58.000000000 -0700 +@@ -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_AUDIO_AC3 0x81 +diff -Naur mythtv-0.21-21399-old/libs/libavformat/mpegts.c mythtv-0.21-21399-new/libs/libavformat/mpegts.c +--- mythtv-0.21-21399-old/libs/libavformat/mpegts.c 2009-08-21 05:52:31.000000000 -0700 ++++ mythtv-0.21-21399-new/libs/libavformat/mpegts.c 2009-08-31 07:25:58.000000000 -0700 +@@ -864,6 +864,7 @@ + case STREAM_TYPE_VIDEO_H264: + case STREAM_TYPE_VIDEO_VC1: + case STREAM_TYPE_AUDIO_AAC: ++ case STREAM_TYPE_AUDIO_AAC_LATM: + case STREAM_TYPE_AUDIO_AC3: + case STREAM_TYPE_AUDIO_DTS: + case STREAM_TYPE_PRIVATE_DATA: +@@ -1434,6 +1435,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 mythtv-0.21-21399-old/libs/libavformat/mpegts.h mythtv-0.21-21399-new/libs/libavformat/mpegts.h +--- mythtv-0.21-21399-old/libs/libavformat/mpegts.h 2009-08-21 05:52:31.000000000 -0700 ++++ mythtv-0.21-21399-new/libs/libavformat/mpegts.h 2009-08-31 07:25:58.000000000 -0700 +@@ -55,6 +55,7 @@ + #define STREAM_TYPE_DSMCC_B 0x0b + #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 + +diff -Naur mythtv-0.21-21399-old/libs/libmythtv/mpeg/mpegtables.cpp mythtv-0.21-21399-new/libs/libmythtv/mpeg/mpegtables.cpp +--- mythtv-0.21-21399-old/libs/libmythtv/mpeg/mpegtables.cpp 2009-08-21 05:52:23.000000000 -0700 ++++ mythtv-0.21-21399-new/libs/libmythtv/mpeg/mpegtables.cpp 2009-08-31 07:25:58.000000000 -0700 +@@ -772,6 +772,8 @@ + return "audio-mp2-layer[1,2,3]"; // EIT, PMT + else if (StreamID::MPEG1Audio==streamID) + return "audio-mp1-layer[1,2,3]"; // EIT, PMT ++ else if (StreamID::MPEG2AudioAmd1==streamID) ++ return "audio-aac-latm"; // EIT, PMT + else if (StreamID::AACAudio==streamID) + return "audio-aac"; // EIT, PMT + else if (StreamID::DTSAudio==streamID) +diff -Naur mythtv-0.21-21399-old/libs/libmythtv/mpeg/mpegtables.h mythtv-0.21-21399-new/libs/libmythtv/mpeg/mpegtables.h +--- mythtv-0.21-21399-old/libs/libmythtv/mpeg/mpegtables.h 2009-08-21 05:52:23.000000000 -0700 ++++ mythtv-0.21-21399-new/libs/libmythtv/mpeg/mpegtables.h 2009-08-31 07:25:58.000000000 -0700 +@@ -155,6 +155,7 @@ + { + return ((StreamID::MPEG1Audio == type) || + (StreamID::MPEG2Audio == type) || ++ (StreamID::MPEG2AudioAmd1 == type) || + (StreamID::AACAudio == type) || + (StreamID::AC3Audio == type) || + (StreamID::DTSAudio == type)); ======================================= --- /trunk/gar-minimyth/html/minimyth/document-changelog.txt Sun Aug 30 10:33:29 2009 +++ /trunk/gar-minimyth/html/minimyth/document-changelog.txt Mon Aug 31 10:02:57 2009 @@ -1,14 +1,15 @@ MiniMyth Changelog -------------------------------------------------------------------------------- -Changes since 69 (2009-08-30): +Changes since 69 (2009-08-31): Current MythTV versions MythTV 0.20-softpad: version 0.20.2.softpad, release-0-20-fixes branch svn 16082 and softpad branch svn 11261 (updated). MythTV 0.20: version 0.20.2, release-0-20-fixes branch svn 16082 MythTV 0.21: version 0.21.0, release-0-21-fixes branch svn 21399 and - patch glvdpau20744. + LATM AAC (ticket 5487) and + VDPAU (patch glvdpau20744). MythTV trunk: version trunk.21596 trunk svn 21596. Modified init @@ -16,7 +17,10 @@ motherboard sensor information is handled by the asus_atk0110.ko in most cases. -Improved MythV slave backend support +Improved MythTV + - Added LATM AAC support to MythTV 0.21. + +Improved MythTV slave backend support - Added support for devices that use the cx25840 driver. Modified MythStream ======================================= --- /trunk/gar-minimyth/script/myth-0.21/mythtv/Makefile Mon Jun 29 09:16:25 2009 +++ /trunk/gar-minimyth/script/myth-0.21/mythtv/Makefile Mon Aug 31 10:02:57 2009 @@ -12,6 +12,7 @@ $(DISTNAME_SHORT)-fftw3f.patch \ $(DISTNAME_SHORT)-glvdpau20744.patch \ $(DISTNAME_SHORT)-ticket-4792.patch \ + $(DISTNAME_SHORT)-ticket-5487.patch \ $(DISTNAME_SHORT)-networkcontrol.patch \ $(DISTNAME_SHORT)-eject.patch \ $(DISTNAME_SHORT)-udevinfo.patch \ ======================================= --- /trunk/gar-minimyth/script/myth-0.21/mythtv/checksums Fri Aug 21 06:05:41 2009 +++ /trunk/gar-minimyth/script/myth-0.21/mythtv/checksums Mon Aug 31 10:02:57 2009 @@ -5,6 +5,7 @@ 036fd82cbc445ba56e623c786a0387d6 download/mythtv-0.21-fftw3f.patch 8f3c9111e07295ecb116e28d190bd75e download/mythtv-0.21-glvdpau20744.patch cfd7edcfffa8c4785cf1a6b339afff3a download/mythtv-0.21-ticket-4792.patch +a05fd3330ff79fa2609cb27f1c250ec6 download/mythtv-0.21-ticket-5487.patch 3252635ae2e0db0f849ae5375eee9165 download/mythtv-0.21-networkcontrol.patch 63f81f67384fb60c5e2cb87939b68794 download/mythtv-0.21-eject.patch 237ce129388989dc7676a591d6e6cf77 download/mythtv-0.21-udevinfo.patch --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "minimyth-commits" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [email protected] For more options, visit this group at http://groups.google.com/group/minimyth-commits?hl=en -~----------~----~----~----~------~----~------~--~---
