PageRenderTime 26ms CodeModel.GetById 10ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 0ms

/libavformat/ac3dec.c

http://github.com/FFmpeg/FFmpeg
C | 139 lines | 107 code | 10 blank | 22 comment | 41 complexity | 8a905af60529dfed6d791015fbb88636 MD5 | raw file
  1/*
  2 * RAW AC-3 and E-AC-3 demuxer
  3 * Copyright (c) 2007 Justin Ruggles <justin.ruggles@gmail.com>
  4 *
  5 * This file is part of FFmpeg.
  6 *
  7 * FFmpeg is free software; you can redistribute it and/or
  8 * modify it under the terms of the GNU Lesser General Public
  9 * License as published by the Free Software Foundation; either
 10 * version 2.1 of the License, or (at your option) any later version.
 11 *
 12 * FFmpeg is distributed in the hope that it will be useful,
 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 15 * Lesser General Public License for more details.
 16 *
 17 * You should have received a copy of the GNU Lesser General Public
 18 * License along with FFmpeg; if not, write to the Free Software
 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 20 */
 21
 22#include "libavutil/avassert.h"
 23#include "libavutil/crc.h"
 24#include "libavcodec/ac3_parser.h"
 25#include "avformat.h"
 26#include "rawdec.h"
 27
 28static int ac3_eac3_probe(const AVProbeData *p, enum AVCodecID expected_codec_id)
 29{
 30    int max_frames, first_frames = 0, frames;
 31    const uint8_t *buf, *buf2, *end;
 32    enum AVCodecID codec_id = AV_CODEC_ID_AC3;
 33
 34    max_frames = 0;
 35    buf = p->buf;
 36    end = buf + p->buf_size;
 37
 38    for(; buf < end; buf++) {
 39        if(buf > p->buf && !(buf[0] == 0x0B && buf[1] == 0x77)
 40                        && !(buf[0] == 0x77 && buf[1] == 0x0B) )
 41            continue;
 42        buf2 = buf;
 43
 44        for(frames = 0; buf2 < end; frames++) {
 45            uint8_t buf3[4096];
 46            uint8_t bitstream_id;
 47            uint16_t frame_size;
 48            int i, ret;
 49
 50            if(!memcmp(buf2, "\x1\x10", 2)) {
 51                if (buf2 + 16 > end)
 52                    break;
 53                buf2+=16;
 54            }
 55            if (buf[0] == 0x77 && buf[1] == 0x0B) {
 56                for(i=0; i<8; i+=2) {
 57                    buf3[i  ] = buf2[i+1];
 58                    buf3[i+1] = buf2[i  ];
 59                }
 60                ret = av_ac3_parse_header(buf3, 8, &bitstream_id,
 61                                          &frame_size);
 62            }else
 63                ret = av_ac3_parse_header(buf2, end - buf2, &bitstream_id,
 64                                          &frame_size);
 65            if (ret < 0)
 66                break;
 67            if(buf2 + frame_size > end)
 68                break;
 69            if (buf[0] == 0x77 && buf[1] == 0x0B) {
 70                av_assert0(frame_size <= sizeof(buf3));
 71                for(i = 8; i < frame_size; i += 2) {
 72                    buf3[i  ] = buf2[i+1];
 73                    buf3[i+1] = buf2[i  ];
 74                }
 75                if (av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, buf3 + 2, frame_size - 2))
 76                    break;
 77            } else {
 78                if (av_crc(av_crc_get_table(AV_CRC_16_ANSI), 0, buf2 + 2, frame_size - 2))
 79                    break;
 80            }
 81            if (bitstream_id > 10)
 82                codec_id = AV_CODEC_ID_EAC3;
 83            buf2 += frame_size;
 84        }
 85        max_frames = FFMAX(max_frames, frames);
 86        if(buf == p->buf)
 87            first_frames = frames;
 88    }
 89    if(codec_id != expected_codec_id) return 0;
 90    // keep this in sync with mp3 probe, both need to avoid
 91    // issues with MPEG-files!
 92    if   (first_frames>=7) return AVPROBE_SCORE_EXTENSION + 1;
 93    else if(max_frames>200)return AVPROBE_SCORE_EXTENSION;
 94    else if(max_frames>=4) return AVPROBE_SCORE_EXTENSION/2;
 95    else if(max_frames>=1) return 1;
 96    else                   return 0;
 97}
 98
 99#if CONFIG_AC3_DEMUXER
100static int ac3_probe(const AVProbeData *p)
101{
102    return ac3_eac3_probe(p, AV_CODEC_ID_AC3);
103}
104
105FF_RAW_DEMUXER_CLASS(ac3)
106AVInputFormat ff_ac3_demuxer = {
107    .name           = "ac3",
108    .long_name      = NULL_IF_CONFIG_SMALL("raw AC-3"),
109    .read_probe     = ac3_probe,
110    .read_header    = ff_raw_audio_read_header,
111    .read_packet    = ff_raw_read_partial_packet,
112    .flags= AVFMT_GENERIC_INDEX,
113    .extensions = "ac3",
114    .raw_codec_id   = AV_CODEC_ID_AC3,
115    .priv_data_size = sizeof(FFRawDemuxerContext),
116    .priv_class     = &ac3_demuxer_class,
117};
118#endif
119
120#if CONFIG_EAC3_DEMUXER
121static int eac3_probe(const AVProbeData *p)
122{
123    return ac3_eac3_probe(p, AV_CODEC_ID_EAC3);
124}
125
126FF_RAW_DEMUXER_CLASS(eac3)
127AVInputFormat ff_eac3_demuxer = {
128    .name           = "eac3",
129    .long_name      = NULL_IF_CONFIG_SMALL("raw E-AC-3"),
130    .read_probe     = eac3_probe,
131    .read_header    = ff_raw_audio_read_header,
132    .read_packet    = ff_raw_read_partial_packet,
133    .flags          = AVFMT_GENERIC_INDEX,
134    .extensions     = "eac3",
135    .raw_codec_id   = AV_CODEC_ID_EAC3,
136    .priv_data_size = sizeof(FFRawDemuxerContext),
137    .priv_class     = &eac3_demuxer_class,
138};
139#endif