⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 demux.c

📁 alac decoder,内容详细
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * ALAC (Apple Lossless Audio Codec) decoder * Copyright (c) 2005 David Hammerton * All rights reserved. * * This is the quicktime container demuxer. * * http://crazney.net/programs/itunes/alac.html *  * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. * */#include <string.h>#include <stdio.h>#include <stdint.h>#include <stdlib.h>#include "stream.h"#include "demux.h"typedef struct{    stream_t *stream;    demux_res_t *res;    long saved_mdat_pos;} qtmovie_t;/* chunk handlers */static void read_chunk_ftyp(qtmovie_t *qtmovie, size_t chunk_len){    fourcc_t type;    uint32_t minor_ver;    size_t size_remaining = chunk_len - 8; /* FIXME: can't hardcode 8, size may be 64bit */    type = stream_read_uint32(qtmovie->stream);    size_remaining-=4;    if (type != MAKEFOURCC('M','4','A',' '))    {        fprintf(stderr, "not M4A file\n");        return;    }    minor_ver = stream_read_uint32(qtmovie->stream);    size_remaining-=4;    /* compatible brands */    while (size_remaining)    {        /* unused */        /*fourcc_t cbrand =*/ stream_read_uint32(qtmovie->stream);        size_remaining-=4;    }}static void read_chunk_tkhd(qtmovie_t *qtmovie, size_t chunk_len){    /* don't need anything from here atm, skip */    size_t size_remaining = chunk_len - 8; /* FIXME WRONG */    stream_skip(qtmovie->stream, size_remaining);}static void read_chunk_mdhd(qtmovie_t *qtmovie, size_t chunk_len){    /* don't need anything from here atm, skip */    size_t size_remaining = chunk_len - 8; /* FIXME WRONG */    stream_skip(qtmovie->stream, size_remaining);}static void read_chunk_edts(qtmovie_t *qtmovie, size_t chunk_len){    /* don't need anything from here atm, skip */    size_t size_remaining = chunk_len - 8; /* FIXME WRONG */    stream_skip(qtmovie->stream, size_remaining);}static void read_chunk_elst(qtmovie_t *qtmovie, size_t chunk_len){    /* don't need anything from here atm, skip */    size_t size_remaining = chunk_len - 8; /* FIXME WRONG */    stream_skip(qtmovie->stream, size_remaining);}/* media handler inside mdia */static void read_chunk_hdlr(qtmovie_t *qtmovie, size_t chunk_len){    fourcc_t comptype, compsubtype;    size_t size_remaining = chunk_len - 8; /* FIXME WRONG */    int strlen;    char str[256] = {0};    /* version */    stream_read_uint8(qtmovie->stream);    size_remaining -= 1;    /* flags */    stream_read_uint8(qtmovie->stream);    stream_read_uint8(qtmovie->stream);    stream_read_uint8(qtmovie->stream);    size_remaining -= 3;    /* component type */    comptype = stream_read_uint32(qtmovie->stream);    compsubtype = stream_read_uint32(qtmovie->stream);    size_remaining -= 8;    /* component manufacturer */    stream_read_uint32(qtmovie->stream);    size_remaining -= 4;    /* flags */    stream_read_uint32(qtmovie->stream);    stream_read_uint32(qtmovie->stream);    size_remaining -= 8;    /* name */    strlen = stream_read_uint8(qtmovie->stream);    stream_read(qtmovie->stream, strlen, str);    size_remaining -= 1 + strlen;    if (size_remaining)    {        stream_skip(qtmovie->stream, size_remaining);    }}static int read_chunk_stsd(qtmovie_t *qtmovie, size_t chunk_len){    unsigned int i;    uint32_t numentries;    size_t size_remaining = chunk_len - 8; /* FIXME WRONG */    /* version */    stream_read_uint8(qtmovie->stream);    size_remaining -= 1;    /* flags */    stream_read_uint8(qtmovie->stream);    stream_read_uint8(qtmovie->stream);    stream_read_uint8(qtmovie->stream);    size_remaining -= 3;    numentries = stream_read_uint32(qtmovie->stream);    size_remaining -= 4;    if (numentries != 1)    {        fprintf(stderr, "only expecting one entry in sample description atom!\n");        return 0;    }    for (i = 0; i < numentries; i++)    {        uint32_t entry_size;        uint16_t version;        uint32_t entry_remaining;        entry_size = stream_read_uint32(qtmovie->stream);        qtmovie->res->format = stream_read_uint32(qtmovie->stream);        entry_remaining = entry_size;        entry_remaining -= 8;        /* sound info: */        stream_skip(qtmovie->stream, 6); /* reserved */        entry_remaining -= 6;        version = stream_read_uint16(qtmovie->stream);        if (version != 1)            fprintf(stderr, "unknown version??\n");        entry_remaining -= 2;        /* revision level */        stream_read_uint16(qtmovie->stream);        /* vendor */        stream_read_uint32(qtmovie->stream);        entry_remaining -= 6;        /* EH?? spec doesn't say theres an extra 16 bits here.. but there is! */        stream_read_uint16(qtmovie->stream);        entry_remaining -= 2;        qtmovie->res->num_channels = stream_read_uint16(qtmovie->stream);        qtmovie->res->sample_size = stream_read_uint16(qtmovie->stream);        entry_remaining -= 4;        /* compression id */        stream_read_uint16(qtmovie->stream);        /* packet size */        stream_read_uint16(qtmovie->stream);        entry_remaining -= 4;        /* sample rate - 32bit fixed point = 16bit?? */        qtmovie->res->sample_rate = stream_read_uint16(qtmovie->stream);        entry_remaining -= 2;        /* skip 2 */        stream_skip(qtmovie->stream, 2);        entry_remaining -= 2;        /* remaining is codec data */#if 0        qtmovie->res->codecdata_len = stream_read_uint32(qtmovie->stream);        if (qtmovie->res->codecdata_len != entry_remaining)            fprintf(stderr, "perhaps not? %i vs %i\n",                    qtmovie->res->codecdata_len, entry_remaining);        entry_remaining -= 4;        stream_read_uint32(qtmovie->stream); /* 'alac' */        entry_remaining -= 4;        qtmovie->res->codecdata = malloc(qtmovie->res->codecdata_len - 8);        stream_read(qtmovie->stream,                entry_remaining,                qtmovie->res->codecdata);        entry_remaining = 0;#else        /* 12 = audio format atom, 8 = padding */        qtmovie->res->codecdata_len = entry_remaining + 12 + 8;        qtmovie->res->codecdata = malloc(qtmovie->res->codecdata_len);        memset(qtmovie->res->codecdata, 0, qtmovie->res->codecdata_len);        /* audio format atom */        ((unsigned int*)qtmovie->res->codecdata)[0] = 0x0c000000;        ((unsigned int*)qtmovie->res->codecdata)[1] = MAKEFOURCC('a','m','r','f');        ((unsigned int*)qtmovie->res->codecdata)[2] = MAKEFOURCC('c','a','l','a');        stream_read(qtmovie->stream,                entry_remaining,                ((char*)qtmovie->res->codecdata) + 12);        entry_remaining -= entry_remaining;#endif        if (entry_remaining)            stream_skip(qtmovie->stream, entry_remaining);        qtmovie->res->format_read = 1;        if (qtmovie->res->format != MAKEFOURCC('a','l','a','c'))        {            /*fprintf(stderr, "expecting 'alac' data format, got %c%c%c%c\n",                    SPLITFOURCC(qtmovie->res->format));*/            return 0;        }    }    return 1;}static void read_chunk_stts(qtmovie_t *qtmovie, size_t chunk_len){    unsigned int i;    uint32_t numentries;    size_t size_remaining = chunk_len - 8; /* FIXME WRONG */    /* version */    stream_read_uint8(qtmovie->stream);    size_remaining -= 1;    /* flags */    stream_read_uint8(qtmovie->stream);    stream_read_uint8(qtmovie->stream);    stream_read_uint8(qtmovie->stream);    size_remaining -= 3;    numentries = stream_read_uint32(qtmovie->stream);    size_remaining -= 4;    qtmovie->res->num_time_to_samples = numentries;    qtmovie->res->time_to_sample = malloc(numentries * sizeof(*qtmovie->res->time_to_sample));    for (i = 0; i < numentries; i++)    {        qtmovie->res->time_to_sample[i].sample_count = stream_read_uint32(qtmovie->stream);        qtmovie->res->time_to_sample[i].sample_duration = stream_read_uint32(qtmovie->stream);        size_remaining -= 8;    }    if (size_remaining)    {        fprintf(stderr, "ehm, size remianing?\n");        stream_skip(qtmovie->stream, size_remaining);    }}static void read_chunk_stsz(qtmovie_t *qtmovie, size_t chunk_len){    unsigned int i;    uint32_t numentries;    size_t size_remaining = chunk_len - 8; /* FIXME WRONG */    /* version */    stream_read_uint8(qtmovie->stream);    size_remaining -= 1;    /* flags */    stream_read_uint8(qtmovie->stream);    stream_read_uint8(qtmovie->stream);    stream_read_uint8(qtmovie->stream);    size_remaining -= 3;    /* default sample size */    if (stream_read_uint32(qtmovie->stream) != 0)    {        fprintf(stderr, "i was expecting variable samples sizes\n");        stream_read_uint32(qtmovie->stream);        size_remaining -= 4;        return;    }    size_remaining -= 4;    numentries = stream_read_uint32(qtmovie->stream);    size_remaining -= 4;    qtmovie->res->num_sample_byte_sizes = numentries;    qtmovie->res->sample_byte_size = malloc(numentries * sizeof(*qtmovie->res->sample_byte_size));    for (i = 0; i < numentries; i++)    {        qtmovie->res->sample_byte_size[i] = stream_read_uint32(qtmovie->stream);        size_remaining -= 4;    }    if (size_remaining)    {        fprintf(stderr, "ehm, size remianing?\n");        stream_skip(qtmovie->stream, size_remaining);    }}static int read_chunk_stbl(qtmovie_t *qtmovie, size_t chunk_len){    size_t size_remaining = chunk_len - 8; /* FIXME WRONG */    while (size_remaining)    {        size_t sub_chunk_len;        fourcc_t sub_chunk_id;        sub_chunk_len = stream_read_uint32(qtmovie->stream);        if (sub_chunk_len <= 1 || sub_chunk_len > size_remaining)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -