示例#1
0
static int flac_read_header(AVFormatContext *s,
                             AVFormatParameters *ap)
{
    uint8_t buf[ID3v2_HEADER_SIZE];
    int ret, metadata_last=0, metadata_type, metadata_size, found_streaminfo=0;
    uint8_t header[4];
    uint8_t *buffer=NULL;
    AVStream *st = av_new_stream(s, 0);
    if (!st)
        return AVERROR(ENOMEM);
    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
    st->codec->codec_id = CODEC_ID_FLAC;
    st->need_parsing = AVSTREAM_PARSE_FULL;
    /* the parameters will be extracted from the compressed bitstream */

    /* skip ID3v2 header if found */
    ret = get_buffer(s->pb, buf, ID3v2_HEADER_SIZE);
    if (ret == ID3v2_HEADER_SIZE && ff_id3v2_match(buf, ID3v2_DEFAULT_MAGIC)) {
        int len = ff_id3v2_tag_len(buf);
        url_fseek(s->pb, len - ID3v2_HEADER_SIZE, SEEK_CUR);
    } else {
        url_fseek(s->pb, 0, SEEK_SET);
    }

    /* if fLaC marker is not found, assume there is no header */
    if (get_le32(s->pb) != MKTAG('f','L','a','C')) {
        url_fseek(s->pb, -4, SEEK_CUR);
        return 0;
    }

    /* process metadata blocks */
    while (!url_feof(s->pb) && !metadata_last) {
        get_buffer(s->pb, header, 4);
        ff_flac_parse_block_header(header, &metadata_last, &metadata_type,
                                   &metadata_size);
        switch (metadata_type) {
        /* allocate and read metadata block for supported types */
        case FLAC_METADATA_TYPE_STREAMINFO:
        case FLAC_METADATA_TYPE_VORBIS_COMMENT:
            buffer = av_mallocz(metadata_size + FF_INPUT_BUFFER_PADDING_SIZE);
            if (!buffer) {
                return AVERROR(ENOMEM);
            }
            if (get_buffer(s->pb, buffer, metadata_size) != metadata_size) {
                av_freep(&buffer);
                return AVERROR(EIO);
            }
            break;
        /* skip metadata block for unsupported types */
        default:
            ret = url_fseek(s->pb, metadata_size, SEEK_CUR);
            if (ret < 0)
                return ret;
        }

        if (metadata_type == FLAC_METADATA_TYPE_STREAMINFO) {
            FLACStreaminfo si;
            /* STREAMINFO can only occur once */
            if (found_streaminfo) {
                av_freep(&buffer);
                return AVERROR_INVALIDDATA;
            }
            if (metadata_size != FLAC_STREAMINFO_SIZE) {
                av_freep(&buffer);
                return AVERROR_INVALIDDATA;
            }
            found_streaminfo = 1;
            st->codec->extradata      = buffer;
            st->codec->extradata_size = metadata_size;
            buffer = NULL;

            /* get codec params from STREAMINFO header */
            ff_flac_parse_streaminfo(st->codec, &si, st->codec->extradata);

            /* set time base and duration */
            if (si.samplerate > 0) {
                av_set_pts_info(st, 64, 1, si.samplerate);
                if (si.samples > 0)
                    st->duration = si.samples;
            }
        } else {
            /* STREAMINFO must be the first block */
            if (!found_streaminfo) {
                av_freep(&buffer);
                return AVERROR_INVALIDDATA;
            }
            /* process supported blocks other than STREAMINFO */
            if (metadata_type == FLAC_METADATA_TYPE_VORBIS_COMMENT) {
                if (ff_vorbis_comment(s, &s->metadata, buffer, metadata_size)) {
                    av_log(s, AV_LOG_WARNING, "error parsing VorbisComment metadata\n");
                }
            }
            av_freep(&buffer);
        }
    }

    return 0;
}
示例#2
0
static VP8StatusCode ParseOptionalChunks(const uint8_t** const data,
                                         size_t* const data_size,
                                         size_t const riff_size,
                                         const uint8_t** const alpha_data,
                                         size_t* const alpha_size) {
  const uint8_t* buf;
  size_t buf_size;
  uint32_t total_size = TAG_SIZE +           
                        CHUNK_HEADER_SIZE +  
                        VP8X_CHUNK_SIZE;     
  assert(data != NULL);
  assert(data_size != NULL);
  buf = *data;
  buf_size = *data_size;

  assert(alpha_data != NULL);
  assert(alpha_size != NULL);
  *alpha_data = NULL;
  *alpha_size = 0;

  while (1) {
    uint32_t chunk_size;
    uint32_t disk_chunk_size;   

    *data = buf;
    *data_size = buf_size;

    if (buf_size < CHUNK_HEADER_SIZE) {  
      return VP8_STATUS_NOT_ENOUGH_DATA;
    }

    chunk_size = get_le32(buf + TAG_SIZE);
    if (chunk_size > MAX_CHUNK_PAYLOAD) {
      return VP8_STATUS_BITSTREAM_ERROR;          
    }
    
    disk_chunk_size = (CHUNK_HEADER_SIZE + chunk_size + 1) & ~1;
    total_size += disk_chunk_size;

    
    if (riff_size > 0 && (total_size > riff_size)) {
      return VP8_STATUS_BITSTREAM_ERROR;          
    }

    
    
    
    
    if (!memcmp(buf, "VP8 ", TAG_SIZE) ||
        !memcmp(buf, "VP8L", TAG_SIZE)) {
      return VP8_STATUS_OK;
    }

    if (buf_size < disk_chunk_size) {             
      return VP8_STATUS_NOT_ENOUGH_DATA;
    }

    if (!memcmp(buf, "ALPH", TAG_SIZE)) {         
      *alpha_data = buf + CHUNK_HEADER_SIZE;
      *alpha_size = chunk_size;
    }

    
    buf += disk_chunk_size;
    buf_size -= disk_chunk_size;
  }
}
示例#3
0
文件: smacker.c 项目: AndyA/ffmbc
static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    SmackerContext *smk = s->priv_data;
    int flags;
    int ret;
    int i;
    int frame_size = 0;
    int palchange = 0;
    int pos;

    if (url_feof(s->pb) || smk->cur_frame >= smk->frames)
        return AVERROR_EOF;

    /* if we demuxed all streams, pass another frame */
    if(smk->curstream < 0) {
        url_fseek(s->pb, smk->nextpos, 0);
        frame_size = smk->frm_size[smk->cur_frame] & (~3);
        flags = smk->frm_flags[smk->cur_frame];
        /* handle palette change event */
        pos = url_ftell(s->pb);
        if(flags & SMACKER_PAL){
            int size, sz, t, off, j, pos;
            uint8_t *pal = smk->pal;
            uint8_t oldpal[768];

            memcpy(oldpal, pal, 768);
            size = get_byte(s->pb);
            size = size * 4 - 1;
            frame_size -= size;
            frame_size--;
            sz = 0;
            pos = url_ftell(s->pb) + size;
            while(sz < 256){
                t = get_byte(s->pb);
                if(t & 0x80){ /* skip palette entries */
                    sz += (t & 0x7F) + 1;
                    pal += ((t & 0x7F) + 1) * 3;
                } else if(t & 0x40){ /* copy with offset */
                    off = get_byte(s->pb) * 3;
                    j = (t & 0x3F) + 1;
                    while(j-- && sz < 256) {
                        *pal++ = oldpal[off + 0];
                        *pal++ = oldpal[off + 1];
                        *pal++ = oldpal[off + 2];
                        sz++;
                        off += 3;
                    }
                } else { /* new entries */
                    *pal++ = smk_pal[t];
                    *pal++ = smk_pal[get_byte(s->pb) & 0x3F];
                    *pal++ = smk_pal[get_byte(s->pb) & 0x3F];
                    sz++;
                }
            }
            url_fseek(s->pb, pos, 0);
            palchange |= 1;
        }
        flags >>= 1;
        smk->curstream = -1;
        /* if audio chunks are present, put them to stack and retrieve later */
        for(i = 0; i < 7; i++) {
            if(flags & 1) {
                int size;
                size = get_le32(s->pb) - 4;
                frame_size -= size;
                frame_size -= 4;
                smk->curstream++;
                smk->bufs[smk->curstream] = av_realloc(smk->bufs[smk->curstream], size);
                smk->buf_sizes[smk->curstream] = size;
                ret = get_buffer(s->pb, smk->bufs[smk->curstream], size);
                if(ret != size)
                    return AVERROR(EIO);
                smk->stream_id[smk->curstream] = smk->indexes[i];
            }
            flags >>= 1;
        }
        if (av_new_packet(pkt, frame_size + 768))
            return AVERROR(ENOMEM);
        if(smk->frm_size[smk->cur_frame] & 1)
            palchange |= 2;
        pkt->data[0] = palchange;
        memcpy(pkt->data + 1, smk->pal, 768);
        ret = get_buffer(s->pb, pkt->data + 769, frame_size);
        if(ret != frame_size)
            return AVERROR(EIO);
        pkt->stream_index = smk->videoindex;
        pkt->size = ret + 769;
        smk->cur_frame++;
        smk->nextpos = url_ftell(s->pb);
    } else {
示例#4
0
/**
 * \brief read until we found all data needed for decoding
 * \param vst video stream of which to change parameters
 * \param ast video stream of which to change parameters
 * \param myth set if this is a MythTVVideo format file
 * \return 1 if all required codec data was found
 */
static int get_codec_data(ByteIOContext *pb, AVStream *vst,
                          AVStream *ast, int myth) {
    frametype_t frametype;
    if (!vst && !myth)
        return 1; // no codec data needed
    while (!url_feof(pb)) {
        int size, subtype;
        frametype = get_byte(pb);
        switch (frametype) {
            case NUV_EXTRADATA:
                subtype = get_byte(pb);
                url_fskip(pb, 6);
                size = PKTSIZE(get_le32(pb));
                if (vst && subtype == 'R') {
                    vst->codec->extradata_size = size;
                    vst->codec->extradata = av_malloc(size);
                    get_buffer(pb, vst->codec->extradata, size);
                    size = 0;
                    if (!myth)
                        return 1;
                }
                break;
            case NUV_MYTHEXT:
                url_fskip(pb, 7);
                size = PKTSIZE(get_le32(pb));
                if (size != 128 * 4)
                    break;
                get_le32(pb); // version
                if (vst) {
                    vst->codec->codec_tag = get_le32(pb);
                    vst->codec->codec_id =
                        codec_get_id(codec_bmp_tags, vst->codec->codec_tag);
                    if (vst->codec->codec_tag == MKTAG('R', 'J', 'P', 'G'))
                        vst->codec->codec_id = CODEC_ID_NUV;
                } else
                    url_fskip(pb, 4);

                if (ast) {
                    ast->codec->codec_tag = get_le32(pb);
                    ast->codec->sample_rate = get_le32(pb);
                    ast->codec->bits_per_sample = get_le32(pb);
                    ast->codec->channels = get_le32(pb);
                    ast->codec->codec_id =
                        wav_codec_get_id(ast->codec->codec_tag,
                                         ast->codec->bits_per_sample);
                    ast->need_parsing = AVSTREAM_PARSE_FULL;
                } else
                    url_fskip(pb, 4 * 4);

                size -= 6 * 4;
                url_fskip(pb, size);
                return 1;
            case NUV_SEEKP:
                size = 11;
                break;
            default:
                url_fskip(pb, 7);
                size = PKTSIZE(get_le32(pb));
                break;
        }
        url_fskip(pb, size);
    }
    return 0;
}
static int ape_read_header(AVFormatContext * s, AVFormatParameters * ap)
{
    ByteIOContext *pb = s->pb;
    APEContext *ape = s->priv_data;
    AVStream *st;
    uint32_t tag;
    int i;
    int total_blocks;
    int64_t pts;

    /* TODO: Skip any leading junk such as id3v2 tags */
    ape->junklength = 0;

    tag = get_le32(pb);
    if (tag != MKTAG('M', 'A', 'C', ' '))
        return -1;

    ape->fileversion = get_le16(pb);

    if (ape->fileversion < APE_MIN_VERSION || ape->fileversion > APE_MAX_VERSION) {
        av_log(s, AV_LOG_ERROR, "Unsupported file version - %d.%02d\n", ape->fileversion / 1000, (ape->fileversion % 1000) / 10);
        return -1;
    }

    if (ape->fileversion >= 3980) {
        ape->padding1             = get_le16(pb);
        ape->descriptorlength     = get_le32(pb);
        ape->headerlength         = get_le32(pb);
        ape->seektablelength      = get_le32(pb);
        ape->wavheaderlength      = get_le32(pb);
        ape->audiodatalength      = get_le32(pb);
        ape->audiodatalength_high = get_le32(pb);
        ape->wavtaillength        = get_le32(pb);
        get_buffer(pb, ape->md5, 16);

        /* Skip any unknown bytes at the end of the descriptor.
           This is for future compatibility */
        if (ape->descriptorlength > 52)
            url_fseek(pb, ape->descriptorlength - 52, SEEK_CUR);

        /* Read header data */
        ape->compressiontype      = get_le16(pb);
        ape->formatflags          = get_le16(pb);
        ape->blocksperframe       = get_le32(pb);
        ape->finalframeblocks     = get_le32(pb);
        ape->totalframes          = get_le32(pb);
        ape->bps                  = get_le16(pb);
        ape->channels             = get_le16(pb);
        ape->samplerate           = get_le32(pb);
    } else {
        ape->descriptorlength = 0;
        ape->headerlength = 32;

        ape->compressiontype      = get_le16(pb);
        ape->formatflags          = get_le16(pb);
        ape->channels             = get_le16(pb);
        ape->samplerate           = get_le32(pb);
        ape->wavheaderlength      = get_le32(pb);
        ape->wavtaillength        = get_le32(pb);
        ape->totalframes          = get_le32(pb);
        ape->finalframeblocks     = get_le32(pb);

        if (ape->formatflags & MAC_FORMAT_FLAG_HAS_PEAK_LEVEL) {
            url_fseek(pb, 4, SEEK_CUR); /* Skip the peak level */
            ape->headerlength += 4;
        }

        if (ape->formatflags & MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS) {
            ape->seektablelength = get_le32(pb);
            ape->headerlength += 4;
            ape->seektablelength *= sizeof(int32_t);
        } else
            ape->seektablelength = ape->totalframes * sizeof(int32_t);

        if (ape->formatflags & MAC_FORMAT_FLAG_8_BIT)
            ape->bps = 8;
        else if (ape->formatflags & MAC_FORMAT_FLAG_24_BIT)
            ape->bps = 24;
        else
            ape->bps = 16;

        if (ape->fileversion >= 3950)
            ape->blocksperframe = 73728 * 4;
        else if (ape->fileversion >= 3900 || (ape->fileversion >= 3800  && ape->compressiontype >= 4000))
            ape->blocksperframe = 73728;
        else
            ape->blocksperframe = 9216;

        /* Skip any stored wav header */
        if (!(ape->formatflags & MAC_FORMAT_FLAG_CREATE_WAV_HEADER))
            url_fskip(pb, ape->wavheaderlength);
    }

    if(!ape->totalframes){
        av_log(s, AV_LOG_ERROR, "No frames in the file!\n");
        return AVERROR(EINVAL);
    }
    if(ape->totalframes > UINT_MAX / sizeof(APEFrame)){
        av_log(s, AV_LOG_ERROR, "Too many frames: %d\n", ape->totalframes);
        return -1;
    }
    ape->frames       = av_malloc(ape->totalframes * sizeof(APEFrame));
    if(!ape->frames)
        return AVERROR_NOMEM;
    ape->firstframe   = ape->junklength + ape->descriptorlength + ape->headerlength + ape->seektablelength + ape->wavheaderlength;
    ape->currentframe = 0;


    ape->totalsamples = ape->finalframeblocks;
    if (ape->totalframes > 1)
        ape->totalsamples += ape->blocksperframe * (ape->totalframes - 1);

    if (ape->seektablelength > 0) {
        ape->seektable = av_malloc(ape->seektablelength);
        if (!ape->seektable)
            return AVERROR(ENOMEM);
        for (i = 0; i < ape->seektablelength / sizeof(uint32_t); i++)
            ape->seektable[i] = get_le32(pb);
    }

    ape->frames[0].pos     = ape->firstframe;
    ape->frames[0].nblocks = ape->blocksperframe;
    ape->frames[0].skip    = 0;
    for (i = 1; i < ape->totalframes; i++) {
        ape->frames[i].pos      = ape->seektable[i]; //ape->frames[i-1].pos + ape->blocksperframe;
        ape->frames[i].nblocks  = ape->blocksperframe;
        ape->frames[i - 1].size = ape->frames[i].pos - ape->frames[i - 1].pos;
        ape->frames[i].skip     = (ape->frames[i].pos - ape->frames[0].pos) & 3;
    }
    ape->frames[ape->totalframes - 1].size    = ape->finalframeblocks * 4;
    ape->frames[ape->totalframes - 1].nblocks = ape->finalframeblocks;

    for (i = 0; i < ape->totalframes; i++) {
        if(ape->frames[i].skip){
            ape->frames[i].pos  -= ape->frames[i].skip;
            ape->frames[i].size += ape->frames[i].skip;
        }
        ape->frames[i].size = (ape->frames[i].size + 3) & ~3;
    }


    ape_dumpinfo(s, ape);

    /* try to read APE tags */
    if (!url_is_streamed(pb)) {
        ape_parse_tag(s);
        url_fseek(pb, 0, SEEK_SET);
    }

    av_log(s, AV_LOG_DEBUG, "Decoding file - v%d.%02d, compression level %d\n", ape->fileversion / 1000, (ape->fileversion % 1000) / 10, ape->compressiontype);

    /* now we are ready: build format streams */
    st = av_new_stream(s, 0);
    if (!st)
        return -1;

    total_blocks = (ape->totalframes == 0) ? 0 : ((ape->totalframes - 1) * ape->blocksperframe) + ape->finalframeblocks;

    st->codec->codec_type      = CODEC_TYPE_AUDIO;
    st->codec->codec_id        = CODEC_ID_APE;
    st->codec->codec_tag       = MKTAG('A', 'P', 'E', ' ');
    st->codec->channels        = ape->channels;
    st->codec->sample_rate     = ape->samplerate;
    st->codec->bits_per_coded_sample = ape->bps;
    st->codec->frame_size      = MAC_SUBFRAME_SIZE;

    st->nb_frames = ape->totalframes;
    s->start_time = 0;
    s->duration   = (int64_t) total_blocks * AV_TIME_BASE / ape->samplerate;
    av_set_pts_info(st, 64, MAC_SUBFRAME_SIZE, ape->samplerate);

    st->codec->extradata = av_malloc(APE_EXTRADATA_SIZE);
    st->codec->extradata_size = APE_EXTRADATA_SIZE;
    AV_WL16(st->codec->extradata + 0, ape->fileversion);
    AV_WL16(st->codec->extradata + 2, ape->compressiontype);
    AV_WL16(st->codec->extradata + 4, ape->formatflags);

    pts = 0;
    for (i = 0; i < ape->totalframes; i++) {
        ape->frames[i].pts = pts;
        av_add_index_entry(st, ape->frames[i].pos, ape->frames[i].pts, 0, 0, AVINDEX_KEYFRAME);
        pts += ape->blocksperframe / MAC_SUBFRAME_SIZE;
    }

    return 0;
}
示例#6
0
// Skips to the next VP8/VP8L chunk header in the data given the size of the
// RIFF chunk 'riff_size'.
// Returns VP8_STATUS_BITSTREAM_ERROR if any invalid chunk size is encountered,
//         VP8_STATUS_NOT_ENOUGH_DATA in case of insufficient data, and
//         VP8_STATUS_OK otherwise.
// If an alpha chunk is found, *alpha_data and *alpha_size are set
// appropriately.
static VP8StatusCode ParseOptionalChunks(const uint8_t** const data,
                                         size_t* const data_size,
                                         size_t const riff_size,
                                         const uint8_t** const alpha_data,
                                         size_t* const alpha_size) {
  const uint8_t* buf;
  size_t buf_size;
  uint32_t total_size = TAG_SIZE +           // "WEBP".
                        CHUNK_HEADER_SIZE +  // "VP8Xnnnn".
                        VP8X_CHUNK_SIZE;     // data.
  assert(data != NULL);
  assert(data_size != NULL);
  buf = *data;
  buf_size = *data_size;

  assert(alpha_data != NULL);
  assert(alpha_size != NULL);
  *alpha_data = NULL;
  *alpha_size = 0;

  while (1) {
    uint32_t chunk_size;
    uint32_t disk_chunk_size;   // chunk_size with padding

    *data = buf;
    *data_size = buf_size;

    if (buf_size < CHUNK_HEADER_SIZE) {  // Insufficient data.
      return VP8_STATUS_NOT_ENOUGH_DATA;
    }

    chunk_size = get_le32(buf + TAG_SIZE);
    if (chunk_size > MAX_CHUNK_PAYLOAD) {
      return VP8_STATUS_BITSTREAM_ERROR;          // Not a valid chunk size.
    }
    // For odd-sized chunk-payload, there's one byte padding at the end.
    disk_chunk_size = (CHUNK_HEADER_SIZE + chunk_size + 1) & ~1;
    total_size += disk_chunk_size;

    // Check that total bytes skipped so far does not exceed riff_size.
    if (riff_size > 0 && (total_size > riff_size)) {
      return VP8_STATUS_BITSTREAM_ERROR;          // Not a valid chunk size.
    }

    // Start of a (possibly incomplete) VP8/VP8L chunk implies that we have
    // parsed all the optional chunks.
    // Note: This check must occur before the check 'buf_size < disk_chunk_size'
    // below to allow incomplete VP8/VP8L chunks.
    if (!memcmp(buf, "VP8 ", TAG_SIZE) ||
        !memcmp(buf, "VP8L", TAG_SIZE)) {
      return VP8_STATUS_OK;
    }

    if (buf_size < disk_chunk_size) {             // Insufficient data.
      return VP8_STATUS_NOT_ENOUGH_DATA;
    }

    if (!memcmp(buf, "ALPH", TAG_SIZE)) {         // A valid ALPH header.
      *alpha_data = buf + CHUNK_HEADER_SIZE;
      *alpha_size = chunk_size;
    }

    // We have a full and valid chunk; skip it.
    buf += disk_chunk_size;
    buf_size -= disk_chunk_size;
  }
}
示例#7
0
int __acc_cdecl_qsort le32_compare(const void *e1, const void *e2)
{
    const unsigned d1 = get_le32(e1);
    const unsigned d2 = get_le32(e2);
    return (d1 < d2) ? -1 : ((d1 > d2) ? 1 : 0);
}
示例#8
0
static int idcin_read_header(AVFormatContext *s,
                             AVFormatParameters *ap)
{
    ByteIOContext *pb = &s->pb;
    IdcinDemuxContext *idcin = (IdcinDemuxContext *)s->priv_data;
    AVStream *st;
    unsigned int width, height;
    unsigned int sample_rate, bytes_per_sample, channels;

    /* get the 5 header parameters */
    width = get_le32(pb);
    height = get_le32(pb);
    sample_rate = get_le32(pb);
    bytes_per_sample = get_le32(pb);
    channels = get_le32(pb);

    st = av_new_stream(s, 0);
    if (!st)
        return AVERROR_NOMEM;
    av_set_pts_info(st, 33, 1, 90000);
    idcin->video_stream_index = st->index;
    st->codec->codec_type = CODEC_TYPE_VIDEO;
    st->codec->codec_id = CODEC_ID_IDCIN;
    st->codec->codec_tag = 0;  /* no fourcc */
    st->codec->width = width;
    st->codec->height = height;

    /* load up the Huffman tables into extradata */
    st->codec->extradata_size = HUFFMAN_TABLE_SIZE;
    st->codec->extradata = av_malloc(HUFFMAN_TABLE_SIZE);
    if (get_buffer(pb, st->codec->extradata, HUFFMAN_TABLE_SIZE) !=
        HUFFMAN_TABLE_SIZE)
        return AVERROR_IO;
    /* save a reference in order to transport the palette */
    st->codec->palctrl = &idcin->palctrl;

    /* if sample rate is 0, assume no audio */
    if (sample_rate) {
        idcin->audio_present = 1;
        st = av_new_stream(s, 0);
        if (!st)
            return AVERROR_NOMEM;
        av_set_pts_info(st, 33, 1, 90000);
        idcin->audio_stream_index = st->index;
        st->codec->codec_type = CODEC_TYPE_AUDIO;
        st->codec->codec_tag = 1;
        st->codec->channels = channels;
        st->codec->sample_rate = sample_rate;
        st->codec->bits_per_sample = bytes_per_sample * 8;
        st->codec->bit_rate = sample_rate * bytes_per_sample * 8 * channels;
        st->codec->block_align = bytes_per_sample * channels;
        if (bytes_per_sample == 1)
            st->codec->codec_id = CODEC_ID_PCM_U8;
        else
            st->codec->codec_id = CODEC_ID_PCM_S16LE;

        if (sample_rate % 14 != 0) {
            idcin->audio_chunk_size1 = (sample_rate / 14) *
            bytes_per_sample * channels;
            idcin->audio_chunk_size2 = (sample_rate / 14 + 1) *
                bytes_per_sample * channels;
        } else {
            idcin->audio_chunk_size1 = idcin->audio_chunk_size2 =
                (sample_rate / 14) * bytes_per_sample * channels;
        }
        idcin->current_audio_chunk = 0;
    } else
        idcin->audio_present = 1;

    idcin->next_chunk_is_video = 1;
    idcin->pts = 0;

    return 0;
}
示例#9
0
static int idcin_read_packet(AVFormatContext *s,
                             AVPacket *pkt)
{
    int ret;
    unsigned int command;
    unsigned int chunk_size;
    IdcinDemuxContext *idcin = (IdcinDemuxContext *)s->priv_data;
    ByteIOContext *pb = &s->pb;
    int i;
    int palette_scale;
    unsigned char r, g, b;
    unsigned char palette_buffer[768];

    if (url_feof(&s->pb))
        return AVERROR_IO;

    if (idcin->next_chunk_is_video) {
        command = get_le32(pb);
        if (command == 2) {
            return AVERROR_IO;
        } else if (command == 1) {
            /* trigger a palette change */
            idcin->palctrl.palette_changed = 1;
            if (get_buffer(pb, palette_buffer, 768) != 768)
                return AVERROR_IO;
            /* scale the palette as necessary */
            palette_scale = 2;
            for (i = 0; i < 768; i++)
                if (palette_buffer[i] > 63) {
                    palette_scale = 0;
                    break;
                }

            for (i = 0; i < 256; i++) {
                r = palette_buffer[i * 3    ] << palette_scale;
                g = palette_buffer[i * 3 + 1] << palette_scale;
                b = palette_buffer[i * 3 + 2] << palette_scale;
                idcin->palctrl.palette[i] = (r << 16) | (g << 8) | (b);
            }
        }

        chunk_size = get_le32(pb);
        /* skip the number of decoded bytes (always equal to width * height) */
        url_fseek(pb, 4, SEEK_CUR);
        chunk_size -= 4;
        ret= av_get_packet(pb, pkt, chunk_size);
        if (ret != chunk_size)
            return AVERROR_IO;
        pkt->stream_index = idcin->video_stream_index;
        pkt->pts = idcin->pts;
    } else {
        /* send out the audio chunk */
        if (idcin->current_audio_chunk)
            chunk_size = idcin->audio_chunk_size2;
        else
            chunk_size = idcin->audio_chunk_size1;
        ret= av_get_packet(pb, pkt, chunk_size);
        if (ret != chunk_size)
            return AVERROR_IO;
        pkt->stream_index = idcin->audio_stream_index;
        pkt->pts = idcin->pts;

        idcin->current_audio_chunk ^= 1;
        idcin->pts += FRAME_PTS_INC;
    }

    if (idcin->audio_present)
        idcin->next_chunk_is_video ^= 1;

    return ret;
}
示例#10
0
static void get_spc_xid6( byte const begin [], int size, track_info_t* out )
{
	// header
	byte const* end = begin + size;
	if ( size < 8 || memcmp( begin, "xid6", 4 ) )
	{
		check( false );
		return;
	}
	int info_size = get_le32( begin + 4 );
	byte const* in = begin + 8; 
	if ( end - in > info_size )
	{
		dprintf( "SPC: Extra data after xid6\n" );
		end = in + info_size;
	}
	
	int year = 0;
	char copyright [256 + 5];
	int copyright_len = 0;
	int const year_len = 5;
	int disc = 0, track = 0;
	
	while ( end - in >= 4 )
	{
		// header
		int id   = in [0];
		int data = in [3] * 0x100 + in [2];
		int type = in [1];
		int len  = type ? data : 0;
		in += 4;
		if ( len > end - in )
		{
			dprintf( "SPC: xid6 goes past end" );
			break; // block goes past end of data
		}
		
		// handle specific block types
		char* field = NULL;
		switch ( id )
		{
			case 0x01: field = out->song;    break;
			case 0x02: field = out->game;    break;
			case 0x03: field = out->author;  break;
			case 0x04: field = out->dumper;  break;
			case 0x07: field = out->comment; break;
			case 0x10: field = out->ost;     break;
			case 0x11: disc = data;          break;
			case 0x12: track = data;         break;
			case 0x14: year = data;          break;
			
			//case 0x30: // intro length
			// Many SPCs have intro length set wrong for looped tracks, making it useless
			/*
			case 0x30:
				check( len == 4 );
				if ( len >= 4 )
				{
					out->intro_length = get_le32( in ) / 64;
					if ( out->length > 0 )
					{
						int loop = out->length - out->intro_length;
						if ( loop >= 2000 )
							out->loop_length = loop;
					}
				}
				break;
			*/
			
			case 0x33:
				check( len == 4 );
				if ( len >= 4 )
				{
					out->fade_length = get_le32( in ) / 64;
				}
				break;
			
			case 0x13:
				copyright_len = min( len, (int) sizeof copyright - year_len );
				memcpy( &copyright [year_len], in, copyright_len );
				break;
			
			default:
				if ( id < 0x01 || (id > 0x07 && id < 0x10) ||
						(id > 0x14 && id < 0x30) || id > 0x36 )
					dprintf( "SPC: Unknown xid6 block: %X\n", (int) id );
				break;
		}
		if ( field )
		{
			check( type == 1 );
			Gme_File::copy_field_( field, (char const*) in, len );
		}
		
		// skip to next block
		in += len;
		
		// blocks are supposed to be 4-byte aligned with zero-padding...
		byte const* unaligned = in;
		while ( (in - begin) & 3 && in < end )
		{
			if ( *in++ != 0 )
			{
				// ...but some files have no padding
				in = unaligned;
				//dprintf( "SPC: xid6 info tag wasn't properly padded to align\n" );
				break;
			}
		}
	}
	
	char* p = &copyright [year_len];
	if ( year )
	{
		*--p = ' ';
		// avoid using bloated printf
		for ( int n = 4; n--; )
		{
			*--p = char (year % 10 + '0');
			year /= 10;
		}
		copyright_len += year_len;
	}
	if ( copyright_len )
		Gme_File::copy_field_( out->copyright, p, copyright_len );
	
	if ( disc > 0 && disc <= 9 )
	{
		out->disc [0] = disc + '0';
		out->disc [1] = 0;
	}

	if ( track > 255 && track < ( ( 100 << 8 ) - 1 ) )
	{
		char* p = &copyright [3];
		*p = 0;
		if ( track & 255 ) *--p = char (track & 255);
		track >>= 8;
		for ( int n = 2; n-- && track; )
		{
			*--p = char (track % 10 + '0');
			track /= 10;
		}
		memcpy( out->track, p, &copyright [4] - p );
	}
示例#11
0
文件: wv.c 项目: MichaelH13/sdkpub
static int wv_read_block_header(AVFormatContext *ctx, ByteIOContext *pb)
{
    WVContext *wc = ctx->priv_data;
    uint32_t tag, ver;
    int size;
    int rate, bpp, chan;

    wc->pos = url_ftell(pb);
    tag = get_le32(pb);
    if (tag != MKTAG('w', 'v', 'p', 'k'))
        return -1;
    size = get_le32(pb);
    if(size < 24 || size > WV_BLOCK_LIMIT){
        av_log(ctx, AV_LOG_ERROR, "Incorrect block size %i\n", size);
        return -1;
    }
    wc->blksize = size;
    ver = get_le16(pb);
    if(ver < 0x402 || ver > 0x410){
        av_log(ctx, AV_LOG_ERROR, "Unsupported version %03X\n", ver);
        return -1;
    }
    get_byte(pb); // track no
    get_byte(pb); // track sub index
    wc->samples = get_le32(pb); // total samples in file
    wc->soff = get_le32(pb); // offset in samples of current block
    get_buffer(pb, wc->extra, WV_EXTRA_SIZE);
    wc->flags = AV_RL32(wc->extra + 4);
    //parse flags
    if(wc->flags & WV_FLOAT){
        av_log(ctx, AV_LOG_ERROR, "Floating point data is not supported\n");
        return -1;
    }
    if(wc->flags & WV_HYBRID){
        av_log(ctx, AV_LOG_ERROR, "Hybrid coding mode is not supported\n");
        return -1;
    }

    bpp = ((wc->flags & 3) + 1) << 3;
    chan = 1 + !(wc->flags & WV_MONO);
    rate = wv_rates[(wc->flags >> 23) & 0xF];
    if(rate == -1){
        av_log(ctx, AV_LOG_ERROR, "Unknown sampling rate\n");
        return -1;
    }
    if(!wc->bpp) wc->bpp = bpp;
    if(!wc->chan) wc->chan = chan;
    if(!wc->rate) wc->rate = rate;

    if(wc->flags && bpp != wc->bpp){
        av_log(ctx, AV_LOG_ERROR, "Bits per sample differ, this block: %i, header block: %i\n", bpp, wc->bpp);
        return -1;
    }
    if(wc->flags && chan != wc->chan){
        av_log(ctx, AV_LOG_ERROR, "Channels differ, this block: %i, header block: %i\n", chan, wc->chan);
        return -1;
    }
    if(wc->flags && rate != wc->rate){
        av_log(ctx, AV_LOG_ERROR, "Sampling rate differ, this block: %i, header block: %i\n", rate, wc->rate);
        return -1;
    }
    wc->blksize = size - 24;
    return 0;
}
示例#12
0
static int mtv_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
    MTVDemuxContext    *mtv = s->priv_data;
    ByteIOContext      *pb  = s->pb;
    AVStream           *st;


    url_fskip(pb, 3);
    mtv->file_size         = get_le32(pb);
    mtv->segments          = get_le32(pb);
    url_fskip(pb, 32);
    mtv->audio_identifier  = get_le24(pb);
    mtv->audio_br          = get_le16(pb);
    mtv->img_colorfmt      = get_le24(pb);
    mtv->img_bpp           = get_byte(pb);
    mtv->img_width         = get_le16(pb);
    mtv->img_height        = get_le16(pb);
    mtv->img_segment_size  = get_le16(pb);
    url_fskip(pb, 4);
    mtv->audio_subsegments = get_le16(pb);
    mtv->video_fps         = (mtv->audio_br / 4) / mtv->audio_subsegments;

    /* FIXME Add sanity check here */

    /* first packet is always audio*/

    mtv->audio_packet_count = 1;

    /* all systems go! init decoders */

    /* video - raw rgb565 */

    st = av_new_stream(s, VIDEO_SID);
    if(!st)
        return AVERROR(ENOMEM);

    av_set_pts_info(st, 64, 1, mtv->video_fps);
    st->codec->codec_type      = CODEC_TYPE_VIDEO;
    st->codec->codec_id        = CODEC_ID_RAWVIDEO;
    st->codec->codec_tag       = MKTAG('R', 'G', 'B', mtv->img_bpp);
    st->codec->width           = mtv->img_width;
    st->codec->height          = mtv->img_height;
    st->codec->bits_per_sample = mtv->img_bpp;
    st->codec->sample_rate     = mtv->video_fps;

    /* audio - mp3 */

    st = av_new_stream(s, AUDIO_SID);
    if(!st)
        return AVERROR(ENOMEM);

    av_set_pts_info(st, 64, 1, AUDIO_SAMPLING_RATE);
    st->codec->codec_type      = CODEC_TYPE_AUDIO;
    st->codec->codec_id        = CODEC_ID_MP3;
    st->codec->bit_rate        = mtv->audio_br;
    st->need_parsing           = AVSTREAM_PARSE_FULL;

    /* Jump over header */

    if(url_fseek(pb, MTV_HEADER_SIZE, SEEK_SET) != MTV_HEADER_SIZE)
        return AVERROR(EIO);

    return 0;

}
示例#13
0
static int nuv_header(AVFormatContext *s, AVFormatParameters *ap) {
    NUVContext *ctx = s->priv_data;
    ByteIOContext *pb = s->pb;
    char id_string[12];
    double aspect, fps;
    int is_mythtv, width, height, v_packs, a_packs;
    int stream_nr = 0;
    AVStream *vst = NULL, *ast = NULL;
    get_buffer(pb, id_string, 12);
    is_mythtv = !memcmp(id_string, "MythTVVideo", 12);
    url_fskip(pb, 5); // version string
    url_fskip(pb, 3); // padding
    width = get_le32(pb);
    height = get_le32(pb);
    get_le32(pb); // unused, "desiredwidth"
    get_le32(pb); // unused, "desiredheight"
    get_byte(pb); // 'P' == progressive, 'I' == interlaced
    url_fskip(pb, 3); // padding
    aspect = av_int2dbl(get_le64(pb));
    if (aspect > 0.9999 && aspect < 1.0001)
        aspect = 4.0 / 3.0;
    fps = av_int2dbl(get_le64(pb));

    // number of packets per stream type, -1 means unknown, e.g. streaming
    v_packs = get_le32(pb);
    a_packs = get_le32(pb);
    get_le32(pb); // text

    get_le32(pb); // keyframe distance (?)

    if (v_packs) {
        ctx->v_id = stream_nr++;
        vst = av_new_stream(s, ctx->v_id);
        if (!vst)
            return AVERROR(ENOMEM);
        vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
        vst->codec->codec_id = CODEC_ID_NUV;
        vst->codec->width = width;
        vst->codec->height = height;
        vst->codec->bits_per_coded_sample = 10;
        vst->sample_aspect_ratio = av_d2q(aspect * height / width, 10000);
        vst->r_frame_rate = av_d2q(fps, 60000);
        av_set_pts_info(vst, 32, 1, 1000);
    } else
        ctx->v_id = -1;

    if (a_packs) {
        ctx->a_id = stream_nr++;
        ast = av_new_stream(s, ctx->a_id);
        if (!ast)
            return AVERROR(ENOMEM);
        ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
        ast->codec->codec_id = CODEC_ID_PCM_S16LE;
        ast->codec->channels = 2;
        ast->codec->sample_rate = 44100;
        ast->codec->bit_rate = 2 * 2 * 44100 * 8;
        ast->codec->block_align = 2 * 2;
        ast->codec->bits_per_coded_sample = 16;
        av_set_pts_info(ast, 32, 1, 1000);
    } else
        ctx->a_id = -1;

    get_codec_data(pb, vst, ast, is_mythtv);
    ctx->rtjpg_video = vst && vst->codec->codec_id == CODEC_ID_NUV;
    return 0;
}
示例#14
0
static int wv_read_block_header(AVFormatContext *ctx, ByteIOContext *pb)
{
    WVContext *wc = ctx->priv_data;
    uint32_t tag, ver;
    int size;
    int rate, bpp, chan;

    wc->pos = url_ftell(pb);
    tag = get_le32(pb);
    if (tag != MKTAG('w', 'v', 'p', 'k'))
        return -1;
    size = get_le32(pb);
    if(size < 24 || size > WV_BLOCK_LIMIT){
        av_log(ctx, AV_LOG_ERROR, "Incorrect block size %i\n", size);
        return -1;
    }
    wc->blksize = size;
    ver = get_le16(pb);
    if(ver < 0x402 || ver > 0x410){
        av_log(ctx, AV_LOG_ERROR, "Unsupported version %03X\n", ver);
        return -1;
    }
    get_byte(pb); // track no
    get_byte(pb); // track sub index
    wc->samples = get_le32(pb); // total samples in file
    wc->soff = get_le32(pb); // offset in samples of current block
    get_buffer(pb, wc->extra, WV_EXTRA_SIZE);
    wc->flags = AV_RL32(wc->extra + 4);
    //parse flags
    bpp = ((wc->flags & 3) + 1) << 3;
    chan = 1 + !(wc->flags & WV_MONO);
    rate = wv_rates[(wc->flags >> 23) & 0xF];
    if(rate == -1 && !wc->block_parsed){
        int64_t block_end = url_ftell(pb) + wc->blksize - 24;
        if(url_is_streamed(pb)){
            av_log(ctx, AV_LOG_ERROR, "Cannot determine custom sampling rate\n");
            return -1;
        }
        while(url_ftell(pb) < block_end){
            int id, size;
            id = get_byte(pb);
            size = (id & 0x80) ? get_le24(pb) : get_byte(pb);
            size <<= 1;
            if(id&0x40)
                size--;
            if((id&0x3F) == 0x27){
                rate = get_le24(pb);
                break;
            }else{
                url_fskip(pb, size);
            }
        }
        if(rate == -1){
            av_log(ctx, AV_LOG_ERROR, "Cannot determine custom sampling rate\n");
            return -1;
        }
        url_fseek(pb, block_end - wc->blksize + 24, SEEK_SET);
    }
    if(!wc->bpp) wc->bpp = bpp;
    if(!wc->chan) wc->chan = chan;
    if(!wc->rate) wc->rate = rate;

    if(wc->flags && bpp != wc->bpp){
        av_log(ctx, AV_LOG_ERROR, "Bits per sample differ, this block: %i, header block: %i\n", bpp, wc->bpp);
        return -1;
    }
    if(wc->flags && chan != wc->chan){
        av_log(ctx, AV_LOG_ERROR, "Channels differ, this block: %i, header block: %i\n", chan, wc->chan);
        return -1;
    }
    if(wc->flags && rate != -1 && rate != wc->rate){
        av_log(ctx, AV_LOG_ERROR, "Sampling rate differ, this block: %i, header block: %i\n", rate, wc->rate);
        return -1;
    }
    wc->blksize = size - 24;
    return 0;
}
示例#15
0
static int ea_read_packet(AVFormatContext *s,
                          AVPacket *pkt)
{
    EaDemuxContext *ea = s->priv_data;
    ByteIOContext *pb = s->pb;
    int ret = 0;
    int packet_read = 0;
    unsigned int chunk_type, chunk_size;
    int key = 0;

    while (!packet_read) {
        chunk_type = get_le32(pb);
        chunk_size = (ea->big_endian ? get_be32(pb) : get_le32(pb)) - 8;

        switch (chunk_type) {
        /* audio data */
        case ISNh_TAG:
            /* header chunk also contains data; skip over the header portion*/
            url_fskip(pb, 32);
            chunk_size -= 32;
        case ISNd_TAG:
        case SCDl_TAG:
        case SNDC_TAG:
            if (!ea->audio_codec) {
                url_fskip(pb, chunk_size);
                break;
            } else if (ea->audio_codec == CODEC_ID_PCM_S16LE_PLANAR) {
                url_fskip(pb, 12);  /* planar header */
                chunk_size -= 12;
            }
            ret = av_get_packet(pb, pkt, chunk_size);
            if (ret != chunk_size)
                ret = AVERROR(EIO);
            else {
                    pkt->stream_index = ea->audio_stream_index;
                    pkt->pts = 90000;
                    pkt->pts *= ea->audio_frame_counter;
                    pkt->pts /= ea->sample_rate;

                    switch (ea->audio_codec) {
                    case CODEC_ID_ADPCM_EA:
                    /* 2 samples/byte, 1 or 2 samples per frame depending
                     * on stereo; chunk also has 12-byte header */
                    ea->audio_frame_counter += ((chunk_size - 12) * 2) /
                        ea->num_channels;
                        break;
                    default:
                        ea->audio_frame_counter += chunk_size /
                            (ea->bytes * ea->num_channels);
                    }
            }

            packet_read = 1;
            break;

        /* ending tag */
        case 0:
        case ISNe_TAG:
        case SCEl_TAG:
        case SEND_TAG:
            ret = AVERROR(EIO);
            packet_read = 1;
            break;

        case MV0K_TAG:
            key = PKT_FLAG_KEY;
        case MV0F_TAG:
            ret = av_get_packet(pb, pkt, chunk_size);
            if (ret != chunk_size)
                ret = AVERROR_IO;
            else {
                pkt->stream_index = ea->video_stream_index;
                pkt->flags |= key;
            }
            packet_read = 1;
            break;

        default:
            url_fseek(pb, chunk_size, SEEK_CUR);
            break;
        }
    }

    return ret;
}
示例#16
0
int main(int argc, char *argv[])
{
	int i, devfd, c, readlen, writelen;
	int req_blocks, part1_offset;
	int ubl_size = 0, uboot_size;
	struct rbl_header *rblp;
	unsigned int uboot_load_address = 0, uboot_entry_point = 0;
	unsigned int uboot_sign_start = 0, uboot_start_block = 0;

	while ((c = getopt(argc, argv, "?hvd:u:b:l:e:p:")) >= 0) {
		switch (c) {
		case 'd':
			dev_name = optarg;
			break;
		case 'u':
			ubl_name = optarg;
			break;
		case 'l':
			uboot_load_address = strtoul(optarg, NULL, 16);
			break;
		case 'e':
			uboot_entry_point = strtoul(optarg, NULL, 16);
			break;
		case 'v':
			verbose++;
			break;
		case 'b':
			uboot_name = optarg;
			break;
		case 'p':
			platform = optarg;
			for (i = 0; i < strlen(platform) - 1; i++)
				platform[i] = toupper(platform[i]);
			printf("%s\n", platform);
			break;
		case 'h':
		case '?':
			usage();
			return 0;
		}
	}

	if (!ubl_name)
		uboot_start_block = UBL_START_BLOCK;

	if (!strcmp(platform, "DM3XX")) {
		if (!uboot_load_address)
			uboot_load_address = DM3XX_UBOOT_LOAD_ADDRESS;
		if (!uboot_entry_point)
			uboot_entry_point = DM3XX_UBOOT_LOAD_ADDRESS;
	}

	if (!strcmp(platform, "OMAPL138")) {
		if (!uboot_load_address)
			uboot_load_address = DA850_UBOOT_LOAD_ADDRESS;
		if (!uboot_entry_point)
			uboot_entry_point = DA850_UBOOT_LOAD_ADDRESS;
	}

	/* Open the SD/MMC Device in Read-Write Mode */
	devfd = open(dev_name, O_RDWR);
	if (devfd <= 0) {
		fprintf(stderr, "Device open Error : %s\n", strerror(errno));
		exit(-1);
	}

	/* Read Master Boot Record - MBR */
	readlen = read(devfd, readbuf, BLOCK_SIZE);
	if (readlen < 0)
		fprintf(stderr, "Device Read Error : %s\n", strerror(errno));

	if (verbose > 2) {
		printf("====================Master Boot Record============\n");
		print_hex(readbuf, BLOCK_SIZE);
		printf("==================================================\n");
	}

	/* Get UBL file size and round it to upper 512 byte boundary */
//	if (!strcmp(platform, "DM3XX")) {
	if (ubl_name) {
		ubl_size = get_file_size(ubl_name);
		if (ubl_size < 0) {
			close(devfd);
			return -1;
		}

		ubl_size = (ubl_size + BLOCK_SIZE - 1) & ~BLOCK_SIZE;
		verbose_printf("UBL Size %d\n", ubl_size);
	}
		if (uboot_name) {
		uboot_size = get_file_size(uboot_name);
		uboot_size = (uboot_size + BLOCK_SIZE - 1) & ~BLOCK_SIZE;
		verbose_printf("U-Boot Size %d\n", uboot_size);

		if (uboot_size <= 0) {
			fprintf(stderr,
				"Invalid U-Boot Size %d\n", uboot_size);
			close(devfd);
			return -1;
		}
	}
 

	/* Get U-boot file size and round it to upper 512 byte boundary */
//	uboot_size = get_file_size(uboot_name);
//	if (uboot_size <= 0) {
//		fprintf(stderr, "Invalid U-Boot Size %d\n", uboot_size);
//		close(devfd);
//		return -1;
//	}

	/* Get first partition start address offset from Master Boot Record */
	part1_offset = get_le32 (&readbuf[PART1_LBA_OFFSET]);
	verbose_printf("First partition starts at %d(%ld)\n", part1_offset,
			(part1_offset * BLOCK_SIZE));

	/* Add MBR + UBL Size + Uboot Size */

//	if (!(strcmp(platform, "DM3XX"))) {
	if (ubl_name) {
		req_blocks = UBL_START_BLOCK + (ubl_size / BLOCK_SIZE) +
		UBL_BLOCK_OFFSET + (uboot_size / BLOCK_SIZE) + 1;
		printf("Required Blocks %d, Available Blocks %d\n", req_blocks,
			part1_offset - 1);

		/*
		 * Return if the card does not have enough
		 * space for writing UBL/Uboot
		 */
		if (req_blocks > part1_offset) {
			fprintf(stderr, "Not enough space left for "
					"flashing UBL and U-boot\n");
			fprintf(stderr, "Make sure that the First Partition "
				" Starts after %d sectors\n", req_blocks);
			close(devfd);
			return -1;
		}

		/* Generate UBL Signature */
		rblp = (struct rbl_header *)ubl_signature;
		memset(rblp, 0, sizeof(struct rbl_header));
		rblp->magic_num   = UBL_MAGIC_NUM;
		rblp->entry_point = UBL_ENTRY_POINT;
		rblp->num_blocks  = ubl_size / BLOCK_SIZE;
		rblp->start_block = UBL_START_BLOCK;

		if (verbose > 1) {
			printf("UBL Magic Number     : %08x\n",
							rblp->magic_num);
			printf("UBL Entry Point      : %08x\n",
							rblp->entry_point);
			printf("UBL Number of Blocks : %08x\n",
							rblp->num_blocks);
			printf("UBL Starting Block   : %08x\n",
							rblp->start_block);
			printf("UBL Load Address     : %08x\n",
							rblp->load_address);
		}

		/* Write UBL Signature 
		verbose_printf("Writing UBL Signature\n");
		lseek(devfd, (BLOCK_SIZE * UBL_SIGN_START), SEEK_SET);
		for (i = UBL_SIGN_START; i <
				(UBL_SIGN_COUNT + UBL_SIGN_START); i++) {
			writelen = write(devfd, rblp, BLOCK_SIZE);
			if (writelen < BLOCK_SIZE) {
				close(devfd);
				return -1;
			}
		} */

		/* Write UBL Binary */
		verbose_printf("Writing UBL\n");
//		lseek(devfd, (BLOCK_SIZE * rblp->start_block), SEEK_SET);
		write_file(devfd, ubl_name);
	}
	if (!uboot_name) {
		close(devfd);
		return 0;
	}

	/* Generate U-boot signature */
	rblp = (struct rbl_header *)uboot_signature;
	memset(rblp, 0, sizeof(struct rbl_header));
	rblp->magic_num = UBOOT_MAGIC_NUM;
	rblp->entry_point = uboot_entry_point;
	rblp->num_blocks = (uboot_size / BLOCK_SIZE) + 1;

	if (!strcmp(platform, "DM3XX")) {
		rblp->start_block = UBL_START_BLOCK + (ubl_size / BLOCK_SIZE) +
					UBL_BLOCK_OFFSET;
	} else if (!strcmp(platform, "OMAPL138")) {
		rblp->start_block = uboot_start_block;
		uboot_sign_start = 1;
	} else {
		printf("error\n");
		return -1;
	}

	rblp->load_address = uboot_load_address;

	if (verbose > 1) {
		printf("U-Boot Magic Number     : %08x\n", rblp->magic_num);
		printf("U-Boot Entry Point      : %08x\n", rblp->entry_point);
		printf("U-Boot Number of Blocks : %08x\n", rblp->num_blocks);
		printf("U-Boot Starting Block   : %08x\n", rblp->start_block);
		printf("Load U-Boot Address     : %08x\n", rblp->load_address);
	}

	/* Write U-Boot Signature */
	verbose_printf("Writing U-Boot Signature\n");
	if (!strcmp(platform, "DM3XX"))
		lseek(devfd, (BLOCK_SIZE * UBOOT_SIGN_START), SEEK_SET);
	else
		lseek(devfd, (BLOCK_SIZE * uboot_sign_start), SEEK_SET);

	for (i = UBOOT_SIGN_START; i <
				(UBOOT_SIGN_COUNT + UBOOT_SIGN_START); i++) {
		writelen = write(devfd, rblp, BLOCK_SIZE);
		if (writelen < BLOCK_SIZE) {
			close(devfd);
			return -1;
		}
	}

	/* Write U-Boot File */
	lseek(devfd, (BLOCK_SIZE * rblp->start_block), SEEK_SET);
	verbose_printf("Writing U-Boot\n");
	write_file(devfd, uboot_name);

	printf("Done...\n");
	close(devfd);
	return 0;
}
示例#17
0
文件: rpl.c 项目: AndyA/ffmbc
static int rpl_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    RPLContext *rpl = s->priv_data;
    ByteIOContext *pb = s->pb;
    AVStream* stream;
    AVIndexEntry* index_entry;
    uint32_t ret;

    if (rpl->chunk_part == s->nb_streams) {
        rpl->chunk_number++;
        rpl->chunk_part = 0;
    }

    stream = s->streams[rpl->chunk_part];

    if (rpl->chunk_number >= stream->nb_index_entries)
        return -1;

    index_entry = &stream->index_entries[rpl->chunk_number];

    if (rpl->frame_in_part == 0)
        if (url_fseek(pb, index_entry->pos, SEEK_SET) < 0)
            return AVERROR(EIO);

    if (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
        stream->codec->codec_tag == 124) {
        // We have to split Escape 124 frames because there are
        // multiple frames per chunk in Escape 124 samples.
        uint32_t frame_size, frame_flags;

        frame_flags = get_le32(pb);
        frame_size = get_le32(pb);
        if (url_fseek(pb, -8, SEEK_CUR) < 0)
            return AVERROR(EIO);

        ret = av_get_packet(pb, pkt, frame_size);
        if (ret != frame_size) {
            av_free_packet(pkt);
            return AVERROR(EIO);
        }
        pkt->duration = 1;
        pkt->pts = index_entry->timestamp + rpl->frame_in_part;
        pkt->stream_index = rpl->chunk_part;

        rpl->frame_in_part++;
        if (rpl->frame_in_part == rpl->frames_per_chunk) {
            rpl->frame_in_part = 0;
            rpl->chunk_part++;
        }
    } else {
        ret = av_get_packet(pb, pkt, index_entry->size);
        if (ret != index_entry->size) {
            av_free_packet(pkt);
            return AVERROR(EIO);
        }

        if (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
            // frames_per_chunk should always be one here; the header
            // parsing will warn if it isn't.
            pkt->duration = rpl->frames_per_chunk;
        } else {
            // All the audio codecs supported in this container
            // (at least so far) are constant-bitrate.
            pkt->duration = ret * 8;
        }
        pkt->pts = index_entry->timestamp;
        pkt->stream_index = rpl->chunk_part;
        rpl->chunk_part++;
    }

    // None of the Escape formats have keyframes, and the ADPCM
    // format used doesn't have keyframes.
    if (rpl->chunk_number == 0 && rpl->frame_in_part == 0)
        pkt->flags |= AV_PKT_FLAG_KEY;

    return ret;
}
示例#18
0
blargg_err_t Zip_Extractor::update_info( bool advance_first )
{
	while ( 1 )
	{
		entry_t& e = (entry_t&) catalog [catalog_pos];

		if ( memcmp( e.type, "\0K\1\2P", 5 ) && memcmp( e.type, "PK\1\2", 4 ) )
		{
			check( !memcmp( e.type, "\0K\5\6P", 5 ) );
			break;
		}

		unsigned len = get_le16( e.filename_len );
		int next_offset = catalog_pos + entry_size + len + get_le16( e.extra_len ) +
				get_le16( e.comment_len );
		if ( (unsigned) next_offset > catalog.size() - end_entry_size )
			return blargg_err_file_corrupt;
		
		if ( catalog [next_offset] == 'P' )
			reorder_entry_header( next_offset );

		if ( !advance_first )
		{
			char unterminate = e.filename[len];
			e.filename [len] = 0; // terminate name
			std::string fname = e.filename;
			
			if ( is_normal_file( e, len ) )
			{
				e.filename[len] = unterminate;
				name.resize(fname.size()+1);
				if(len != 0)
				{
					memcpy(name.begin(),fname.c_str(),len);
					name[name.size()-1] = 0;
				}
				set_name( name.begin() );
				set_info( get_le32( e.size ), get_le32( e.date ), get_le32( e.crc ) );

				unsigned extra_len = get_le32(e.extra_len);

				//walk over extra fields
				unsigned i = len;
				while(i < extra_len + len)
				{
					unsigned id = get_le16(e.filename + i);
					i += 2;
					unsigned exlen = get_le16(e.filename + i);
					i += 2;
					int exfield = i;
					i += exlen;
					if(id == 0x7075) //INFO-ZIP unicode path extra field (contains version, checksum, and utf-8 filename)
					{
						unsigned version = (unsigned char)*(e.filename + exfield);
						if(version == 1)
						{
							exfield += 1; //skip version
							exfield += 4; //skip crc
							//the remainder is a utf-8 filename
							int fnamelen = exlen-5;
							char* tempbuf = (char*)malloc(fnamelen + 1);
							memcpy(tempbuf,e.filename + exfield, fnamelen);
							tempbuf[fnamelen] = 0;
							wchar_t* wfname_buf = blargg_to_wide(tempbuf);
							std::wstring wfname = wfname_buf;
							free(tempbuf);
							free(wfname_buf);
							
							size_t wfname_len = wfname.size();

							this->wname.resize(wfname_len+1);
							if(wfname_len != 0)
							{
								memcpy(this->wname.begin(),wfname.c_str(),wfname_len*sizeof(wchar_t));
								wname[wname.size()-1] = 0;
							}
							set_name( name.begin(), wname.begin() );
							
						}
					}
				}
				break;
			}
		}

		catalog_pos = next_offset;
		advance_first = false;
	}
	
	return blargg_ok;
}
示例#19
0
static int read_header(AVFormatContext *s,
                       AVFormatParameters *ap)
{
    AnmDemuxContext *anm = s->priv_data;
    ByteIOContext *pb = s->pb;
    AVStream *st;
    int i, ret;

    url_fskip(pb, 4); /* magic number */
    if (get_le16(pb) != MAX_PAGES) {
        av_log_ask_for_sample(s, "max_pages != " AV_STRINGIFY(MAX_PAGES) "\n");
        return AVERROR_INVALIDDATA;
    }

    anm->nb_pages   = get_le16(pb);
    anm->nb_records = get_le32(pb);
    url_fskip(pb, 2); /* max records per page */
    anm->page_table_offset = get_le16(pb);
    if (get_le32(pb) != ANIM_TAG)
        return AVERROR_INVALIDDATA;

    /* video stream */
    st = av_new_stream(s, 0);
    if (!st)
        return AVERROR(ENOMEM);
    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    st->codec->codec_id   = CODEC_ID_ANM;
    st->codec->codec_tag  = 0; /* no fourcc */
    st->codec->width      = get_le16(pb);
    st->codec->height     = get_le16(pb);
    if (get_byte(pb) != 0)
        goto invalid;
    url_fskip(pb, 1); /* frame rate multiplier info */

    /* ignore last delta record (used for looping) */
    if (get_byte(pb))  /* has_last_delta */
        anm->nb_records = FFMAX(anm->nb_records - 1, 0);

    url_fskip(pb, 1); /* last_delta_valid */

    if (get_byte(pb) != 0)
        goto invalid;

    if (get_byte(pb) != 1)
        goto invalid;

    url_fskip(pb, 1); /* other recs per frame */

    if (get_byte(pb) != 1)
        goto invalid;

    url_fskip(pb, 32); /* record_types */
    st->nb_frames = get_le32(pb);
    av_set_pts_info(st, 64, 1, get_le16(pb));
    url_fskip(pb, 58);

    /* color cycling and palette data */
    st->codec->extradata_size = 16*8 + 4*256;
    st->codec->extradata      = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
    if (!st->codec->extradata) {
        ret = AVERROR(ENOMEM);
        goto close_and_return;
    }
    ret = get_buffer(pb, st->codec->extradata, st->codec->extradata_size);
    if (ret < 0)
        goto close_and_return;

    /* read page table */
    ret = url_fseek(pb, anm->page_table_offset, SEEK_SET);
    if (ret < 0)
        goto close_and_return;

    for (i = 0; i < MAX_PAGES; i++) {
        Page *p = &anm->pt[i];
        p->base_record = get_le16(pb);
        p->nb_records  = get_le16(pb);
        p->size        = get_le16(pb);
    }

    /* find page of first frame */
    anm->page = find_record(anm, 0);
    if (anm->page < 0) {
        ret = anm->page;
        goto close_and_return;
    }

    anm->record = -1;
    return 0;

invalid:
    av_log_ask_for_sample(s, NULL);
    ret = AVERROR_INVALIDDATA;

close_and_return:
    av_close_input_stream(s);
    return ret;
}
示例#20
0
/* aiff input */
static int aiff_read_header(AVFormatContext *s,
                            AVFormatParameters *ap)
{
    int size, filesize, offset;
    uint32_t tag;
    unsigned version = AIFF_C_VERSION1;
    ByteIOContext *pb = &s->pb;
    AVStream * st = s->streams[0];

    /* check FORM header */
    filesize = get_tag(pb, &tag);
    if (filesize < 0 || tag != MKTAG('F', 'O', 'R', 'M'))
        return AVERROR_INVALIDDATA;

    /* AIFF data type */
    tag = get_le32(pb);
    if (tag == MKTAG('A', 'I', 'F', 'F'))       /* Got an AIFF file */
        version = AIFF;
    else if (tag != MKTAG('A', 'I', 'F', 'C'))  /* An AIFF-C file then */
        return AVERROR_INVALIDDATA;

    filesize -= 4;

    st = av_new_stream(s, 0);
    if (!st)
        return AVERROR_NOMEM;

    while (filesize > 0) {
        /* parse different chunks */
        size = get_tag(pb, &tag);
        if (size < 0)
            return size;

        filesize -= size + 8;

        switch (tag) {
            case MKTAG('C', 'O', 'M', 'M'):     /* Common chunk */
                /* Then for the complete header info */
                st->nb_frames = get_aiff_header (pb, st->codec, size, version);
                if (st->nb_frames < 0)
                        return st->nb_frames;
                break;

            case MKTAG('F', 'V', 'E', 'R'):     /* Version chunk */
                version = get_be32(pb);
                break;

            case MKTAG('N', 'A', 'M', 'E'):     /* Sample name chunk */
                get_meta (pb, s->title, sizeof(s->title), size);
                break;

            case MKTAG('A', 'U', 'T', 'H'):     /* Author chunk */
                get_meta (pb, s->author, sizeof(s->author), size);
                break;

            case MKTAG('(', 'c', ')', ' '):     /* Copyright chunk */
                get_meta (pb, s->copyright, sizeof(s->copyright), size);
                break;

            case MKTAG('A', 'N', 'N', 'O'):     /* Annotation chunk */
                get_meta (pb, s->comment, sizeof(s->comment), size);
                break;

            case MKTAG('S', 'S', 'N', 'D'):     /* Sampled sound chunk */
                get_be32(pb);               /* Block align... don't care */
                offset = get_be32(pb);      /* Offset of sound data */
                goto got_sound;

            default: /* Jump */
                if (size & 1)   /* Always even aligned */
                    size++;
                url_fskip (pb, size);
        }
    }

    /* End of loop and didn't get sound */
    return AVERROR_INVALIDDATA;

got_sound:
    /* Now positioned, get the sound data start and end */
    if (st->nb_frames)
        s->file_size = st->nb_frames * st->codec->block_align;

    av_set_pts_info(st, 64, 1, st->codec->sample_rate);
    st->start_time = 0;
    st->duration = st->nb_frames;

    /* Position the stream at the first block */
    url_fskip(pb, offset);

    return 0;
}
示例#21
0
static int fourxm_read_packet(AVFormatContext *s,
                              AVPacket *pkt)
{
    FourxmDemuxContext *fourxm = s->priv_data;
    ByteIOContext *pb = &s->pb;
    unsigned int fourcc_tag;
    unsigned int size, out_size;
    int ret = 0;
    int track_number;
    int packet_read = 0;
    unsigned char header[8];
    int audio_frame_count;

    while (!packet_read) {

        if ((ret = get_buffer(&s->pb, header, 8)) < 0)
            return ret;
        fourcc_tag = AV_RL32(&header[0]);
        size = AV_RL32(&header[4]);
        if (url_feof(pb))
            return AVERROR(EIO);
        switch (fourcc_tag) {

        case LIST_TAG:
            /* this is a good time to bump the video pts */
            fourxm->video_pts ++;

            /* skip the LIST-* tag and move on to the next fourcc */
            get_le32(pb);
            break;

        case ifrm_TAG:
        case pfrm_TAG:
        case cfrm_TAG:
        case ifr2_TAG:
        case pfr2_TAG:
        case cfr2_TAG:
        {

            /* allocate 8 more bytes than 'size' to account for fourcc
             * and size */
            if (size + 8 < size || av_new_packet(pkt, size + 8))
                return AVERROR(EIO);
            pkt->stream_index = fourxm->video_stream_index;
            pkt->pts = fourxm->video_pts;
            pkt->pos = url_ftell(&s->pb);
            memcpy(pkt->data, header, 8);
            ret = get_buffer(&s->pb, &pkt->data[8], size);

            if (ret < 0)
                av_free_packet(pkt);
            else
                packet_read = 1;
            break;
        }

        case snd__TAG:
            track_number = get_le32(pb);
            out_size= get_le32(pb);
            size-=8;

            if (track_number == fourxm->selected_track) {
                ret= av_get_packet(&s->pb, pkt, size);
                if(ret<0)
                    return AVERROR(EIO);
                pkt->stream_index =
                    fourxm->tracks[fourxm->selected_track].stream_index;
                pkt->pts = fourxm->audio_pts;
                packet_read = 1;

                /* pts accounting */
                audio_frame_count = size;
                if (fourxm->tracks[fourxm->selected_track].adpcm)
                    audio_frame_count -=
                        2 * (fourxm->tracks[fourxm->selected_track].channels);
                audio_frame_count /=
                      fourxm->tracks[fourxm->selected_track].channels;
                if (fourxm->tracks[fourxm->selected_track].adpcm)
                    audio_frame_count *= 2;
                else
                    audio_frame_count /=
                    (fourxm->tracks[fourxm->selected_track].bits / 8);
                fourxm->audio_pts += audio_frame_count;

            } else {
                url_fseek(pb, size, SEEK_CUR);
            }
            break;

        default:
            url_fseek(pb, size, SEEK_CUR);
            break;
        }
    }
    return ret;
}
示例#22
0
/* mmf input */
static int mmf_read_header(AVFormatContext *s,
                           AVFormatParameters *ap)
{
    MMFContext *mmf = s->priv_data;
    unsigned int tag;
    ByteIOContext *pb = &s->pb;
    AVStream *st;
    offset_t file_size, size;
    int rate, params;

    tag = get_le32(pb);
    if (tag != MKTAG('M', 'M', 'M', 'D'))
        return -1;
    file_size = get_be32(pb);

    /* Skip some unused chunks that may or may not be present */
    for(;; url_fseek(pb, size, SEEK_CUR)) {
        tag = get_le32(pb);
        size = get_be32(pb);
        if(tag == MKTAG('C','N','T','I')) continue;
        if(tag == MKTAG('O','P','D','A')) continue;
        break;
    }

    /* Tag = "ATRx", where "x" = track number */
    if ((tag & 0xffffff) == MKTAG('M', 'T', 'R', 0)) {
        av_log(s, AV_LOG_ERROR, "MIDI like format found, unsupported\n");
        return -1;
    }
    if ((tag & 0xffffff) != MKTAG('A', 'T', 'R', 0)) {
        av_log(s, AV_LOG_ERROR, "Unsupported SMAF chunk %08x\n", tag);
        return -1;
    }

    get_byte(pb); /* format type */
    get_byte(pb); /* sequence type */
    params = get_byte(pb); /* (channel << 7) | (format << 4) | rate */
    rate = mmf_rate(params & 0x0f);
    if(rate  < 0) {
        av_log(s, AV_LOG_ERROR, "Invalid sample rate\n");
        return -1;
    }
    get_byte(pb); /* wave base bit */
    get_byte(pb); /* time base d */
    get_byte(pb); /* time base g */

    /* Skip some unused chunks that may or may not be present */
    for(;; url_fseek(pb, size, SEEK_CUR)) {
        tag = get_le32(pb);
        size = get_be32(pb);
        if(tag == MKTAG('A','t','s','q')) continue;
        if(tag == MKTAG('A','s','p','I')) continue;
        break;
    }

    /* Make sure it's followed by an Awa chunk, aka wave data */
    if ((tag & 0xffffff) != MKTAG('A', 'w', 'a', 0)) {
        av_log(s, AV_LOG_ERROR, "Unexpected SMAF chunk %08x\n", tag);
        return -1;
    }
    mmf->data_size = size;

    st = av_new_stream(s, 0);
    if (!st)
        return AVERROR_NOMEM;

    st->codec->codec_type = CODEC_TYPE_AUDIO;
    st->codec->codec_id = CODEC_ID_ADPCM_YAMAHA;
    st->codec->sample_rate = rate;
    st->codec->channels = 1;
    st->codec->bits_per_sample = 4;
    st->codec->bit_rate = st->codec->sample_rate * st->codec->bits_per_sample;

    av_set_pts_info(st, 64, 1, st->codec->sample_rate);

    return 0;
}
static void ape_parse_tag(AVFormatContext *s)
{
    ByteIOContext *pb = s->pb;
    int file_size = url_fsize(pb);
    uint32_t val, fields, tag_bytes;
    uint8_t buf[8];
    int i;

    if (file_size < APE_TAG_FOOTER_BYTES)
        return;

    url_fseek(pb, file_size - APE_TAG_FOOTER_BYTES, SEEK_SET);

    get_buffer(pb, buf, 8);    /* APETAGEX */
    if (strncmp(buf, "APETAGEX", 8)) {
        return;
    }

    val = get_le32(pb);        /* APE tag version */
    if (val > APE_TAG_VERSION) {
        av_log(s, AV_LOG_ERROR, "Unsupported tag version. (>=%d)\n", APE_TAG_VERSION);
        return;
    }

    tag_bytes = get_le32(pb);  /* tag size */
    if (tag_bytes - APE_TAG_FOOTER_BYTES > (1024 * 1024 * 16)) {
        av_log(s, AV_LOG_ERROR, "Tag size is way too big\n");
        return;
    }

    fields = get_le32(pb);     /* number of fields */
    if (fields > 65536) {
        av_log(s, AV_LOG_ERROR, "Too many tag fields (%d)\n", fields);
        return;
    }

    val = get_le32(pb);        /* flags */
    if (val & APE_TAG_FLAG_IS_HEADER) {
        av_log(s, AV_LOG_ERROR, "APE Tag is a header\n");
        return;
    }

    if (val & APE_TAG_FLAG_CONTAINS_HEADER)
        tag_bytes += 2*APE_TAG_FOOTER_BYTES;

    url_fseek(pb, file_size - tag_bytes, SEEK_SET);

    for (i=0; i<fields; i++)
        ape_tag_read_field(s);

#if ENABLE_DEBUG
    av_log(s, AV_LOG_DEBUG, "\nAPE Tags:\n\n");
    av_log(s, AV_LOG_DEBUG, "title     = %s\n", s->title);
    av_log(s, AV_LOG_DEBUG, "author    = %s\n", s->author);
    av_log(s, AV_LOG_DEBUG, "copyright = %s\n", s->copyright);
    av_log(s, AV_LOG_DEBUG, "comment   = %s\n", s->comment);
    av_log(s, AV_LOG_DEBUG, "album     = %s\n", s->album);
    av_log(s, AV_LOG_DEBUG, "year      = %d\n", s->year);
    av_log(s, AV_LOG_DEBUG, "track     = %d\n", s->track);
    av_log(s, AV_LOG_DEBUG, "genre     = %s\n", s->genre);
#endif
}
示例#24
0
/*
* Process EA file header
* Returns 1 if the EA file is valid and successfully opened, 0 otherwise
*/
int CEASpliterFilter::process_header() {
	uint32_t blockid, size = 0;
	int i;
	EaDemuxContext *ea = (EaDemuxContext *)m_pea;
	
	for (i=0; i<5 && (!ea->audio_codec || !ea->video_codec); i++) {
		unsigned int startpos = m_pFile->GetPos();
		int err = 0;

		blockid = get_le32(pb);
		av_log(s, AV_LOG_ERROR, " %x\n", blockid);

		size = get_le32(pb);
		if (i == 0)
			ea->big_endian = size > 0x000FFFFF;
		if (ea->big_endian)
			size = bswap_32(size);

		switch (blockid) {
			case ISNh_TAG:
				if (m_pFile->BitRead(32) != EACS_TAG) {
					av_log (s, AV_LOG_ERROR, "unknown 1SNh headerid\n");
					return 0;
				}
				err = process_audio_header_eacs();
				break;

			case SCHl_TAG :
			case SHEN_TAG :
				blockid = get_le32(pb);
				if (blockid == GSTR_TAG) {
					url_fskip(pb, 4);
				} else if ((blockid & 0xFFFF)!=PT00_TAG) {
					av_log (s, AV_LOG_ERROR, "unknown SCHl headerid %x\n", blockid);
					return 0;
				}
				err = process_audio_header_elements();
				break;

			case SEAD_TAG:
				err = process_audio_header_sead();
				break;

			case MVIh_TAG :
				ea->video_codec = CODEC_ID_CMV;
				ea->time_base.num = 0;
				ea->time_base.den = 0;

				break;

			case kVGT_TAG:
				ea->video_codec = CODEC_ID_TGV;
				ea->time_base.num = 0;
				ea->time_base.den = 0;

				break;

			case mTCD_TAG :
				err = process_video_header_mdec();
				break;

			case MPCh_TAG:
				ea->video_codec = CODEC_ID_MPEG2VIDEO;
				break;

			case pQGT_TAG:
			case TGQs_TAG:
				ea->video_codec = CODEC_ID_TGQ;
				break;

			case pIQT_TAG:
				ea->video_codec = CODEC_ID_TQI;
				break;

			case MADk_TAG :
				ea->video_codec = CODEC_ID_MAD;
				break;

			case MVhd_TAG :
				err = process_video_header_vp6();
				break;
			default:
				av_log(s, AV_LOG_ERROR, "error parsing header: %x\n", blockid);
				break;
		}

		if (err < 0) {
			av_log(s, AV_LOG_ERROR, "error parsing header: %i\n", err);
			return err;
		}

		//url_fseek(pb, startpos + size, SEEK_SET);
		m_pFile->Seek( startpos + size);
	}

	//url_fseek(pb, 0, SEEK_SET);
	m_pFile->Seek(0);

	return 1;
}
示例#25
0
static void get_spc_xid6( byte const* begin, long size, track_info_t* out )
{
	// header
	byte const* end = begin + size;
	if ( size < 8 || memcmp( begin, "xid6", 4 ) )
	{
		check( false );
		return;
	}
	long info_size = get_le32( begin + 4 );
	byte const* in = begin + 8; 
	if ( end - in > info_size )
	{
		ddprintf( "Extra data after SPC xid6 info\n" );
		end = in + info_size;
	}
	
	int year = 0;
	char copyright [256 + 5];
	int copyright_len = 0;
	int const year_len = 5;
	
	while ( end - in >= 4 )
	{
		// header
		int id   = in [0];
		int data = in [3] * 0x100 + in [2];
		int type = in [1];
		int len  = type ? data : 0;
		in += 4;
		if ( len > end - in )
		{
			check( false );
			break; // block goes past end of data
		}
		
		// handle specific block types
		char* field = 0;
		switch ( id )
		{
			case 0x01: field = out->song;    break;
			case 0x02: field = out->game;    break;
			case 0x03: field = out->author;  break;
			case 0x04: field = out->dumper;  break;
			case 0x07: field = out->comment; break;
			case 0x14: year = data;          break;
			
			//case 0x30: // intro length
			// Many SPCs have intro length set wrong for looped tracks, making it useless
			/*
			case 0x30:
				check( len == 4 );
				if ( len >= 4 )
				{
					out->intro_length = get_le32( in ) / 64;
					if ( out->length > 0 )
					{
						long loop = out->length - out->intro_length;
						if ( loop >= 2000 )
							out->loop_length = loop;
					}
				}
				break;
			*/
			
			case 0x13:
				copyright_len = min( len, (int) sizeof copyright - year_len );
				memcpy( &copyright [year_len], in, copyright_len );
				break;
			
			default:
				if ( id < 0x01 || (id > 0x07 && id < 0x10) ||
						(id > 0x14 && id < 0x30) || id > 0x36 )
					ddprintf( "Unknown SPC xid6 block: %X\n", (int) id );
				break;
		}
		if ( field )
		{
			check( type == 1 );
			Gme_File::copy_field_( field, (char const*) in, len );
		}
		
		// skip to next block
		in += len;
		
		// blocks are supposed to be 4-byte aligned with zero-padding...
		byte const* unaligned = in;
		while ( (in - begin) & 3 && in < end )
		{
			if ( *in++ != 0 )
			{
				// ...but some files have no padding
				in = unaligned;
				ddprintf( "SPC info tag wasn't properly padded to align\n" );
				break;
			}
		}
	}
	
	char* p = &copyright [year_len];
	if ( year )
	{
		*--p = ' ';
		for ( int n = 4; n--; )
		{
			*--p = char (year % 10 + '0');
			year /= 10;
		}
		copyright_len += year_len;
	}
	if ( copyright_len )
		Gme_File::copy_field_( out->copyright, p, copyright_len );
	
	check( in == end );
}
示例#26
0
int CEASpliterFilter::ea_read_packet()
{
	EaDemuxContext *ea = (EaDemuxContext *)m_pea;
	AVPacket *pkt = (AVPacket *)m_pkt;
	//ByteIOContext *pb = s->pb;
	int ret = 0;
	int packet_read = 0;
	unsigned int chunk_type, chunk_size;
	int key = 0;
	int av_uninit(num_samples);

	while (!packet_read) {
		chunk_type = get_le32(pb);
		chunk_size = (ea->big_endian ? get_be32(pb) : get_le32(pb)) - 8;

		switch (chunk_type) {
			/* audio data */
		case ISNh_TAG:
			/* header chunk also contains data; skip over the header portion*/
			url_fskip(pb, 32);
			chunk_size -= 32;
		case ISNd_TAG:
		case SCDl_TAG:
		case SNDC_TAG:
		case SDEN_TAG:
			if (!ea->audio_codec) {
				url_fskip(pb, chunk_size);
				break;
			} else if (ea->audio_codec == CODEC_ID_PCM_S16LE_PLANAR ||
				ea->audio_codec == CODEC_ID_MP3) {
					num_samples = get_le32(pb);
					url_fskip(pb, 8);
					chunk_size -= 12;
			}
			ret = eav_get_packet(  chunk_size);
			if (ret < 0)
				return ret;
			pkt->stream_index = ea->audio_stream_index;
			pkt->pts = 90000;
			pkt->pts *= ea->audio_frame_counter;
			pkt->pts /= ea->sample_rate;

			switch (ea->audio_codec) {
		case CODEC_ID_ADPCM_EA:
			/* 2 samples/byte, 1 or 2 samples per frame depending
			* on stereo; chunk also has 12-byte header */
			ea->audio_frame_counter += ((chunk_size - 12) * 2) /
				ea->num_channels;
			break;
		case CODEC_ID_PCM_S16LE_PLANAR:
		case CODEC_ID_MP3:
			ea->audio_frame_counter += num_samples;
			break;
		default:
			ea->audio_frame_counter += chunk_size /
				(ea->bytes * ea->num_channels);
			}

			packet_read = 1;
			break;

			/* ending tag */
		case 0:
		case ISNe_TAG:
		case SCEl_TAG:
		case SEND_TAG:
		case SEEN_TAG:
			ret = AVERROR(EIO);
			packet_read = 1;
			break;

		case MVIh_TAG:
		case kVGT_TAG:
		case pQGT_TAG:
		case TGQs_TAG:
		case MADk_TAG:
			key = PKT_FLAG_KEY;
		case MVIf_TAG:
		case fVGT_TAG:
		case MADm_TAG:
		case MADe_TAG:
			url_fseek(pb, -8, SEEK_CUR);     // include chunk preamble
			chunk_size += 8;
			goto get_video_packet;

		case mTCD_TAG:
			url_fseek(pb, 8, SEEK_CUR);  // skip ea dct header
			chunk_size -= 8;
			goto get_video_packet;

		case MV0K_TAG:
		case MPCh_TAG:
		case pIQT_TAG:
			key = PKT_FLAG_KEY;
		case MV0F_TAG:
get_video_packet:
			ret = eav_get_packet( chunk_size);
			if (ret < 0)
				return ret;
			pkt->stream_index = ea->video_stream_index;
			pkt->flags |= key;
			packet_read = 1;
			break;

		default:
			url_fseek(pb, chunk_size, SEEK_CUR);
			break;
		}
	}

	return ret;
}
示例#27
0
文件: c93.c 项目: DocOnDev/mythtv
static int read_packet(AVFormatContext *s, AVPacket *pkt)
{
    ByteIOContext *pb = s->pb;
    C93DemuxContext *c93 = s->priv_data;
    C93BlockRecord *br = &c93->block_records[c93->current_block];
    int datasize;
    int ret, i;

    if (c93->next_pkt_is_audio) {
        c93->current_frame++;
        c93->next_pkt_is_audio = 0;
        datasize = get_le16(pb);
        if (datasize > 42) {
            if (!c93->audio) {
                c93->audio = av_new_stream(s, 1);
                if (!c93->audio)
                    return AVERROR(ENOMEM);
                c93->audio->codec->codec_type = AVMEDIA_TYPE_AUDIO;
            }
            url_fskip(pb, 26); /* VOC header */
            ret = voc_get_packet(s, pkt, c93->audio, datasize - 26);
            if (ret > 0) {
                pkt->stream_index = 1;
                pkt->flags |= AV_PKT_FLAG_KEY;
                return ret;
            }
        }
    }
    if (c93->current_frame >= br->frames) {
        if (c93->current_block >= 511 || !br[1].length)
            return AVERROR(EIO);
        br++;
        c93->current_block++;
        c93->current_frame = 0;
    }

    if (c93->current_frame == 0) {
        url_fseek(pb, br->index * 2048, SEEK_SET);
        for (i = 0; i < 32; i++) {
            c93->frame_offsets[i] = get_le32(pb);
        }
    }

    url_fseek(pb,br->index * 2048 +
            c93->frame_offsets[c93->current_frame], SEEK_SET);
    datasize = get_le16(pb); /* video frame size */

    ret = av_new_packet(pkt, datasize + 768 + 1);
    if (ret < 0)
        return ret;
    pkt->data[0] = 0;
    pkt->size = datasize + 1;

    ret = get_buffer(pb, pkt->data + 1, datasize);
    if (ret < datasize) {
        ret = AVERROR(EIO);
        goto fail;
    }

    datasize = get_le16(pb); /* palette size */
    if (datasize) {
        if (datasize != 768) {
            av_log(s, AV_LOG_ERROR, "invalid palette size %u\n", datasize);
            ret = AVERROR_INVALIDDATA;
            goto fail;
        }
        pkt->data[0] |= C93_HAS_PALETTE;
        ret = get_buffer(pb, pkt->data + pkt->size, datasize);
        if (ret < datasize) {
            ret = AVERROR(EIO);
            goto fail;
        }
        pkt->size += 768;
    }
    pkt->stream_index = 0;
    c93->next_pkt_is_audio = 1;

    /* only the first frame is guaranteed to not reference previous frames */
    if (c93->current_block == 0 && c93->current_frame == 0) {
        pkt->flags |= AV_PKT_FLAG_KEY;
        pkt->data[0] |= C93_FIRST_FRAME;
    }
    return 0;

    fail:
    av_free_packet(pkt);
    return ret;
}
示例#28
0
文件: p_unix.cpp 项目: sincoder/upx
void PackUnix::unpack(OutputFile *fo)
{
    unsigned szb_info = sizeof(b_info);
    {
        Elf32_Ehdr ehdr;
        fi->seek(0, SEEK_SET);
        fi->readx(&ehdr, sizeof(ehdr));
        unsigned const e_entry = get_te32(&ehdr.e_entry);
        if (e_entry < 0x401180) { /* old style, 8-byte b_info */
            szb_info = 2*sizeof(unsigned);
        }
        else {
            Elf32_Phdr phdr;
            fi->seek(get_te32(&ehdr.e_phoff), SEEK_SET);
            fi->readx(&phdr, sizeof(phdr));
            unsigned const p_vaddr = get_te32(&phdr.p_vaddr);
            if (0x80==(e_entry - p_vaddr)) { /* 1.22 old style */
                szb_info = 2*sizeof(unsigned);
            }
        }
    }

    unsigned c_adler = upx_adler32(NULL, 0);
    unsigned u_adler = upx_adler32(NULL, 0);

    // defaults for ph.version == 8
    unsigned orig_file_size = 0;
    blocksize = 512 * 1024;

    fi->seek(overlay_offset, SEEK_SET);
    if (ph.version > 8)
    {
        p_info hbuf;
        fi->readx(&hbuf, sizeof(hbuf));
        orig_file_size = get_te32(&hbuf.p_filesize);
        blocksize = get_te32(&hbuf.p_blocksize);

        if (file_size > (off_t)orig_file_size || blocksize > orig_file_size)
            throwCantUnpack("file header corrupted");
    }
    else
    {
        // skip 4 bytes (program id)
        fi->seek(4, SEEK_CUR);
    }

    ibuf.alloc(blocksize + OVERHEAD);

    // decompress blocks
    unsigned total_in = 0;
    unsigned total_out = 0;
    b_info bhdr; memset(&bhdr, 0, sizeof(bhdr));
    for (;;)
    {
#define buf ibuf
        int i;
        unsigned sz_unc, sz_cpr;

        fi->readx(&bhdr, szb_info);
        ph.u_len = sz_unc = get_te32(&bhdr.sz_unc);
        ph.c_len = sz_cpr = get_te32(&bhdr.sz_cpr);

        if (sz_unc == 0)                   // uncompressed size 0 -> EOF
        {
            // note: must reload sz_cpr as magic is always stored le32
            sz_cpr = get_le32(&bhdr.sz_cpr);
            if (sz_cpr != UPX_MAGIC_LE32)  // sz_cpr must be h->magic
                throwCompressedDataViolation();
            break;
        }
        if (sz_unc <= 0 || sz_cpr <= 0)
            throwCompressedDataViolation();
        if (sz_cpr > sz_unc || sz_unc > blocksize)
            throwCompressedDataViolation();

        i = blocksize + OVERHEAD - sz_cpr;
        fi->readx(buf+i, sz_cpr);
        // update checksum of compressed data
        c_adler = upx_adler32(buf + i, sz_cpr, c_adler);
        // decompress
        if (sz_cpr < sz_unc) {
            decompress(buf+i, buf, false);
            if (0!=bhdr.b_ftid) {
                Filter ft(ph.level);
                ft.init(bhdr.b_ftid);
                ft.cto = bhdr.b_cto8;
                ft.unfilter(buf, sz_unc);
            }
            i = 0;
        }
        // update checksum of uncompressed data
        u_adler = upx_adler32(buf + i, sz_unc, u_adler);
        total_in  += sz_cpr;
        total_out += sz_unc;
        // write block
        if (fo)
            fo->write(buf + i, sz_unc);
#undef buf
    }

    // update header with totals
    ph.c_len = total_in;
    ph.u_len = total_out;

    // all bytes must be written
    if (ph.version > 8 && total_out != orig_file_size)
        throwEOFException();

    // finally test the checksums
   // if (ph.c_adler != c_adler || ph.u_adler != u_adler)
    //    throwChecksumError();
}
示例#29
0
文件: smacker.c 项目: AndyA/ffmbc
static int smacker_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
    ByteIOContext *pb = s->pb;
    SmackerContext *smk = s->priv_data;
    AVStream *st, *ast[7];
    int i, ret;
    int tbase;

    /* read and check header */
    smk->magic = get_le32(pb);
    if (smk->magic != MKTAG('S', 'M', 'K', '2') && smk->magic != MKTAG('S', 'M', 'K', '4'))
        return -1;
    smk->width = get_le32(pb);
    smk->height = get_le32(pb);
    smk->frames = get_le32(pb);
    smk->pts_inc = (int32_t)get_le32(pb);
    smk->flags = get_le32(pb);
    if(smk->flags & SMACKER_FLAG_RING_FRAME)
        smk->frames++;
    for(i = 0; i < 7; i++)
        smk->audio[i] = get_le32(pb);
    smk->treesize = get_le32(pb);

    if(smk->treesize >= UINT_MAX/4){ // smk->treesize + 16 must not overflow (this check is probably redundant)
        av_log(s, AV_LOG_ERROR, "treesize too large\n");
        return -1;
    }

