예제 #1
0
/* Process EA file header.
 * Return 1 if the EA file is valid and successfully opened, 0 otherwise. */
static int process_ea_header(AVFormatContext *s)
{
    uint32_t blockid, size = 0;
    EaDemuxContext *ea = s->priv_data;
    AVIOContext *pb    = s->pb;
    int i;

    for (i = 0; i < 5 && (!ea->audio_codec || !ea->video.codec); i++) {
        uint64_t startpos     = avio_tell(pb);
        int err               = 0;

        blockid = avio_rl32(pb);
        size    = avio_rl32(pb);
        if (i == 0)
            ea->big_endian = size > av_bswap32(size);
        if (ea->big_endian)
            size = av_bswap32(size);

        if (size < 8) {
            av_log(s, AV_LOG_ERROR, "chunk size too small\n");
            return AVERROR_INVALIDDATA;
        }

        switch (blockid) {
        case ISNh_TAG:
            if (avio_rl32(pb) != EACS_TAG) {
                avpriv_request_sample(s, "unknown 1SNh headerid");
                return 0;
            }
            process_audio_header_eacs(s);
            break;

        case SCHl_TAG:
        case SHEN_TAG:
            blockid = avio_rl32(pb);
            if (blockid == GSTR_TAG) {
                avio_skip(pb, 4);
            } else if ((blockid & 0xFF) != (PT00_TAG & 0xFF)) {
                blockid = avio_rl32(pb);
            }
            ea->platform = (blockid >> 16) & 0xFF;
            err = process_audio_header_elements(s);
            break;

        case SEAD_TAG:
            process_audio_header_sead(s);
            break;

        case MVIh_TAG:
            process_video_header_cmv(s, &ea->video);
            break;

        case kVGT_TAG:
            ea->video.codec = AV_CODEC_ID_TGV;
            break;

        case mTCD_TAG:
            process_video_header_mdec(s, &ea->video);
            break;

        case MPCh_TAG:
            ea->video.codec = AV_CODEC_ID_MPEG2VIDEO;
            break;

        case pQGT_TAG:
        case TGQs_TAG:
            ea->video.codec = AV_CODEC_ID_TGQ;
            ea->video.time_base   = (AVRational) { 1, 15 };
            break;

        case pIQT_TAG:
            ea->video.codec = AV_CODEC_ID_TQI;
            ea->video.time_base   = (AVRational) { 1, 15 };
            break;

        case MADk_TAG:
            ea->video.codec = AV_CODEC_ID_MAD;
            avio_skip(pb, 6);
            ea->video.time_base = (AVRational) { avio_rl16(pb), 1000 };
            break;

        case MVhd_TAG:
            err = process_video_header_vp6(s, &ea->video);
            break;

        case AVhd_TAG:
            err = process_video_header_vp6(s, &ea->alpha);
            break;
        }

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

        avio_seek(pb, startpos + size, SEEK_SET);
    }

    avio_seek(pb, 0, SEEK_SET);

    return 1;
}
예제 #2
0
/* Process EA file header.
 * Return 1 if the EA file is valid and successfully opened, 0 otherwise. */
static int process_ea_header(AVFormatContext *s)
{
    uint32_t blockid, size = 0;
    EaDemuxContext *ea = s->priv_data;
    AVIOContext *pb    = s->pb;
    int i;

    for (i = 0; i < 5 && (!ea->audio_codec || !ea->video_codec); i++) {
        unsigned int startpos = avio_tell(pb);
        int err               = 0;

        blockid = avio_rl32(pb);
        size    = avio_rl32(pb);
        if (i == 0)
            ea->big_endian = size > 0x000FFFFF;
        if (ea->big_endian)
            size = av_bswap32(size);

        switch (blockid) {
        case ISNh_TAG:
            if (avio_rl32(pb) != EACS_TAG) {
                avpriv_request_sample(s, "unknown 1SNh headerid");
                return 0;
            }
            process_audio_header_eacs(s);
            break;

        case SCHl_TAG:
        case SHEN_TAG:
            blockid = avio_rl32(pb);
            if (blockid == GSTR_TAG) {
                avio_skip(pb, 4);
            } else if ((blockid & 0xFFFF) != PT00_TAG) {
                avpriv_request_sample(s, "unknown SCHl headerid");
                return 0;
            }
            err = process_audio_header_elements(s);
            break;

        case SEAD_TAG:
            process_audio_header_sead(s);
            break;

        case MVIh_TAG:
            process_video_header_cmv(s);
            break;

        case kVGT_TAG:
            ea->video_codec = AV_CODEC_ID_TGV;
            break;

        case mTCD_TAG:
            process_video_header_mdec(s);
            break;

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

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

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

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

        case MVhd_TAG:
            err = process_video_header_vp6(s);
            break;
        }

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

        avio_seek(pb, startpos + size, SEEK_SET);
    }

    avio_seek(pb, 0, SEEK_SET);

    return 1;
}