| @@ -109,7 +109,8 @@ OBJS-$(CONFIG_CLJR_ENCODER) += cljr.o | |||||
| OBJS-$(CONFIG_COOK_DECODER) += cook.o | OBJS-$(CONFIG_COOK_DECODER) += cook.o | ||||
| OBJS-$(CONFIG_CSCD_DECODER) += cscd.o | OBJS-$(CONFIG_CSCD_DECODER) += cscd.o | ||||
| OBJS-$(CONFIG_CYUV_DECODER) += cyuv.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_DFA_DECODER) += dfa.o | ||||
| OBJS-$(CONFIG_DNXHD_DECODER) += dnxhddec.o dnxhddata.o | OBJS-$(CONFIG_DNXHD_DECODER) += dnxhddec.o dnxhddata.o | ||||
| OBJS-$(CONFIG_DNXHD_ENCODER) += dnxhdenc.o dnxhddata.o \ | OBJS-$(CONFIG_DNXHD_ENCODER) += dnxhdenc.o dnxhddata.o \ | ||||
| @@ -38,6 +38,7 @@ | |||||
| #include "dcadata.h" | #include "dcadata.h" | ||||
| #include "dcahuff.h" | #include "dcahuff.h" | ||||
| #include "dca.h" | #include "dca.h" | ||||
| #include "dca_parser.h" | |||||
| #include "synth_filter.h" | #include "synth_filter.h" | ||||
| #include "dcadsp.h" | #include "dcadsp.h" | ||||
| #include "fmtconvert.h" | #include "fmtconvert.h" | ||||
| @@ -1360,47 +1361,6 @@ static int dca_decode_block(DCAContext *s, int base_channel, int block_index) | |||||
| return 0; | 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) | * 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->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) { | if (s->dca_buffer_size == AVERROR_INVALIDDATA) { | ||||
| av_log(avctx, AV_LOG_ERROR, "Not a valid DCA frame\n"); | av_log(avctx, AV_LOG_ERROR, "Not a valid DCA frame\n"); | ||||
| return AVERROR_INVALIDDATA; | return AVERROR_INVALIDDATA; | ||||
| @@ -1703,7 +1663,6 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, | |||||
| //set AVCodec values with parsed data | //set AVCodec values with parsed data | ||||
| avctx->sample_rate = s->sample_rate; | avctx->sample_rate = s->sample_rate; | ||||
| avctx->bit_rate = s->bit_rate; | avctx->bit_rate = s->bit_rate; | ||||
| avctx->frame_size = s->sample_blocks * 32; | |||||
| s->profile = FF_PROFILE_DTS; | s->profile = FF_PROFILE_DTS; | ||||
| @@ -24,6 +24,10 @@ | |||||
| #include "parser.h" | #include "parser.h" | ||||
| #include "dca.h" | #include "dca.h" | ||||
| #include "dcadata.h" | |||||
| #include "dca_parser.h" | |||||
| #include "get_bits.h" | |||||
| #include "put_bits.h" | |||||
| typedef struct DCAParseContext { | typedef struct DCAParseContext { | ||||
| ParseContext pc; | ParseContext pc; | ||||
| @@ -100,6 +104,71 @@ static av_cold int dca_parse_init(AVCodecParserContext * s) | |||||
| return 0; | 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, | static int dca_parse(AVCodecParserContext * s, | ||||
| AVCodecContext * avctx, | AVCodecContext * avctx, | ||||
| const uint8_t ** poutbuf, int *poutbuf_size, | const uint8_t ** poutbuf, int *poutbuf_size, | ||||
| @@ -107,7 +176,7 @@ static int dca_parse(AVCodecParserContext * s, | |||||
| { | { | ||||
| DCAParseContext *pc1 = s->priv_data; | DCAParseContext *pc1 = s->priv_data; | ||||
| ParseContext *pc = &pc1->pc; | ParseContext *pc = &pc1->pc; | ||||
| int next; | |||||
| int next, duration, sample_rate; | |||||
| if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { | if (s->flags & PARSER_FLAG_COMPLETE_FRAMES) { | ||||
| next = buf_size; | next = buf_size; | ||||
| @@ -120,6 +189,15 @@ static int dca_parse(AVCodecParserContext * s, | |||||
| return buf_size; | 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 = buf; | ||||
| *poutbuf_size = buf_size; | *poutbuf_size = buf_size; | ||||
| return next; | 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 */ | |||||