//FIXME remove extradata "rebuilding"
    smk->mmap_size = get_le32(pb);
    smk->mclr_size = get_le32(pb);
    smk->full_size = get_le32(pb);
    smk->type_size = get_le32(pb);
    for(i = 0; i < 7; i++)
        smk->rates[i] = get_le32(pb);
    smk->pad = get_le32(pb);
    /* setup data */
    if(smk->frames > 0xFFFFFF) {
        av_log(s, AV_LOG_ERROR, "Too many frames: %i\n", smk->frames);
        return -1;
    }
    smk->frm_size = av_malloc(smk->frames * 4);
    smk->frm_flags = av_malloc(smk->frames);

    smk->is_ver4 = (smk->magic != MKTAG('S', 'M', 'K', '2'));

    /* read frame info */
    for(i = 0; i < smk->frames; i++) {
        smk->frm_size[i] = get_le32(pb);
    }
    for(i = 0; i < smk->frames; i++) {
        smk->frm_flags[i] = get_byte(pb);
    }

    /* init video codec */
    st = av_new_stream(s, 0);
    if (!st)
        return -1;
    smk->videoindex = st->index;
    st->codec->width = smk->width;
    st->codec->height = smk->height;
    st->codec->pix_fmt = PIX_FMT_PAL8;
    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    st->codec->codec_id = CODEC_ID_SMACKVIDEO;
    st->codec->codec_tag = smk->magic;
    /* Smacker uses 100000 as internal timebase */
    if(smk->pts_inc < 0)
        smk->pts_inc = -smk->pts_inc;
    else
        smk->pts_inc *= 100;
    tbase = 100000;
    av_reduce(&tbase, &smk->pts_inc, tbase, smk->pts_inc, (1UL<<31)-1);
    av_set_pts_info(st, 33, smk->pts_inc, tbase);
    st->duration = smk->frames;
    /* handle possible audio streams */
    for(i = 0; i < 7; i++) {
        smk->indexes[i] = -1;
        if(smk->rates[i] & 0xFFFFFF){
            ast[i] = av_new_stream(s, 0);
            smk->indexes[i] = ast[i]->index;
            ast[i]->codec->codec_type = AVMEDIA_TYPE_AUDIO;
            if (smk->rates[i] & SMK_AUD_BINKAUD) {
                ast[i]->codec->codec_id = CODEC_ID_BINKAUDIO_RDFT;
            } else if (smk->rates[i] & SMK_AUD_USEDCT) {
                ast[i]->codec->codec_id = CODEC_ID_BINKAUDIO_DCT;
            } else if (smk->rates[i] & SMK_AUD_PACKED){
                ast[i]->codec->codec_id = CODEC_ID_SMACKAUDIO;
                ast[i]->codec->codec_tag = MKTAG('S', 'M', 'K', 'A');
            } else {
                ast[i]->codec->codec_id = CODEC_ID_PCM_U8;
            }
            ast[i]->codec->channels = (smk->rates[i] & SMK_AUD_STEREO) ? 2 : 1;
            ast[i]->codec->sample_rate = smk->rates[i] & 0xFFFFFF;
            ast[i]->codec->bits_per_coded_sample = (smk->rates[i] & SMK_AUD_16BITS) ? 16 : 8;
            if(ast[i]->codec->bits_per_coded_sample == 16 && ast[i]->codec->codec_id == CODEC_ID_PCM_U8)
                ast[i]->codec->codec_id = CODEC_ID_PCM_S16LE;
            av_set_pts_info(ast[i], 64, 1, ast[i]->codec->sample_rate
                    * ast[i]->codec->channels * ast[i]->codec->bits_per_coded_sample / 8);
        }
    }


    /* load trees to extradata, they will be unpacked by decoder */
    st->codec->extradata = av_malloc(smk->treesize + 16);
    st->codec->extradata_size = smk->treesize + 16;
    if(!st->codec->extradata){
        av_log(s, AV_LOG_ERROR, "Cannot allocate %i bytes of extradata\n", smk->treesize + 16);
        av_free(smk->frm_size);
        av_free(smk->frm_flags);
        return -1;
    }
    ret = get_buffer(pb, st->codec->extradata + 16, st->codec->extradata_size - 16);
    if(ret != st->codec->extradata_size - 16){
        av_free(smk->frm_size);
        av_free(smk->frm_flags);
        return AVERROR(EIO);
    }
    ((int32_t*)st->codec->extradata)[0] = av_le2ne32(smk->mmap_size);
    ((int32_t*)st->codec->extradata)[1] = av_le2ne32(smk->mclr_size);
    ((int32_t*)st->codec->extradata)[2] = av_le2ne32(smk->full_size);
    ((int32_t*)st->codec->extradata)[3] = av_le2ne32(smk->type_size);

    smk->curstream = -1;
    smk->nextpos = url_ftell(pb);

    return 0;
}
示例#30
0
文件: tta.c 项目: allweax/ffmpeg-msvc
static int tta_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
    TTAContext *c = s->priv_data;
    AVStream *st;
    int i, channels, bps, samplerate, datalen, framelen;
    uint64_t framepos, start_offset;

    ff_id3v2_read(s);
    if (!av_metadata_get(s->metadata, "", NULL, AV_METADATA_IGNORE_SUFFIX))
        ff_id3v1_read(s);

    start_offset = url_ftell(s->pb);
    if (get_le32(s->pb) != AV_RL32("TTA1"))
        return -1; // not tta file

    url_fskip(s->pb, 2); // FIXME: flags
    channels = get_le16(s->pb);
    bps = get_le16(s->pb);
    samplerate = get_le32(s->pb);
    if(samplerate <= 0 || samplerate > 1000000){
        av_log(s, AV_LOG_ERROR, "nonsense samplerate\n");
        return -1;
    }

    datalen = get_le32(s->pb);
    if(datalen < 0){
        av_log(s, AV_LOG_ERROR, "nonsense datalen\n");
        return -1;
    }

    url_fskip(s->pb, 4); // header crc

    framelen = samplerate*256/245;
    c->totalframes = datalen / framelen + ((datalen % framelen) ? 1 : 0);
    c->currentframe = 0;

    if(c->totalframes >= UINT_MAX/sizeof(uint32_t)){
        av_log(s, AV_LOG_ERROR, "totalframes too large\n");
        return -1;
    }

    st = av_new_stream(s, 0);
    if (!st)
        return AVERROR(ENOMEM);

    av_set_pts_info(st, 64, 1, samplerate);
    st->start_time = 0;
    st->duration = datalen;

    framepos = url_ftell(s->pb) + 4*c->totalframes + 4;

    for (i = 0; i < c->totalframes; i++) {
        uint32_t size = get_le32(s->pb);
        av_add_index_entry(st, framepos, i*framelen, size, 0, AVINDEX_KEYFRAME);
        framepos += size;
    }
    url_fskip(s->pb, 4); // seektable crc

    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
    st->codec->codec_id = CODEC_ID_TTA;
    st->codec->channels = channels;
    st->codec->sample_rate = samplerate;
    st->codec->bits_per_coded_sample = bps;

    st->codec->extradata_size = url_ftell(s->pb) - start_offset;
    if(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE <= (unsigned)st->codec->extradata_size){
        //this check is redundant as get_buffer should fail
        av_log(s, AV_LOG_ERROR, "extradata_size too large\n");
        return -1;
    }
    st->codec->extradata = av_mallocz(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE);
    url_fseek(s->pb, start_offset, SEEK_SET);
    get_buffer(s->pb, st->codec->extradata, st->codec->extradata_size);

    return 0;
}