"Fossies" - the Fresh Open Source Software Archive

Member "ffmpeg-3.4.2/libavformat/aacdec.c" (12 Feb 2018, 4732 Bytes) of package /linux/misc/ffmpeg-3.4.2.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "aacdec.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 3.4_vs_3.4.1.

    1 /*
    2  * raw ADTS AAC demuxer
    3  * Copyright (c) 2008 Michael Niedermayer <michaelni@gmx.at>
    4  * Copyright (c) 2009 Robert Swain ( rob opendot cl )
    5  *
    6  * This file is part of FFmpeg.
    7  *
    8  * FFmpeg is free software; you can redistribute it and/or
    9  * modify it under the terms of the GNU Lesser General Public
   10  * License as published by the Free Software Foundation; either
   11  * version 2.1 of the License, or (at your option) any later version.
   12  *
   13  * FFmpeg is distributed in the hope that it will be useful,
   14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   16  * Lesser General Public License for more details.
   17  *
   18  * You should have received a copy of the GNU Lesser General Public
   19  * License along with FFmpeg; if not, write to the Free Software
   20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
   21  */
   22 
   23 #include "libavutil/intreadwrite.h"
   24 #include "avformat.h"
   25 #include "internal.h"
   26 #include "id3v1.h"
   27 #include "apetag.h"
   28 
   29 #define ADTS_HEADER_SIZE 7
   30 
   31 static int adts_aac_probe(AVProbeData *p)
   32 {
   33     int max_frames = 0, first_frames = 0;
   34     int fsize, frames;
   35     const uint8_t *buf0 = p->buf;
   36     const uint8_t *buf2;
   37     const uint8_t *buf;
   38     const uint8_t *end = buf0 + p->buf_size - 7;
   39 
   40     buf = buf0;
   41 
   42     for (; buf < end; buf = buf2 + 1) {
   43         buf2 = buf;
   44 
   45         for (frames = 0; buf2 < end; frames++) {
   46             uint32_t header = AV_RB16(buf2);
   47             if ((header & 0xFFF6) != 0xFFF0) {
   48                 if (buf != buf0) {
   49                     // Found something that isn't an ADTS header, starting
   50                     // from a position other than the start of the buffer.
   51                     // Discard the count we've accumulated so far since it
   52                     // probably was a false positive.
   53                     frames = 0;
   54                 }
   55                 break;
   56             }
   57             fsize = (AV_RB32(buf2 + 3) >> 13) & 0x1FFF;
   58             if (fsize < 7)
   59                 break;
   60             fsize = FFMIN(fsize, end - buf2);
   61             buf2 += fsize;
   62         }
   63         max_frames = FFMAX(max_frames, frames);
   64         if (buf == buf0)
   65             first_frames = frames;
   66     }
   67 
   68     if (first_frames >= 3)
   69         return AVPROBE_SCORE_EXTENSION + 1;
   70     else if (max_frames > 100)
   71         return AVPROBE_SCORE_EXTENSION;
   72     else if (max_frames >= 3)
   73         return AVPROBE_SCORE_EXTENSION / 2;
   74     else if (first_frames >= 1)
   75         return 1;
   76     else
   77         return 0;
   78 }
   79 
   80 static int adts_aac_read_header(AVFormatContext *s)
   81 {
   82     AVStream *st;
   83     uint16_t state;
   84 
   85     st = avformat_new_stream(s, NULL);
   86     if (!st)
   87         return AVERROR(ENOMEM);
   88 
   89     st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
   90     st->codecpar->codec_id   = s->iformat->raw_codec_id;
   91     st->need_parsing         = AVSTREAM_PARSE_FULL_RAW;
   92 
   93     ff_id3v1_read(s);
   94     if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
   95         !av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX)) {
   96         int64_t cur = avio_tell(s->pb);
   97         ff_ape_parse_tag(s);
   98         avio_seek(s->pb, cur, SEEK_SET);
   99     }
  100 
  101     // skip data until the first ADTS frame is found
  102     state = avio_r8(s->pb);
  103     while (!avio_feof(s->pb) && avio_tell(s->pb) < s->probesize) {
  104         state = (state << 8) | avio_r8(s->pb);
  105         if ((state >> 4) != 0xFFF)
  106             continue;
  107         avio_seek(s->pb, -2, SEEK_CUR);
  108         break;
  109     }
  110     if ((state >> 4) != 0xFFF)
  111         return AVERROR_INVALIDDATA;
  112 
  113     // LCM of all possible ADTS sample rates
  114     avpriv_set_pts_info(st, 64, 1, 28224000);
  115 
  116     return 0;
  117 }
  118 
  119 static int adts_aac_read_packet(AVFormatContext *s, AVPacket *pkt)
  120 {
  121     int ret, fsize;
  122 
  123     ret = av_get_packet(s->pb, pkt, ADTS_HEADER_SIZE);
  124     if (ret < 0)
  125         return ret;
  126     if (ret < ADTS_HEADER_SIZE) {
  127         av_packet_unref(pkt);
  128         return AVERROR(EIO);
  129     }
  130 
  131     if ((AV_RB16(pkt->data) >> 4) != 0xfff) {
  132         av_packet_unref(pkt);
  133         return AVERROR_INVALIDDATA;
  134     }
  135 
  136     fsize = (AV_RB32(pkt->data + 3) >> 13) & 0x1FFF;
  137     if (fsize < ADTS_HEADER_SIZE) {
  138         av_packet_unref(pkt);
  139         return AVERROR_INVALIDDATA;
  140     }
  141 
  142     ret = av_append_packet(s->pb, pkt, fsize - ADTS_HEADER_SIZE);
  143     if (ret < 0)
  144         av_packet_unref(pkt);
  145 
  146     return ret;
  147 }
  148 
  149 AVInputFormat ff_aac_demuxer = {
  150     .name         = "aac",
  151     .long_name    = NULL_IF_CONFIG_SMALL("raw ADTS AAC (Advanced Audio Coding)"),
  152     .read_probe   = adts_aac_probe,
  153     .read_header  = adts_aac_read_header,
  154     .read_packet  = adts_aac_read_packet,
  155     .flags        = AVFMT_GENERIC_INDEX,
  156     .extensions   = "aac",
  157     .mime_type    = "audio/aac,audio/aacp,audio/x-aac",
  158     .raw_codec_id = AV_CODEC_ID_AAC,
  159 };