| @@ -3,6 +3,10 @@ · 2 unmodified lines |
| 3 | 3 | * Copyright (c) 2005-2006 Oded Shimon ( ods15 ods15 dyndns org ) |
| 4 | 4 | * Copyright (c) 2006-2007 Maxim Gavrilov ( maxim.gavrilov gmail com ) |
| 5 | 5 | * |
| 6 | + * AAC LATM decoder |
| 7 | + * Copyright (c) 2008-2010 Paul Kendall <paul@kcbbs.gen.nz> |
| 8 | + * Copyright (c) 2010 Janne Grunau <janne-ffmpeg@jannau.net> |
| 9 | + * |
| 6 | 10 | * This file is part of FFmpeg. |
| 7 | 11 | * |
| 8 | 12 | * FFmpeg is free software; you can redistribute it and/or |
| @@ -2098,6 +2102,261 @@ static av_cold int aac_decode_close(AVCodecContext *avctx) · 2089 unmodified lines |
| 2098 | 2102 | return 0; |
| 2099 | 2103 | } |
| 2100 | 2104 | |
| 2105 | + |
| 2106 | +#define LOAS_SYNC_WORD 0x2b7 ///< 11 bits LOAS sync word |
| 2107 | + |
| 2108 | +struct LATMContext { |
| 2109 | + AACContext aac_ctx; ///< containing AACContext |
| 2110 | + int initialized; ///< initilized after a valid extradata was seen |
| 2111 | + |
| 2112 | + // parser data |
| 2113 | + int audio_mux_version_A; ///< LATM syntax version |
| 2114 | + int frame_length_type; ///< 0/1 variable/fixed frame length |
| 2115 | + int frame_length; ///< frame length for fixed frame length |
| 2116 | +}; |
| 2117 | + |
| 2118 | +static inline uint32_t latm_get_value(GetBitContext *b) |
| 2119 | +{ |
| 2120 | + int length = get_bits(b, 2); |
| 2121 | + |
| 2122 | + return get_bits_long(b, (length+1)*8); |
| 2123 | +} |
| 2124 | + |
| 2125 | +static int latm_decode_audio_specific_config(struct LATMContext *latmctx, |
| 2126 | + GetBitContext *gb) |
| 2127 | +{ |
| 2128 | + AVCodecContext *avctx = latmctx->aac_ctx.avctx; |
| 2129 | + MPEG4AudioConfig m4ac; |
| 2130 | + int config_start_bit = get_bits_count(gb); |
| 2131 | + int bits_consumed, esize; |
| 2132 | + |
| 2133 | + if (config_start_bit % 8) { |
| 2134 | + av_log_missing_feature(latmctx->aac_ctx.avctx, "audio specific " |
| 2135 | + "config not byte aligned.\n", 1); |
| 2136 | + return AVERROR_INVALIDDATA; |
| 2137 | + } else { |
| 2138 | + bits_consumed = |
| 2139 | + decode_audio_specific_config(NULL, avctx, &m4ac, |
| 2140 | + gb->buffer + (config_start_bit / 8), |
| 2141 | + get_bits_left(gb) / 8); |
| 2142 | + |
| 2143 | + if (bits_consumed < 0) |
| 2144 | + return AVERROR_INVALIDDATA; |
| 2145 | + |
| 2146 | + esize = (bits_consumed+7) / 8; |
| 2147 | + |
| 2148 | + if (avctx->extradata_size <= esize) { |
| 2149 | + av_free(avctx->extradata); |
| 2150 | + avctx->extradata = av_malloc(esize + FF_INPUT_BUFFER_PADDING_SIZE); |
| 2151 | + if (!avctx->extradata) |
| 2152 | + return AVERROR(ENOMEM); |
| 2153 | + } |
| 2154 | + |
| 2155 | + avctx->extradata_size = esize; |
| 2156 | + memcpy(avctx->extradata, gb->buffer + (config_start_bit/8), esize); |
| 2157 | + memset(avctx->extradata+esize, 0, FF_INPUT_BUFFER_PADDING_SIZE); |
| 2158 | + } |
| 2159 | + |
| 2160 | + return bits_consumed; |
| 2161 | +} |
| 2162 | + |
| 2163 | +static int read_stream_mux_config(struct LATMContext *latmctx, |
| 2164 | + GetBitContext *gb) |
| 2165 | +{ |
| 2166 | + int ret, audio_mux_version = get_bits(gb, 1); |
| 2167 | + |
| 2168 | + latmctx->audio_mux_version_A = 0; |
| 2169 | + if (audio_mux_version) |
| 2170 | + latmctx->audio_mux_version_A = get_bits(gb, 1); |
| 2171 | + |
| 2172 | + if (!latmctx->audio_mux_version_A) { |
| 2173 | + |
| 2174 | + if (audio_mux_version) |
| 2175 | + latm_get_value(gb); // taraFullness |
| 2176 | + |
| 2177 | + skip_bits(gb, 1); // allStreamSameTimeFraming |
| 2178 | + skip_bits(gb, 6); // numSubFrames |
| 2179 | + // numPrograms |
| 2180 | + if (get_bits(gb, 4)) { // numPrograms |
| 2181 | + av_log_missing_feature(latmctx->aac_ctx.avctx, |
| 2182 | + "multiple programs are not supported\n", 1); |
| 2183 | + return AVERROR_PATCHWELCOME; |
| 2184 | + } |
| 2185 | + |
| 2186 | + // for each program (which there is only on in DVB) |
| 2187 | + |
| 2188 | + // for each layer (which there is only on in DVB) |
| 2189 | + if (get_bits(gb, 3)) { // numLayer |
| 2190 | + av_log_missing_feature(latmctx->aac_ctx.avctx, |
| 2191 | + "multiple layers are not supported\n", 1); |
| 2192 | + return AVERROR_PATCHWELCOME; |
| 2193 | + } |
| 2194 | + |
| 2195 | + // for all but first stream: use_same_config = get_bits(gb, 1); |
| 2196 | + if (!audio_mux_version) { |
| 2197 | + if ((ret = latm_decode_audio_specific_config(latmctx, gb)) < 0) |
| 2198 | + return ret; |
| 2199 | + } else { |
| 2200 | + int ascLen = latm_get_value(gb); |
| 2201 | + if ((ret = latm_decode_audio_specific_config(latmctx, gb)) < 0) |
| 2202 | + return ret; |
| 2203 | + ascLen -= ret; |
| 2204 | + skip_bits_long(gb, ascLen); |
| 2205 | + } |
| 2206 | + |
| 2207 | + latmctx->frame_length_type = get_bits(gb, 3); |
| 2208 | + switch (latmctx->frame_length_type) { |
| 2209 | + case 0: |
| 2210 | + skip_bits(gb, 8); // latmBufferFullness |
| 2211 | + break; |
| 2212 | + case 1: |
| 2213 | + latmctx->frame_length = get_bits(gb, 9); |
| 2214 | + break; |
| 2215 | + case 3: |
| 2216 | + case 4: |
| 2217 | + case 5: |
| 2218 | + skip_bits(gb, 6); // CELP frame length table index |
| 2219 | + break; |
| 2220 | + case 6: |
| 2221 | + case 7: |
| 2222 | + skip_bits(gb, 1); // HVXC frame length table index |
| 2223 | + break; |
| 2224 | + } |
| 2225 | + |
| 2226 | + if (get_bits(gb, 1)) { // other data |
| 2227 | + if (audio_mux_version) { |
| 2228 | + latm_get_value(gb); // other_data_bits |
| 2229 | + } else { |
| 2230 | + int esc; |
| 2231 | + do { |
| 2232 | + esc = get_bits(gb, 1); |
| 2233 | + skip_bits(gb, 8); |
| 2234 | + } while (esc); |
| 2235 | + } |
| 2236 | + } |
| 2237 | + |
| 2238 | + if (get_bits(gb, 1)) // crc present |
| 2239 | + skip_bits(gb, 8); // config_crc |
| 2240 | + } |
| 2241 | + |
| 2242 | + return 0; |
| 2243 | +} |
| 2244 | + |
| 2245 | +static int read_payload_length_info(struct LATMContext *ctx, GetBitContext *gb) |
| 2246 | +{ |
| 2247 | + uint8_t tmp; |
| 2248 | + |
| 2249 | + if (ctx->frame_length_type == 0) { |
| 2250 | + int mux_slot_length = 0; |
| 2251 | + do { |
| 2252 | + tmp = get_bits(gb, 8); |
| 2253 | + mux_slot_length += tmp; |
| 2254 | + } while (tmp == 255); |
| 2255 | + return mux_slot_length; |
| 2256 | + } else if (ctx->frame_length_type == 1) { |
| 2257 | + return ctx->frame_length; |
| 2258 | + } else if (ctx->frame_length_type == 3 || |
| 2259 | + ctx->frame_length_type == 5 || |
| 2260 | + ctx->frame_length_type == 7) { |
| 2261 | + skip_bits(gb, 2); // mux_slot_length_coded |
| 2262 | + } |
| 2263 | + return 0; |
| 2264 | +} |
| 2265 | + |
| 2266 | +static int read_audio_mux_element(struct LATMContext *latmctx, |
| 2267 | + GetBitContext *gb) |
| 2268 | +{ |
| 2269 | + int err; |
| 2270 | + uint8_t use_same_mux = get_bits(gb, 1); |
| 2271 | + if (!use_same_mux) { |
| 2272 | + if ((err = read_stream_mux_config(latmctx, gb)) < 0) |
| 2273 | + return err; |
| 2274 | + } else if (!latmctx->aac_ctx.avctx->extradata) { |
| 2275 | + av_log(latmctx->aac_ctx.avctx, AV_LOG_DEBUG, |
| 2276 | + "no decoder config found\n"); |
| 2277 | + return AVERROR(EAGAIN); |
| 2278 | + } |
| 2279 | + if (latmctx->audio_mux_version_A == 0) { |
| 2280 | + int mux_slot_length_bytes = read_payload_length_info(latmctx, gb); |
| 2281 | + if (mux_slot_length_bytes * 8 > get_bits_left(gb)) { |
| 2282 | + av_log(latmctx->aac_ctx.avctx, AV_LOG_ERROR, "incomplete frame\n"); |
| 2283 | + return AVERROR_INVALIDDATA; |
| 2284 | + } else if (mux_slot_length_bytes * 8 + 256 < get_bits_left(gb)) { |
| 2285 | + av_log(latmctx->aac_ctx.avctx, AV_LOG_ERROR, |
| 2286 | + "frame length mismatch %d << %d\n", |
| 2287 | + mux_slot_length_bytes * 8, get_bits_left(gb)); |
| 2288 | + return AVERROR_INVALIDDATA; |
| 2289 | + } |
| 2290 | + } |
| 2291 | + return 0; |
| 2292 | +} |
| 2293 | + |
| 2294 | + |
| 2295 | +static int latm_decode_frame(AVCodecContext *avctx, void *out, int *out_size, |
| 2296 | + AVPacket *avpkt) |
| 2297 | +{ |
| 2298 | + struct LATMContext *latmctx = avctx->priv_data; |
| 2299 | + int muxlength, err; |
| 2300 | + GetBitContext gb; |
| 2301 | + |
| 2302 | + if (avpkt->size == 0) |
| 2303 | + return 0; |
| 2304 | + |
| 2305 | + init_get_bits(&gb, avpkt->data, avpkt->size * 8); |
| 2306 | + |
| 2307 | + // check for LOAS sync word |
| 2308 | + if (get_bits(&gb, 11) != LOAS_SYNC_WORD) |
| 2309 | + return AVERROR_INVALIDDATA; |
| 2310 | + |
| 2311 | + muxlength = get_bits(&gb, 13); |
| 2312 | + // not enough data, the parser should have sorted this |
| 2313 | + if (muxlength+3 > avpkt->size) |
| 2314 | + return AVERROR_INVALIDDATA; |
| 2315 | + |
| 2316 | + if ((err = read_audio_mux_element(latmctx, &gb)) < 0) |
| 2317 | + return err; |
| 2318 | + |
| 2319 | + if (!latmctx->initialized) { |
| 2320 | + if (!avctx->extradata) { |
| 2321 | + *out_size = 0; |
| 2322 | + return avpkt->size; |
| 2323 | + } else { |
| 2324 | + if ((err = aac_decode_init(avctx)) < 0) |
| 2325 | + return err; |
| 2326 | + latmctx->initialized = 1; |
| 2327 | + } |
| 2328 | + } |
| 2329 | + |
| 2330 | + if (show_bits(&gb, 12) == 0xfff) { |
| 2331 | + av_log(latmctx->aac_ctx.avctx, AV_LOG_ERROR, |
| 2332 | + "ADTS header detected, probably as result of configuration " |
| 2333 | + "misparsing\n"); |
| 2334 | + return AVERROR_INVALIDDATA; |
| 2335 | + } |
| 2336 | + |
| 2337 | + if ((err = aac_decode_frame_int(avctx, out, out_size, &gb)) < 0) |
| 2338 | + return err; |
| 2339 | + |
| 2340 | + return muxlength; |
| 2341 | +} |
| 2342 | + |
| 2343 | +av_cold static int latm_decode_init(AVCodecContext *avctx) |
| 2344 | +{ |
| 2345 | + struct LATMContext *latmctx = avctx->priv_data; |
| 2346 | + int ret; |
| 2347 | + |
| 2348 | + ret = aac_decode_init(avctx); |
| 2349 | + |
| 2350 | + if (avctx->extradata_size > 0) { |
| 2351 | + latmctx->initialized = !ret; |
| 2352 | + } else { |
| 2353 | + latmctx->initialized = 0; |
| 2354 | + } |
| 2355 | + |
| 2356 | + return ret; |
| 2357 | +} |
| 2358 | + |
| 2359 | + |
| 2101 | 2360 | AVCodec aac_decoder = { |
| 2102 | 2361 | "aac", |
| 2103 | 2362 | AVMEDIA_TYPE_AUDIO, |
| @@ -2113,3 +2372,23 @@ AVCodec aac_decoder = { · 9 unmodified lines |
| 2113 | 2372 | }, |
| 2114 | 2373 | .channel_layouts = aac_channel_layout, |
| 2115 | 2374 | }; |
| 2375 | + |
| 2376 | +/* |
| 2377 | + Note: This decoder filter is intended to decode LATM streams transferred |
| 2378 | + in MPEG transport streams which only contain one program. |
| 2379 | + To do a more complex LATM demuxing a separate LATM demuxer should be used. |
| 2380 | +*/ |
| 2381 | +AVCodec aac_latm_decoder = { |
| 2382 | + .name = "aac_latm", |
| 2383 | + .type = CODEC_TYPE_AUDIO, |
| 2384 | + .id = CODEC_ID_AAC_LATM, |
| 2385 | + .priv_data_size = sizeof(struct LATMContext), |
| 2386 | + .init = latm_decode_init, |
| 2387 | + .close = aac_decode_close, |
| 2388 | + .decode = latm_decode_frame, |
| 2389 | + .long_name = NULL_IF_CONFIG_SMALL("AAC LATM (Advanced Audio Codec LATM syntax)"), |
| 2390 | + .sample_fmts = (const enum SampleFormat[]) { |
| 2391 | + SAMPLE_FMT_S16,SAMPLE_FMT_NONE |
| 2392 | + }, |
| 2393 | + .channel_layouts = aac_channel_layout, |
| 2394 | +}; |