| @@ -109,7 +109,8 @@ OBJS-$(CONFIG_CLJR_ENCODER) += cljr.o | |||
| OBJS-$(CONFIG_COOK_DECODER) += cook.o | |||
| OBJS-$(CONFIG_CSCD_DECODER) += cscd.o | |||
| OBJS-$(CONFIG_CYUV_DECODER) += cyuv.o | |||
| OBJS-$(CONFIG_DCA_DECODER) += dca.o synth_filter.o dcadsp.o | |||
| OBJS-$(CONFIG_DCA_DECODER) += dca.o synth_filter.o dcadsp.o \ | |||
| dca_parser.o | |||
| OBJS-$(CONFIG_DFA_DECODER) += dfa.o | |||
| OBJS-$(CONFIG_DNXHD_DECODER) += dnxhddec.o dnxhddata.o | |||
| OBJS-$(CONFIG_DNXHD_ENCODER) += dnxhdenc.o dnxhddata.o \ | |||
| @@ -38,6 +38,7 @@ | |||
| #include "dcadata.h" | |||
| #include "dcahuff.h" | |||
| #include "dca.h" | |||
| #include "dca_parser.h" | |||
| #include "synth_filter.h" | |||
| #include "dcadsp.h" | |||
| #include "fmtconvert.h" | |||
| @@ -1360,47 +1361,6 @@ static int dca_decode_block(DCAContext *s, int base_channel, int block_index) | |||
| return 0; | |||
| } | |||
| /** | |||
| * Convert bitstream to one representation based on sync marker | |||
| */ | |||
| static int dca_convert_bitstream(const uint8_t *src, int src_size, uint8_t *dst, | |||
| int max_size) | |||
| { | |||
| uint32_t mrk; | |||
| int i, tmp; | |||
| const uint16_t *ssrc = (const uint16_t *) src; | |||
| uint16_t *sdst = (uint16_t *) dst; | |||
| PutBitContext pb; | |||
| if ((unsigned) src_size > (unsigned) max_size) { | |||
| // av_log(NULL, AV_LOG_ERROR, "Input frame size larger than DCA_MAX_FRAME_SIZE!\n"); | |||
| // return -1; | |||
| src_size = max_size; | |||
| } | |||
| mrk = AV_RB32(src); | |||
| switch (mrk) { | |||
| case DCA_MARKER_RAW_BE: | |||
| memcpy(dst, src, src_size); | |||
| return src_size; | |||
| case DCA_MARKER_RAW_LE: | |||
| for (i = 0; i < (src_size + 1) >> 1; i++) | |||
| *sdst++ = av_bswap16(*ssrc++); | |||
| return src_size; | |||
| case DCA_MARKER_14B_BE: | |||
| case DCA_MARKER_14B_LE: | |||
| init_put_bits(&pb, dst, max_size); | |||
| for (i = 0; i < (src_size + 1) >> 1; i++, src += 2) { | |||
| tmp = ((mrk == DCA_MARKER_14B_BE) ? AV_RB16(src) : AV_RL16(src)) & 0x3FFF; | |||
| put_bits(&pb, 14, tmp); | |||
| } | |||
| flush_put_bits(&pb); | |||
| return (put_bits_count(&pb) + 7) >> 3; | |||
| default: | |||
| return AVERROR_INVALIDDATA; | |||
| } | |||
| } | |||
| /** | |||
| * Return the number of channels in an ExSS speaker mask (HD) | |||
| */ | |||
| @@ -1688,8 +1648,8 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, | |||
| s->xch_present = 0; | |||
| s->dca_buffer_size = dca_convert_bitstream(buf, buf_size, s->dca_buffer, | |||
| DCA_MAX_FRAME_SIZE + DCA_MAX_EXSS_HEADER_SIZE); | |||
| s->dca_buffer_size = ff_dca_convert_bitstream(buf, buf_size, s->dca_buffer, | |||
| DCA_MAX_FRAME_SIZE + DCA_MAX_EXSS_HEADER_SIZE); | |||
| if (s->dca_buffer_size == AVERROR_INVALIDDATA) { | |||
| av_log(avctx, AV_LOG_ERROR, "Not a valid DCA frame\n"); | |||
| return AVERROR_INVALIDDATA; | |||
| @@ -1703,7 +1663,6 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, | |||
| //set AVCodec values with parsed data | |||
| avctx->sample_rate = s->sample_rate; | |||
| avctx->bit_rate = s->bit_rate; | |||
| avctx->frame_size = s->sample_blocks * 32; | |||
| s->profile = FF_PROFILE_DTS; | |||
| @@ -24,6 +24,10 @@ | |||
| #include "parser.h" | |||
| #include "dca.h" | |||
| #include "dcadata.h" | |||
| #include "dca_parser.h" | |||
| #include "get_bits.h" | |||
| #include "put_bits.h" | |||
| typedef struct DCAParseContext { | |||
| ParseContext pc; | |||
| @@ -100,6 +104,71 @@ static av_cold int dca_parse_init(AVCodecParserContext * s) | |||
| return 0; | |||
| } | |||
| int ff_dca_convert_bitstream(const uint8_t *src, int src_size, uint8_t *dst, | |||
| int max_size) | |||
| { | |||
| uint32_t mrk; | |||
| int i, tmp; | |||
| const uint16_t *ssrc = (const uint16_t *) src; | |||
| uint16_t *sdst = (uint16_t *) dst; | |||
| PutBitContext pb; | |||
| if ((unsigned) src_size > (unsigned) max_size) | |||
| src_size = max_size; | |||
| mrk = AV_RB32(src); | |||
| switch (mrk) { | |||
| case DCA_MARKER_RAW_BE: | |||
| memcpy(dst, src, src_size); | |||
| return src_size; | |||
| case DCA_MARKER_RAW_LE: | |||
| for (i = 0; i < (src_size + 1) >> 1; i++) | |||
| *sdst++ = av_bswap16(*ssrc++); | |||
| return src_size; | |||
| case DCA_MARKER_14B_BE: | |||
| case DCA_MARKER_14B_LE: | |||
| init_put_bits(&pb, dst, max_size); | |||
| for (i = 0; i < (src_size + 1) >> 1; i++, src += 2) { | |||
| tmp = ((mrk == DCA_MARKER_14B_BE) ? AV_RB16(src) : AV_RL16(src)) & 0x3FFF; | |||
| put_bits(&pb, 14, tmp); | |||
| } | |||
| flush_put_bits(&pb); | |||
| return (put_bits_count(&pb) + 7) >> 3; | |||
| default: | |||
| return AVERROR_INVALIDDATA; | |||
| } | |||
| } | |||
| static int dca_parse_params(const uint8_t *buf, int buf_size, int *duration, | |||
| int *sample_rate) | |||
| { | |||
| GetBitContext gb; | |||
| uint8_t hdr[12 + FF_INPUT_BUFFER_PADDING_SIZE] = { 0 }; | |||
| int ret, sample_blocks, sr_code; | |||
| if (buf_size < 12) | |||
| return AVERROR_INVALIDDATA; | |||
| if ((ret = ff_dca_convert_bitstream(buf, 12, hdr, 12)) < 0) | |||
| return ret; | |||
| init_get_bits(&gb, hdr, 96); | |||
| skip_bits_long(&gb, 39); | |||
| sample_blocks = get_bits(&gb, 7) + 1; | |||
| if (sample_blocks < 8) | |||
| return AVERROR_INVALIDDATA; | |||
| *duration = 256 * (sample_blocks / 8); | |||
| skip_bits(&gb, 20); | |||
| sr_code = get_bits(&gb, 4); | |||
| *sample_rate = dca_sample_rates[sr_code]; | |||
| if (*sample_rate == 0) | |||
| return AVERROR_INVALIDDATA; | |||
| return 0; | |||
| } | |||
| static int dca_parse(AVCodecParserContext * s, | |||
| AVCodecContext * avctx, | |||
| const uint8_t ** poutbuf, int *poutbuf_size, | |||
| @@ -107,7 +176,7 @@ static int dca_parse(AVCodecParserContext * s, | |||
| { | |||
| DCAParseContext *pc1 = s->priv_data; | |||
| ParseContext *pc = &pc1->pc; | |||
| int next; | |||
| int next, duration, sample_rate; | |||
| if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { | |||
| next = buf_size; | |||
| @@ -120,6 +189,15 @@ static int dca_parse(AVCodecParserContext * s, | |||
| return buf_size; | |||
| } | |||
| } | |||
| /* read the duration and sample rate from the frame header */ | |||
| if (!dca_parse_params(buf, buf_size, &duration, &sample_rate)) { | |||
| s->duration = duration; | |||
| if (!avctx->sample_rate) | |||
| avctx->sample_rate = sample_rate; | |||
| } else | |||
| s->duration = 0; | |||
| *poutbuf = buf; | |||
| *poutbuf_size = buf_size; | |||
| return next; | |||
| @@ -0,0 +1,36 @@ | |||
| /* | |||
| * DCA parser | |||
| * Copyright (C) 2004 Gildas Bazin | |||
| * Copyright (C) 2004 Benjamin Zores | |||
| * Copyright (C) 2006 Benjamin Larsson | |||
| * Copyright (C) 2007 Konstantin Shishkov | |||
| * | |||
| * 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 | |||
| */ | |||
| #ifndef AVCODEC_DCA_PARSER_H | |||
| #define AVCODEC_DCA_PARSER_H | |||
| #include <stdint.h> | |||
| /** | |||
| * Convert bitstream to one representation based on sync marker | |||
| */ | |||
| int ff_dca_convert_bitstream(const uint8_t *src, int src_size, uint8_t *dst, | |||
| int max_size); | |||
| #endif /* AVCODEC_DCA_PARSER_H */ | |||