Exemple #1
0
/* first is true if we read the frame header */
static int ffm_read_data(AVFormatContext *s,
                         uint8_t *buf, int size, int header)
{
    FFMContext *ffm = s->priv_data;
    AVIOContext *pb = s->pb;
    int len, fill_size, size1, frame_offset, id;
    int64_t last_pos = -1;

    size1 = size;
    while (size > 0) {
    redo:
        len = ffm->packet_end - ffm->packet_ptr;
        if (len < 0)
            return -1;
        if (len > size)
            len = size;
        if (len == 0) {
            if (avio_tell(pb) == ffm->file_size)
                avio_seek(pb, ffm->packet_size, SEEK_SET);
    retry_read:
            if (pb->buffer_size != ffm->packet_size) {
                int64_t tell = avio_tell(pb);
                ffio_set_buf_size(pb, ffm->packet_size);
                avio_seek(pb, tell, SEEK_SET);
            }
            id = avio_rb16(pb); /* PACKET_ID */
            if (id != PACKET_ID) {
                if (ffm_resync(s, id) < 0)
                    return -1;
                last_pos = avio_tell(pb);
            }
            fill_size = avio_rb16(pb);
            ffm->dts = avio_rb64(pb);
            frame_offset = avio_rb16(pb);
            avio_read(pb, ffm->packet, ffm->packet_size - FFM_HEADER_SIZE);
            ffm->packet_end = ffm->packet + (ffm->packet_size - FFM_HEADER_SIZE - fill_size);
            if (ffm->packet_end < ffm->packet || frame_offset < 0)
                return -1;
            /* if first packet or resynchronization packet, we must
               handle it specifically */
            if (ffm->first_packet || (frame_offset & 0x8000)) {
                if (!frame_offset) {
                    /* This packet has no frame headers in it */
                    if (avio_tell(pb) >= ffm->packet_size * 3LL) {
                        int64_t seekback = FFMIN(ffm->packet_size * 2LL, avio_tell(pb) - last_pos);
                        seekback = FFMAX(seekback, 0);
                        avio_seek(pb, -seekback, SEEK_CUR);
                        goto retry_read;
                    }
                    /* This is bad, we cannot find a valid frame header */
                    return 0;
                }
                ffm->first_packet = 0;
                if ((frame_offset & 0x7fff) < FFM_HEADER_SIZE)
                    return -1;
                ffm->packet_ptr = ffm->packet + (frame_offset & 0x7fff) - FFM_HEADER_SIZE;
                if (!header)
                    break;
            } else {
                ffm->packet_ptr = ffm->packet;
            }
            goto redo;
        }
        memcpy(buf, ffm->packet_ptr, len);
        buf += len;
        ffm->packet_ptr += len;
        size -= len;
        header = 0;
    }
    return size1 - size;
}
Exemple #2
0
static int flv_write_header(AVFormatContext *s)
{
    AVIOContext *pb = s->pb;
    FLVContext *flv = s->priv_data;
    AVCodecContext *audio_enc = NULL, *video_enc = NULL;
    int i, metadata_count = 0;
    double framerate = 0.0;
    int64_t metadata_size_pos, data_size, metadata_count_pos;
    AVDictionaryEntry *tag = NULL;

    for(i=0; i<s->nb_streams; i++){
        AVCodecContext *enc = s->streams[i]->codec;
        FLVStreamContext *sc;
        if (enc->codec_type == AVMEDIA_TYPE_VIDEO) {
            if (s->streams[i]->r_frame_rate.den && s->streams[i]->r_frame_rate.num) {
                framerate = av_q2d(s->streams[i]->r_frame_rate);
            } else {
                framerate = 1/av_q2d(s->streams[i]->codec->time_base);
            }
            video_enc = enc;
            if(enc->codec_tag == 0) {
                av_log(enc, AV_LOG_ERROR, "video codec not compatible with flv\n");
                return -1;
            }
        } else {
            audio_enc = enc;
            if(get_audio_flags(enc)<0)
                return -1;
        }
        avpriv_set_pts_info(s->streams[i], 32, 1, 1000); /* 32 bit pts in ms */

        sc = av_mallocz(sizeof(FLVStreamContext));
        if (!sc)
            return AVERROR(ENOMEM);
        s->streams[i]->priv_data = sc;
        sc->last_ts = -1;
    }
    flv->delay = AV_NOPTS_VALUE;

    avio_write(pb, "FLV", 3);
    avio_w8(pb,1);
    avio_w8(pb,   FLV_HEADER_FLAG_HASAUDIO * !!audio_enc
                 + FLV_HEADER_FLAG_HASVIDEO * !!video_enc);
    avio_wb32(pb,9);
    avio_wb32(pb,0);

    for(i=0; i<s->nb_streams; i++){
        if(s->streams[i]->codec->codec_tag == 5){
            avio_w8(pb,8); // message type
            avio_wb24(pb,0); // include flags
            avio_wb24(pb,0); // time stamp
            avio_wb32(pb,0); // reserved
            avio_wb32(pb,11); // size
            flv->reserved=5;
        }
    }

    /* write meta_tag */
    avio_w8(pb, 18);         // tag type META
    metadata_size_pos= avio_tell(pb);
    avio_wb24(pb, 0);          // size of data part (sum of all parts below)
    avio_wb24(pb, 0);          // time stamp
    avio_wb32(pb, 0);          // reserved

    /* now data of data_size size */

    /* first event name as a string */
    avio_w8(pb, AMF_DATA_TYPE_STRING);
    put_amf_string(pb, "onMetaData"); // 12 bytes

    /* mixed array (hash) with size and string/type/data tuples */
    avio_w8(pb, AMF_DATA_TYPE_MIXEDARRAY);
    metadata_count_pos = avio_tell(pb);
    metadata_count = 5*!!video_enc + 5*!!audio_enc + 2; // +2 for duration and file size
    avio_wb32(pb, metadata_count);

    put_amf_string(pb, "duration");
    flv->duration_offset= avio_tell(pb);
    put_amf_double(pb, s->duration / AV_TIME_BASE); // fill in the guessed duration, it'll be corrected later if incorrect

    if(video_enc){
        put_amf_string(pb, "width");
        put_amf_double(pb, video_enc->width);

        put_amf_string(pb, "height");
        put_amf_double(pb, video_enc->height);

        put_amf_string(pb, "videodatarate");
        put_amf_double(pb, video_enc->bit_rate / 1024.0);

        put_amf_string(pb, "framerate");
        put_amf_double(pb, framerate);

        put_amf_string(pb, "videocodecid");
        put_amf_double(pb, video_enc->codec_tag);
    }

    if(audio_enc){
        put_amf_string(pb, "audiodatarate");
        put_amf_double(pb, audio_enc->bit_rate / 1024.0);

        put_amf_string(pb, "audiosamplerate");
        put_amf_double(pb, audio_enc->sample_rate);

        put_amf_string(pb, "audiosamplesize");
        put_amf_double(pb, audio_enc->codec_id == CODEC_ID_PCM_U8 ? 8 : 16);

        put_amf_string(pb, "stereo");
        put_amf_bool(pb, audio_enc->channels == 2);

        put_amf_string(pb, "audiocodecid");
        put_amf_double(pb, audio_enc->codec_tag);
    }

    while ((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
        put_amf_string(pb, tag->key);
        avio_w8(pb, AMF_DATA_TYPE_STRING);
        put_amf_string(pb, tag->value);
        metadata_count++;
    }

    put_amf_string(pb, "filesize");
    flv->filesize_offset= avio_tell(pb);
    put_amf_double(pb, 0); // delayed write

    put_amf_string(pb, "");
    avio_w8(pb, AMF_END_OF_OBJECT);

    /* write total size of tag */
    data_size= avio_tell(pb) - metadata_size_pos - 10;

    avio_seek(pb, metadata_count_pos, SEEK_SET);
    avio_wb32(pb, metadata_count);

    avio_seek(pb, metadata_size_pos, SEEK_SET);
    avio_wb24(pb, data_size);
    avio_skip(pb, data_size + 10 - 3);
    avio_wb32(pb, data_size + 11);

    for (i = 0; i < s->nb_streams; i++) {
        AVCodecContext *enc = s->streams[i]->codec;
        if (enc->codec_id == CODEC_ID_AAC || enc->codec_id == CODEC_ID_H264) {
            int64_t pos;
            avio_w8(pb, enc->codec_type == AVMEDIA_TYPE_VIDEO ?
                     FLV_TAG_TYPE_VIDEO : FLV_TAG_TYPE_AUDIO);
            avio_wb24(pb, 0); // size patched later
            avio_wb24(pb, 0); // ts
            avio_w8(pb, 0); // ts ext
            avio_wb24(pb, 0); // streamid
            pos = avio_tell(pb);
            if (enc->codec_id == CODEC_ID_AAC) {
                avio_w8(pb, get_audio_flags(enc));
                avio_w8(pb, 0); // AAC sequence header
                avio_write(pb, enc->extradata, enc->extradata_size);
            } else {
                avio_w8(pb, enc->codec_tag | FLV_FRAME_KEY); // flags
                avio_w8(pb, 0); // AVC sequence header
                avio_wb24(pb, 0); // composition time
                ff_isom_write_avcc(pb, enc->extradata, enc->extradata_size);
            }
            data_size = avio_tell(pb) - pos;
            avio_seek(pb, -data_size - 10, SEEK_CUR);
            avio_wb24(pb, data_size);
            avio_skip(pb, data_size + 10 - 3);
            avio_wb32(pb, data_size + 11); // previous tag size
        }
    }

    return 0;
}
Exemple #3
0
static int64_t seek_by_sector(AVIOContext *pb, int64_t sector, int64_t offset)
{
    return avio_seek(pb, (sector << WTV_SECTOR_BITS) + offset, SEEK_SET);
}
Exemple #4
0
static int read_header(AVFormatContext *s)
{
    AVIOContext *pb = s->pb;
    CaffContext *caf  = s->priv_data;
    AVStream *st;
    uint32_t tag = 0;
    int found_data, ret;
    int64_t size;

    avio_skip(pb, 8); /* magic, version, file flags */

    /* audio description chunk */
    if (avio_rb32(pb) != MKBETAG('d','e','s','c')) {
        av_log(s, AV_LOG_ERROR, "desc chunk not present\n");
        return AVERROR_INVALIDDATA;
    }
    size = avio_rb64(pb);
    if (size != 32)
        return AVERROR_INVALIDDATA;

    ret = read_desc_chunk(s);
    if (ret)
        return ret;
    st = s->streams[0];

    /* parse each chunk */
    found_data = 0;
    while (!pb->eof_reached) {

        /* stop at data chunk if seeking is not supported or
           data chunk size is unknown */
        if (found_data && (caf->data_size < 0 || !pb->seekable))
            break;

        tag  = avio_rb32(pb);
        size = avio_rb64(pb);
        if (pb->eof_reached)
            break;

        switch (tag) {
        case MKBETAG('d','a','t','a'):
            avio_skip(pb, 4); /* edit count */
            caf->data_start = avio_tell(pb);
            caf->data_size  = size < 0 ? -1 : size - 4;
            if (caf->data_size > 0 && pb->seekable)
                avio_skip(pb, caf->data_size);
            found_data = 1;
            break;

        case MKBETAG('c','h','a','n'):
            if ((ret = ff_mov_read_chan(s, s->pb, st, size)) < 0)
                return ret;
            break;

        /* magic cookie chunk */
        case MKBETAG('k','u','k','i'):
            if (read_kuki_chunk(s, size))
                return AVERROR_INVALIDDATA;
            break;

        /* packet table chunk */
        case MKBETAG('p','a','k','t'):
            if (read_pakt_chunk(s, size))
                return AVERROR_INVALIDDATA;
            break;

        case MKBETAG('i','n','f','o'):
            read_info_chunk(s, size);
            break;

        default:
#define _(x) ((x) >= ' ' ? (x) : ' ')
            av_log(s, AV_LOG_WARNING,
                   "skipping CAF chunk: %08"PRIX32" (%"PRIu8"%"PRIu8"%"PRIu8"%"PRIu8")\n",
                tag, _(tag>>24), _((tag>>16)&0xFF), _((tag>>8)&0xFF), _(tag&0xFF));
#undef _
        case MKBETAG('f','r','e','e'):
            if (size < 0)
                return AVERROR_INVALIDDATA;
            avio_skip(pb, size);
            break;
        }
    }

    if (!found_data)
        return AVERROR_INVALIDDATA;

    if (caf->bytes_per_packet > 0 && caf->frames_per_packet > 0) {
        if (caf->data_size > 0)
            st->nb_frames = (caf->data_size / caf->bytes_per_packet) * caf->frames_per_packet;
    } else if (st->nb_index_entries) {
        st->codec->bit_rate = st->codec->sample_rate * caf->data_size * 8 /
                              st->duration;
    } else {
        av_log(s, AV_LOG_ERROR, "Missing packet table. It is required when "
                                "block size or frame size are variable.\n");
        return AVERROR_INVALIDDATA;
    }

    avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
    st->start_time = 0;

    /* position the stream at the start of data */
    if (caf->data_size >= 0)
        avio_seek(pb, caf->data_start, SEEK_SET);

    return 0;
}
Exemple #5
0
static int rm_read_header(AVFormatContext *s)
{
    RMDemuxContext *rm = s->priv_data;
    AVStream *st;
    AVIOContext *pb = s->pb;
    unsigned int tag;
    int tag_size;
    unsigned int start_time, duration;
    unsigned int data_off = 0, indx_off = 0;
    char buf[128], mime[128];
    int flags = 0;

    tag = avio_rl32(pb);
    if (tag == MKTAG('.', 'r', 'a', 0xfd)) {
        /* very old .ra format */
        return rm_read_header_old(s);
    } else if (tag != MKTAG('.', 'R', 'M', 'F')) {
        return AVERROR(EIO);
    }

    tag_size = avio_rb32(pb);
    avio_skip(pb, tag_size - 8);

    for(;;) {
        if (avio_feof(pb))
            return -1;
        tag = avio_rl32(pb);
        tag_size = avio_rb32(pb);
        avio_rb16(pb);
        av_dlog(s, "tag=%c%c%c%c (%08x) size=%d\n",
                (tag      ) & 0xff,
                (tag >>  8) & 0xff,
                (tag >> 16) & 0xff,
                (tag >> 24) & 0xff,
                tag,
                tag_size);
        if (tag_size < 10 && tag != MKTAG('D', 'A', 'T', 'A'))
            return -1;
        switch(tag) {
        case MKTAG('P', 'R', 'O', 'P'):
            /* file header */
            avio_rb32(pb); /* max bit rate */
            avio_rb32(pb); /* avg bit rate */
            avio_rb32(pb); /* max packet size */
            avio_rb32(pb); /* avg packet size */
            avio_rb32(pb); /* nb packets */
            duration = avio_rb32(pb); /* duration */
            s->duration = av_rescale(duration, AV_TIME_BASE, 1000);
            avio_rb32(pb); /* preroll */
            indx_off = avio_rb32(pb); /* index offset */
            data_off = avio_rb32(pb); /* data offset */
            avio_rb16(pb); /* nb streams */
            flags = avio_rb16(pb); /* flags */
            break;
        case MKTAG('C', 'O', 'N', 'T'):
            rm_read_metadata(s, pb, 1);
            break;
        case MKTAG('M', 'D', 'P', 'R'):
            st = avformat_new_stream(s, NULL);
            if (!st)
                return AVERROR(ENOMEM);
            st->id = avio_rb16(pb);
            avio_rb32(pb); /* max bit rate */
            st->codec->bit_rate = avio_rb32(pb); /* bit rate */
            avio_rb32(pb); /* max packet size */
            avio_rb32(pb); /* avg packet size */
            start_time = avio_rb32(pb); /* start time */
            avio_rb32(pb); /* preroll */
            duration = avio_rb32(pb); /* duration */
            st->start_time = start_time;
            st->duration = duration;
            if(duration>0)
                s->duration = AV_NOPTS_VALUE;
            get_str8(pb, buf, sizeof(buf)); /* desc */
            get_str8(pb, mime, sizeof(mime)); /* mimetype */
            st->codec->codec_type = AVMEDIA_TYPE_DATA;
            st->priv_data = ff_rm_alloc_rmstream();
            if (ff_rm_read_mdpr_codecdata(s, s->pb, st, st->priv_data,
                                          avio_rb32(pb), mime) < 0)
                return -1;
            break;
        case MKTAG('D', 'A', 'T', 'A'):
            goto header_end;
        default:
            /* unknown tag: skip it */
            avio_skip(pb, tag_size - 10);
            break;
        }
    }
 header_end:
    rm->nb_packets = avio_rb32(pb); /* number of packets */
    if (!rm->nb_packets && (flags & 4))
        rm->nb_packets = 3600 * 25;
    avio_rb32(pb); /* next data header */

    if (!data_off)
        data_off = avio_tell(pb) - 18;
    if (indx_off && pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX) &&
        avio_seek(pb, indx_off, SEEK_SET) >= 0) {
        rm_read_index(s);
        avio_seek(pb, data_off + 18, SEEK_SET);
    }

    return 0;
}
Exemple #6
0
static int ipmovie_read_header(AVFormatContext *s)
{
    IPMVEContext *ipmovie = s->priv_data;
    AVIOContext *pb = s->pb;
    AVPacket pkt;
    AVStream *st;
    unsigned char chunk_preamble[CHUNK_PREAMBLE_SIZE];
    int chunk_type, i;
    uint8_t signature_buffer[sizeof(signature)];

    avio_read(pb, signature_buffer, sizeof(signature_buffer));
    while (memcmp(signature_buffer, signature, sizeof(signature))) {
        memmove(signature_buffer, signature_buffer + 1, sizeof(signature_buffer) - 1);
        signature_buffer[sizeof(signature_buffer) - 1] = avio_r8(pb);
        if (url_feof(pb))
            return AVERROR_EOF;
    }
    /* initialize private context members */
    ipmovie->video_pts = ipmovie->audio_frame_count = 0;
    ipmovie->audio_chunk_offset = ipmovie->video_chunk_offset =
    ipmovie->decode_map_chunk_offset = 0;

    /* on the first read, this will position the stream at the first chunk */
    ipmovie->next_chunk_offset = avio_tell(pb) + 4;

    for (i = 0; i < 256; i++)
        ipmovie->palette[i] = 0xFFU << 24;

    /* process the first chunk which should be CHUNK_INIT_VIDEO */
    if (process_ipmovie_chunk(ipmovie, pb, &pkt) != CHUNK_INIT_VIDEO)
        return AVERROR_INVALIDDATA;

    /* peek ahead to the next chunk-- if it is an init audio chunk, process
     * it; if it is the first video chunk, this is a silent file */
    if (avio_read(pb, chunk_preamble, CHUNK_PREAMBLE_SIZE) !=
        CHUNK_PREAMBLE_SIZE)
        return AVERROR(EIO);
    chunk_type = AV_RL16(&chunk_preamble[2]);
    avio_seek(pb, -CHUNK_PREAMBLE_SIZE, SEEK_CUR);

    if (chunk_type == CHUNK_VIDEO)
        ipmovie->audio_type = AV_CODEC_ID_NONE;  /* no audio */
    else if (process_ipmovie_chunk(ipmovie, pb, &pkt) != CHUNK_INIT_AUDIO)
        return AVERROR_INVALIDDATA;

    /* initialize the stream decoders */
    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);
    avpriv_set_pts_info(st, 63, 1, 1000000);
    ipmovie->video_stream_index = st->index;
    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    st->codec->codec_id = AV_CODEC_ID_INTERPLAY_VIDEO;
    st->codec->codec_tag = 0;  /* no fourcc */
    st->codec->width = ipmovie->video_width;
    st->codec->height = ipmovie->video_height;
    st->codec->bits_per_coded_sample = ipmovie->video_bpp;

    if (ipmovie->audio_type) {
        st = avformat_new_stream(s, NULL);
        if (!st)
            return AVERROR(ENOMEM);
        avpriv_set_pts_info(st, 32, 1, ipmovie->audio_sample_rate);
        ipmovie->audio_stream_index = st->index;
        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
        st->codec->codec_id = ipmovie->audio_type;
        st->codec->codec_tag = 0;  /* no tag */
        st->codec->channels = ipmovie->audio_channels;
        st->codec->sample_rate = ipmovie->audio_sample_rate;
        st->codec->bits_per_coded_sample = ipmovie->audio_bits;
        st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
            st->codec->bits_per_coded_sample;
        if (st->codec->codec_id == AV_CODEC_ID_INTERPLAY_DPCM)
            st->codec->bit_rate /= 2;
        st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;
    }

    return 0;
}
Exemple #7
0
static int ea_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    EaDemuxContext *ea = s->priv_data;
    AVIOContext *pb    = s->pb;
    int partial_packet = 0;
    unsigned int chunk_type, chunk_size;
    int ret = 0, packet_read = 0, key = 0;
    int av_uninit(num_samples);

    while (!packet_read || partial_packet) {
        chunk_type = avio_rl32(pb);
        chunk_size = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb);
        if (chunk_size <= 8)
            return AVERROR_INVALIDDATA;
        chunk_size -= 8;

        switch (chunk_type) {
        /* audio data */
        case ISNh_TAG:
            /* header chunk also contains data; skip over the header portion */
            if (chunk_size < 32)
                return AVERROR_INVALIDDATA;
            avio_skip(pb, 32);
            chunk_size -= 32;
        case ISNd_TAG:
        case SCDl_TAG:
        case SNDC_TAG:
        case SDEN_TAG:
            if (!ea->audio_codec) {
                avio_skip(pb, chunk_size);
                break;
            } else if (ea->audio_codec == AV_CODEC_ID_PCM_S16LE_PLANAR ||
                       ea->audio_codec == AV_CODEC_ID_MP3) {
                num_samples = avio_rl32(pb);
                avio_skip(pb, 8);
                chunk_size -= 12;
            }
            if (partial_packet) {
                avpriv_request_sample(s, "video header followed by audio packet");
                av_free_packet(pkt);
                partial_packet = 0;
            }
            ret = av_get_packet(pb, pkt, chunk_size);
            if (ret < 0)
                return ret;
            pkt->stream_index = ea->audio_stream_index;

            switch (ea->audio_codec) {
            case AV_CODEC_ID_ADPCM_EA:
            case AV_CODEC_ID_ADPCM_EA_R1:
            case AV_CODEC_ID_ADPCM_EA_R2:
            case AV_CODEC_ID_ADPCM_IMA_EA_EACS:
            case AV_CODEC_ID_ADPCM_EA_R3:
                if (pkt->size < 4) {
                    av_log(s, AV_LOG_ERROR, "Packet is too short\n");
                    av_free_packet(pkt);
                    return AVERROR_INVALIDDATA;
                }
                if (ea->audio_codec == AV_CODEC_ID_ADPCM_EA_R3)
                    pkt->duration = AV_RB32(pkt->data);
                else
                    pkt->duration = AV_RL32(pkt->data);
                break;
            case AV_CODEC_ID_ADPCM_IMA_EA_SEAD:
                pkt->duration = ret * 2 / ea->num_channels;
                break;
            case AV_CODEC_ID_PCM_S16LE_PLANAR:
            case AV_CODEC_ID_MP3:
                pkt->duration = num_samples;
                break;
            default:
                pkt->duration = 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 = AV_PKT_FLAG_KEY;
        case MVIf_TAG:
        case fVGT_TAG:
        case MADm_TAG:
        case MADe_TAG:
            avio_seek(pb, -8, SEEK_CUR);    // include chunk preamble
            chunk_size += 8;
            goto get_video_packet;

        case mTCD_TAG:
            avio_skip(pb, 8);               // skip ea DCT header
            chunk_size -= 8;
            goto get_video_packet;

        case MV0K_TAG:
        case MPCh_TAG:
        case pIQT_TAG:
            key = AV_PKT_FLAG_KEY;
        case MV0F_TAG:
get_video_packet:
            if (partial_packet) {
                ret = av_append_packet(pb, pkt, chunk_size);
            } else
                ret = av_get_packet(pb, pkt, chunk_size);
            if (ret < 0) {
                packet_read = 1;
                break;
            }
            partial_packet = chunk_type == MVIh_TAG;
            pkt->stream_index = ea->video_stream_index;
            pkt->flags       |= key;
            packet_read       = 1;
            break;

        default:
            avio_skip(pb, chunk_size);
            break;
        }
    }

    if (ret < 0 && partial_packet)
        av_free_packet(pkt);
    return ret;
}
/**
 * Write an RTP hint (that may contain one or more RTP packets)
 * for the packets in data. data contains one or more packets with a
 * BE32 size header.
 *
 * @param out buffer where the hints are written
 * @param data buffer containing RTP packets
 * @param size the size of the data buffer
 * @param trk the MOVTrack for the hint track
 * @param pts pointer where the timestamp for the written RTP hint is stored
 * @return the number of RTP packets in the written hint
 */
static int write_hint_packets(AVIOContext *out, const uint8_t *data,
                              int size, MOVTrack *trk, int64_t *pts)
{
	int64_t curpos;
	int64_t count_pos, entries_pos;
	int count = 0, entries;

	count_pos = avio_tell(out);
	/* RTPsample header */
	avio_wb16(out, 0); /* packet count */
	avio_wb16(out, 0); /* reserved */

	while (size > 4)
	{
		uint32_t packet_len = AV_RB32(data);
		uint16_t seq;
		uint32_t ts;

		data += 4;
		size -= 4;
		if (packet_len > size || packet_len <= 12)
			break;
		if (data[1] >= 200 && data[1] <= 204)
		{
			/* RTCP packet, just skip */
			data += packet_len;
			size -= packet_len;
			continue;
		}

		if (packet_len > trk->max_packet_size)
			trk->max_packet_size = packet_len;

		seq = AV_RB16(&data[2]);
		ts = AV_RB32(&data[4]);

		if (trk->prev_rtp_ts == 0)
			trk->prev_rtp_ts = ts;
		/* Unwrap the 32-bit RTP timestamp that wraps around often
		 * into a not (as often) wrapping 64-bit timestamp. */
		trk->cur_rtp_ts_unwrapped += (int32_t) (ts - trk->prev_rtp_ts);
		trk->prev_rtp_ts = ts;
		if (*pts == AV_NOPTS_VALUE)
			*pts = trk->cur_rtp_ts_unwrapped;

		count++;
		/* RTPpacket header */
		avio_wb32(out, 0); /* relative_time */
		avio_write(out, data, 2); /* RTP header */
		avio_wb16(out, seq); /* RTPsequenceseed */
		avio_wb16(out, 0); /* reserved + flags */
		entries_pos = avio_tell(out);
		avio_wb16(out, 0); /* entry count */

		data += 12;
		size -= 12;
		packet_len -= 12;

		entries = 0;
		/* Write one or more constructors describing the payload data */
		describe_payload(data, packet_len, out, &entries, &trk->sample_queue);
		data += packet_len;
		size -= packet_len;

		curpos = avio_tell(out);
		avio_seek(out, entries_pos, SEEK_SET);
		avio_wb16(out, entries);
		avio_seek(out, curpos, SEEK_SET);
	}

	curpos = avio_tell(out);
	avio_seek(out, count_pos, SEEK_SET);
	avio_wb16(out, count);
	avio_seek(out, curpos, SEEK_SET);
	return count;
}
Exemple #9
0
/* wav input */
static int wav_read_header(AVFormatContext *s,
                           AVFormatParameters *ap)
{
    int64_t size, av_uninit(data_size);
    int64_t sample_count=0;
    int rf64;
    unsigned int tag;
    AVIOContext *pb = s->pb;
    AVStream *st;
    WAVContext *wav = s->priv_data;

    /* check RIFF header */
    tag = avio_rl32(pb);

    rf64 = tag == MKTAG('R', 'F', '6', '4');
    if (!rf64 && tag != MKTAG('R', 'I', 'F', 'F'))
        return -1;
    avio_rl32(pb); /* file size */
    tag = avio_rl32(pb);
    if (tag != MKTAG('W', 'A', 'V', 'E'))
        return -1;

    if (rf64) {
        if (avio_rl32(pb) != MKTAG('d', 's', '6', '4'))
            return -1;
        size = avio_rl32(pb);
        if (size < 16)
            return -1;
        avio_rl64(pb); /* RIFF size */
        data_size = avio_rl64(pb);
        sample_count = avio_rl64(pb);
        avio_seek(pb, size - 16, SEEK_CUR); /* skip rest of ds64 chunk */
    }

    /* parse fmt header */
    size = find_tag(pb, MKTAG('f', 'm', 't', ' '));
    if (size < 0)
        return -1;
    st = av_new_stream(s, 0);
    if (!st)
        return AVERROR(ENOMEM);

    ff_get_wav_header(pb, st->codec, size);
    st->need_parsing = AVSTREAM_PARSE_FULL;

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

    for (;;) {
        if (url_feof(pb))
            return -1;
        size = next_tag(pb, &tag);
        if (tag == MKTAG('d', 'a', 't', 'a')){
            break;
        }else if (tag == MKTAG('f','a','c','t') && !sample_count){
            sample_count = avio_rl32(pb);
            size -= 4;
        }
        avio_seek(pb, size, SEEK_CUR);
    }
    if (rf64)
        size = data_size;
    if (size < 0)
        return -1;
    if (!size) {
        wav->data_end = INT64_MAX;
    } else
        wav->data_end= avio_tell(pb) + size;

    if (!sample_count && st->codec->channels && av_get_bits_per_sample(st->codec->codec_id))
        sample_count = (size<<3) / (st->codec->channels * (uint64_t)av_get_bits_per_sample(st->codec->codec_id));
    if (sample_count)
        st->duration = sample_count;
    return 0;
}
Exemple #10
0
static int rpl_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
    AVIOContext *pb = s->pb;
    RPLContext *rpl = s->priv_data;
    AVStream *vst = NULL, *ast = NULL;
    int total_audio_size;
    int error = 0;

    uint32_t i;

    int32_t audio_format, chunk_catalog_offset, number_of_chunks;
    AVRational fps;

    char line[RPL_LINE_LENGTH];

    // The header for RPL/ARMovie files is 21 lines of text
    // containing the various header fields.  The fields are always
    // in the same order, and other text besides the first
    // number usually isn't important.
    // (The spec says that there exists some significance
    // for the text in a few cases; samples needed.)
    error |= read_line(pb, line, sizeof(line));      // ARMovie
    error |= read_line(pb, line, sizeof(line));      // movie name
    av_dict_set(&s->metadata, "title"    , line, 0);
    error |= read_line(pb, line, sizeof(line));      // date/copyright
    av_dict_set(&s->metadata, "copyright", line, 0);
    error |= read_line(pb, line, sizeof(line));      // author and other
    av_dict_set(&s->metadata, "author"   , line, 0);

    // video headers
    vst = av_new_stream(s, 0);
    if (!vst)
        return AVERROR(ENOMEM);
    vst->codec->codec_type      = AVMEDIA_TYPE_VIDEO;
    vst->codec->codec_tag       = read_line_and_int(pb, &error);  // video format
    vst->codec->width           = read_line_and_int(pb, &error);  // video width
    vst->codec->height          = read_line_and_int(pb, &error);  // video height
    vst->codec->bits_per_coded_sample = read_line_and_int(pb, &error);  // video bits per sample
    error |= read_line(pb, line, sizeof(line));                   // video frames per second
    fps = read_fps(line, &error);
    av_set_pts_info(vst, 32, fps.den, fps.num);

    // Figure out the video codec
    switch (vst->codec->codec_tag) {
#if 0
        case 122:
            vst->codec->codec_id = CODEC_ID_ESCAPE122;
            break;
#endif
        case 124:
            vst->codec->codec_id = CODEC_ID_ESCAPE124;
            // The header is wrong here, at least sometimes
            vst->codec->bits_per_coded_sample = 16;
            break;
#if 0
        case 130:
            vst->codec->codec_id = CODEC_ID_ESCAPE130;
            break;
#endif
        default:
            av_log(s, AV_LOG_WARNING,
                   "RPL video format %i not supported yet!\n",
                   vst->codec->codec_tag);
            vst->codec->codec_id = CODEC_ID_NONE;
    }

    // Audio headers

    // ARMovie supports multiple audio tracks; I don't have any
    // samples, though. This code will ignore additional tracks.
    audio_format = read_line_and_int(pb, &error);  // audio format ID
    if (audio_format) {
        ast = av_new_stream(s, 0);
        if (!ast)
            return AVERROR(ENOMEM);
        ast->codec->codec_type      = AVMEDIA_TYPE_AUDIO;
        ast->codec->codec_tag       = audio_format;
        ast->codec->sample_rate     = read_line_and_int(pb, &error);  // audio bitrate
        ast->codec->channels        = read_line_and_int(pb, &error);  // number of audio channels
        ast->codec->bits_per_coded_sample = read_line_and_int(pb, &error);  // audio bits per sample
        // At least one sample uses 0 for ADPCM, which is really 4 bits
        // per sample.
        if (ast->codec->bits_per_coded_sample == 0)
            ast->codec->bits_per_coded_sample = 4;

        ast->codec->bit_rate = ast->codec->sample_rate *
                               ast->codec->bits_per_coded_sample *
                               ast->codec->channels;

        ast->codec->codec_id = CODEC_ID_NONE;
        switch (audio_format) {
            case 1:
                if (ast->codec->bits_per_coded_sample == 16) {
                    // 16-bit audio is always signed
                    ast->codec->codec_id = CODEC_ID_PCM_S16LE;
                    break;
                }
                // There are some other formats listed as legal per the spec;
                // samples needed.
                break;
            case 101:
                if (ast->codec->bits_per_coded_sample == 8) {
                    // The samples with this kind of audio that I have
                    // are all unsigned.
                    ast->codec->codec_id = CODEC_ID_PCM_U8;
                    break;
                } else if (ast->codec->bits_per_coded_sample == 4) {
                    ast->codec->codec_id = CODEC_ID_ADPCM_IMA_EA_SEAD;
                    break;
                }
                break;
        }
        if (ast->codec->codec_id == CODEC_ID_NONE) {
            av_log(s, AV_LOG_WARNING,
                   "RPL audio format %i not supported yet!\n",
                   audio_format);
        }
        av_set_pts_info(ast, 32, 1, ast->codec->bit_rate);
    } else {
        for (i = 0; i < 3; i++)
            error |= read_line(pb, line, sizeof(line));
    }

    rpl->frames_per_chunk = read_line_and_int(pb, &error);  // video frames per chunk
    if (rpl->frames_per_chunk > 1 && vst->codec->codec_tag != 124)
        av_log(s, AV_LOG_WARNING,
               "Don't know how to split frames for video format %i. "
               "Video stream will be broken!\n", vst->codec->codec_tag);

    number_of_chunks = read_line_and_int(pb, &error);  // number of chunks in the file
    // The number in the header is actually the index of the last chunk.
    number_of_chunks++;

    error |= read_line(pb, line, sizeof(line));  // "even" chunk size in bytes
    error |= read_line(pb, line, sizeof(line));  // "odd" chunk size in bytes
    chunk_catalog_offset =                       // offset of the "chunk catalog"
        read_line_and_int(pb, &error);           //   (file index)
    error |= read_line(pb, line, sizeof(line));  // offset to "helpful" sprite
    error |= read_line(pb, line, sizeof(line));  // size of "helpful" sprite
    error |= read_line(pb, line, sizeof(line));  // offset to key frame list

    // Read the index
    avio_seek(pb, chunk_catalog_offset, SEEK_SET);
    total_audio_size = 0;
    for (i = 0; i < number_of_chunks; i++) {
        int64_t offset, video_size, audio_size;
        error |= read_line(pb, line, sizeof(line));
        if (3 != sscanf(line, "%"PRId64" , %"PRId64" ; %"PRId64,
                        &offset, &video_size, &audio_size))
            error = -1;
        av_add_index_entry(vst, offset, i * rpl->frames_per_chunk,
                           video_size, rpl->frames_per_chunk, 0);
        if (ast)
            av_add_index_entry(ast, offset + video_size, total_audio_size,
                               audio_size, audio_size * 8, 0);
        total_audio_size += audio_size * 8;
    }

    if (error) return AVERROR(EIO);

    return 0;
}
Exemple #11
0
static int rpl_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    RPLContext *rpl = s->priv_data;
    AVIOContext *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 (avio_seek(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;

        avio_skip(pb, 4); /* flags */
        frame_size = avio_rl32(pb);
        if (avio_seek(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;
}
Exemple #12
0
static int thp_read_header(AVFormatContext *s,
                           AVFormatParameters *ap)
{
    ThpDemuxContext *thp = (ThpDemuxContext *)s->priv_data;
    AVStream *st;
    AVIOContext *pb = s->pb;
    int64_t fsize= avio_size(pb);
    int i;

    /* Read the file header.  */
                           avio_rb32(pb); /* Skip Magic.  */
    thp->version         = avio_rb32(pb);

                           avio_rb32(pb); /* Max buf size.  */
                           avio_rb32(pb); /* Max samples.  */

    thp->fps             = av_d2q(av_int2float(avio_rb32(pb)), INT_MAX);
    thp->framecnt        = avio_rb32(pb);
    thp->first_framesz   = avio_rb32(pb);
    pb->maxsize          = avio_rb32(pb);
    if(fsize>0 && (!pb->maxsize || fsize < pb->maxsize))
        pb->maxsize= fsize;

    thp->compoff         = avio_rb32(pb);
                           avio_rb32(pb); /* offsetDataOffset.  */
    thp->first_frame     = avio_rb32(pb);
    thp->last_frame      = avio_rb32(pb);

    thp->next_framesz    = thp->first_framesz;
    thp->next_frame      = thp->first_frame;

    /* Read the component structure.  */
    avio_seek (pb, thp->compoff, SEEK_SET);
    thp->compcount       = avio_rb32(pb);

    /* Read the list of component types.  */
    avio_read(pb, thp->components, 16);

    for (i = 0; i < thp->compcount; i++) {
        if (thp->components[i] == 0) {
            if (thp->vst != 0)
                break;

            /* Video component.  */
            st = avformat_new_stream(s, NULL);
            if (!st)
                return AVERROR(ENOMEM);

            /* The denominator and numerator are switched because 1/fps
               is required.  */
            avpriv_set_pts_info(st, 64, thp->fps.den, thp->fps.num);
            st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
            st->codec->codec_id = CODEC_ID_THP;
            st->codec->codec_tag = 0;  /* no fourcc */
            st->codec->width = avio_rb32(pb);
            st->codec->height = avio_rb32(pb);
            st->codec->sample_rate = av_q2d(thp->fps);
            thp->vst = st;
            thp->video_stream_index = st->index;

            if (thp->version == 0x11000)
                avio_rb32(pb); /* Unknown.  */
        } else if (thp->components[i] == 1) {
            if (thp->has_audio != 0)
                break;

            /* Audio component.  */
            st = avformat_new_stream(s, NULL);
            if (!st)
                return AVERROR(ENOMEM);

            st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
            st->codec->codec_id = CODEC_ID_ADPCM_THP;
            st->codec->codec_tag = 0;  /* no fourcc */
            st->codec->channels    = avio_rb32(pb); /* numChannels.  */
            st->codec->sample_rate = avio_rb32(pb); /* Frequency.  */

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

            thp->audio_stream_index = st->index;
            thp->has_audio = 1;
        }
    }

    return 0;
}
Exemple #13
0
static int mpjpeg_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    int size;
    int ret;

    MPJPEGDemuxContext *mpjpeg = s->priv_data;
    if (mpjpeg->boundary == NULL) {
        uint8_t* boundary = NULL;
        if (mpjpeg->strict_mime_boundary) {
            boundary = mpjpeg_get_boundary(s->pb);
        }
        if (boundary != NULL) {
            mpjpeg->boundary = boundary;
            mpjpeg->searchstr = av_asprintf( "\r\n%s\r\n", boundary );
        } else {
            mpjpeg->boundary = av_strdup("--");
            mpjpeg->searchstr = av_strdup("\r\n--");
        }
        if (!mpjpeg->boundary || !mpjpeg->searchstr) {
            av_freep(&mpjpeg->boundary);
            av_freep(&mpjpeg->searchstr);
            return AVERROR(ENOMEM);
        }
        mpjpeg->searchstr_len = strlen(mpjpeg->searchstr);
    }

    ret = parse_multipart_header(s->pb, &size, mpjpeg->boundary, s);


    if (ret < 0)
        return ret;

    if (size > 0) {
        /* size has been provided to us in MIME header */
        ret = av_get_packet(s->pb, pkt, size);
    } else {
        /* no size was given -- we read until the next boundary or end-of-file */
        int remaining = 0, len;

        const int read_chunk = 2048;
        av_init_packet(pkt);
        pkt->data = NULL;
        pkt->size = 0;
        pkt->pos  = avio_tell(s->pb);

        /* we may need to return as much as all we've read back to the buffer */
        ffio_ensure_seekback(s->pb, read_chunk);

        while ((ret = av_append_packet(s->pb, pkt, read_chunk - remaining)) >= 0) {
            /* scan the new data */
            char *start;

            len = ret + remaining;
            start = pkt->data + pkt->size - len;
            do {
                if (!memcmp(start, mpjpeg->searchstr, mpjpeg->searchstr_len)) {
                    // got the boundary! rewind the stream
                    avio_seek(s->pb, -(len-2), SEEK_CUR);
                    pkt->size -= (len-2);
                    return pkt->size;
                }
                len--;
                start++;
            } while (len >= mpjpeg->searchstr_len);
            remaining = len;
        }

        /* error or EOF occurred */
        if (ret == AVERROR_EOF) {
            ret = pkt->size > 0 ? pkt->size : AVERROR_EOF;
        } else {
            av_packet_unref(pkt);
        }
    }

    return ret;
}
Exemple #14
0
static int read_packet(AVFormatContext *s, AVPacket *pkt)
{
    AVIOContext *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 = avio_rl16(pb);
        if (datasize > 42) {
            if (!c93->audio) {
                c93->audio = avformat_new_stream(s, NULL);
                if (!c93->audio)
                    return AVERROR(ENOMEM);
                c93->audio->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
            }
            avio_skip(pb, 26); /* VOC header */
            ret = ff_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_EOF;
        br++;
        c93->current_block++;
        c93->current_frame = 0;
    }

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

    avio_seek(pb,br->index * 2048 +
            c93->frame_offsets[c93->current_frame], SEEK_SET);
    datasize = avio_rl16(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 = avio_read(pb, pkt->data + 1, datasize);
    if (ret < datasize) {
        ret = AVERROR(EIO);
        goto fail;
    }

    datasize = avio_rl16(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 = avio_read(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_packet_unref(pkt);
    return ret;
}
Exemple #15
0
static int gxf_write_umf_media_description(AVFormatContext *s)
{
    GXFContext *gxf = s->priv_data;
    AVIOContext *pb = s->pb;
    int64_t pos;
    int i, j;

    pos = url_ftell(pb);
    gxf->umf_media_offset = pos - gxf->umf_start_offset;
    for (i = 0; i <= s->nb_streams; ++i) {
        GXFStreamContext *sc;
        int64_t startpos, curpos;

        if (i == s->nb_streams)
            sc = &gxf->timecode_track;
        else
            sc = s->streams[i]->priv_data;

        startpos = url_ftell(pb);
        avio_wl16(pb, 0); /* length */
        avio_wl16(pb, sc->media_info);
        avio_wl16(pb, 0); /* reserved */
        avio_wl16(pb, 0); /* reserved */
        avio_wl32(pb, gxf->nb_fields);
        avio_wl32(pb, 0); /* attributes rw, ro */
        avio_wl32(pb, 0); /* mark in */
        avio_wl32(pb, gxf->nb_fields); /* mark out */
        avio_write(pb, ES_NAME_PATTERN, strlen(ES_NAME_PATTERN));
        avio_wb16(pb, sc->media_info);
        for (j = strlen(ES_NAME_PATTERN)+2; j < 88; j++)
            avio_w8(pb, 0);
        avio_wl32(pb, sc->track_type);
        avio_wl32(pb, sc->sample_rate);
        avio_wl32(pb, sc->sample_size);
        avio_wl32(pb, 0); /* reserved */

        if (sc == &gxf->timecode_track)
            gxf_write_umf_media_timecode(pb, sc); /* 8 0bytes */
        else {
            AVStream *st = s->streams[i];
            switch (st->codec->codec_id) {
            case CODEC_ID_MPEG1VIDEO:
            case CODEC_ID_MPEG2VIDEO:
                gxf_write_umf_media_mpeg(pb, st);
                break;
            case CODEC_ID_PCM_S16LE:
                gxf_write_umf_media_audio(pb, sc);
                break;
            case CODEC_ID_DVVIDEO:
                gxf_write_umf_media_dv(pb, sc);
                break;
            }
        }

        curpos = url_ftell(pb);
        avio_seek(pb, startpos, SEEK_SET);
        avio_wl16(pb, curpos - startpos);
        avio_seek(pb, curpos, SEEK_SET);
    }
    return url_ftell(pb) - pos;
}
Exemple #16
0
static int film_read_packet(AVFormatContext *s,
                            AVPacket *pkt)
{
    FilmDemuxContext *film = s->priv_data;
    AVIOContext *pb = s->pb;
    film_sample *sample;
    int ret = 0;
    int i;
    int left, right;

    if (film->current_sample >= film->sample_count)
        return AVERROR(EIO);

    sample = &film->sample_table[film->current_sample];

    /* position the stream (will probably be there anyway) */
    avio_seek(pb, sample->sample_offset, SEEK_SET);

    /* do a special song and dance when loading FILM Cinepak chunks */
    if ((sample->stream == film->video_stream_index) &&
        (film->video_type == CODEC_ID_CINEPAK)) {
        pkt->pos= avio_tell(pb);
        if (av_new_packet(pkt, sample->sample_size))
            return AVERROR(ENOMEM);
        avio_read(pb, pkt->data, sample->sample_size);
    } else if ((sample->stream == film->audio_stream_index) &&
        (film->audio_channels == 2) &&
        (film->audio_type != CODEC_ID_ADPCM_ADX)) {
        /* stereo PCM needs to be interleaved */

        if (av_new_packet(pkt, sample->sample_size))
            return AVERROR(ENOMEM);

        /* make sure the interleave buffer is large enough */
        if (sample->sample_size > film->stereo_buffer_size) {
            av_free(film->stereo_buffer);
            film->stereo_buffer_size = sample->sample_size;
            film->stereo_buffer = av_malloc(film->stereo_buffer_size);
        }

        pkt->pos= avio_tell(pb);
        ret = avio_read(pb, film->stereo_buffer, sample->sample_size);
        if (ret != sample->sample_size)
            ret = AVERROR(EIO);

        left = 0;
        right = sample->sample_size / 2;
        for (i = 0; i < sample->sample_size; ) {
            if (film->audio_bits == 8) {
                pkt->data[i++] = film->stereo_buffer[left++];
                pkt->data[i++] = film->stereo_buffer[right++];
            } else {
                pkt->data[i++] = film->stereo_buffer[left++];
                pkt->data[i++] = film->stereo_buffer[left++];
                pkt->data[i++] = film->stereo_buffer[right++];
                pkt->data[i++] = film->stereo_buffer[right++];
            }
        }
    } else {
        ret= av_get_packet(pb, pkt, sample->sample_size);
        if (ret != sample->sample_size)
            ret = AVERROR(EIO);
    }

    pkt->stream_index = sample->stream;
    pkt->pts = sample->pts;

    film->current_sample++;

    return ret;
}
Exemple #17
0
static int load_ipmovie_packet(IPMVEContext *s, AVIOContext *pb,
    AVPacket *pkt) {

    int chunk_type;

    if (s->audio_chunk_offset && s->audio_channels && s->audio_bits) {
        if (s->audio_type == AV_CODEC_ID_NONE) {
            av_log(NULL, AV_LOG_ERROR, "Can not read audio packet before"
                   "audio codec is known\n");
                return CHUNK_BAD;
        }

        /* adjust for PCM audio by skipping chunk header */
        if (s->audio_type != AV_CODEC_ID_INTERPLAY_DPCM) {
            s->audio_chunk_offset += 6;
            s->audio_chunk_size -= 6;
        }

        avio_seek(pb, s->audio_chunk_offset, SEEK_SET);
        s->audio_chunk_offset = 0;

        if (s->audio_chunk_size != av_get_packet(pb, pkt, s->audio_chunk_size))
            return CHUNK_EOF;

        pkt->stream_index = s->audio_stream_index;
        pkt->pts = s->audio_frame_count;

        /* audio frame maintenance */
        if (s->audio_type != AV_CODEC_ID_INTERPLAY_DPCM)
            s->audio_frame_count +=
            (s->audio_chunk_size / s->audio_channels / (s->audio_bits / 8));
        else
            s->audio_frame_count +=
                (s->audio_chunk_size - 6 - s->audio_channels) / s->audio_channels;

        av_dlog(NULL, "sending audio frame with pts %"PRId64" (%d audio frames)\n",
                pkt->pts, s->audio_frame_count);

        chunk_type = CHUNK_VIDEO;

    } else if (s->decode_map_chunk_offset) {

        /* send both the decode map and the video data together */

        if (av_new_packet(pkt, s->decode_map_chunk_size + s->video_chunk_size))
            return CHUNK_NOMEM;

        if (s->has_palette) {
            uint8_t *pal;

            pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE,
                                          AVPALETTE_SIZE);
            if (pal) {
                memcpy(pal, s->palette, AVPALETTE_SIZE);
                s->has_palette = 0;
            }
        }

        if (s->changed) {
            ff_add_param_change(pkt, 0, 0, 0, s->video_width, s->video_height);
            s->changed = 0;
        }
        pkt->pos= s->decode_map_chunk_offset;
        avio_seek(pb, s->decode_map_chunk_offset, SEEK_SET);
        s->decode_map_chunk_offset = 0;

        if (avio_read(pb, pkt->data, s->decode_map_chunk_size) !=
            s->decode_map_chunk_size) {
            av_free_packet(pkt);
            return CHUNK_EOF;
        }

        avio_seek(pb, s->video_chunk_offset, SEEK_SET);
        s->video_chunk_offset = 0;

        if (avio_read(pb, pkt->data + s->decode_map_chunk_size,
            s->video_chunk_size) != s->video_chunk_size) {
            av_free_packet(pkt);
            return CHUNK_EOF;
        }

        pkt->stream_index = s->video_stream_index;
        pkt->pts = s->video_pts;

        av_dlog(NULL, "sending video frame with pts %"PRId64"\n", pkt->pts);

        s->video_pts += s->frame_pts_inc;

        chunk_type = CHUNK_VIDEO;

    } else {

        avio_seek(pb, s->next_chunk_offset, SEEK_SET);
        chunk_type = CHUNK_DONE;

    }

    return chunk_type;
}
Exemple #18
0
static int dxa_read_header(AVFormatContext *s)
{
    AVIOContext *pb = s->pb;
    DXAContext *c = s->priv_data;
    AVStream *st, *ast;
    uint32_t tag;
    int32_t fps;
    int w, h;
    int num, den;
    int flags;
    int ret;

    tag = avio_rl32(pb);
    if (tag != MKTAG('D', 'E', 'X', 'A'))
        return -1;
    flags = avio_r8(pb);
    c->frames = avio_rb16(pb);
    if(!c->frames){
        av_log(s, AV_LOG_ERROR, "File contains no frames ???\n");
        return -1;
    }

    fps = avio_rb32(pb);
    if(fps > 0){
        den = 1000;
        num = fps;
    }else if (fps < 0){
        den = 100000;
        num = -fps;
    }else{
        den = 10;
        num = 1;
    }
    w = avio_rb16(pb);
    h = avio_rb16(pb);
    c->has_sound = 0;

    st = avformat_new_stream(s, NULL);
    if (!st)
        return -1;

    // Parse WAV data header
    if(avio_rl32(pb) == MKTAG('W', 'A', 'V', 'E')){
        uint32_t size, fsize;
        c->has_sound = 1;
        size = avio_rb32(pb);
        c->vidpos = avio_tell(pb) + size;
        avio_skip(pb, 16);
        fsize = avio_rl32(pb);

        ast = avformat_new_stream(s, NULL);
        if (!ast)
            return -1;
        ret = ff_get_wav_header(pb, ast->codec, fsize);
        if (ret < 0)
            return ret;
        if (ast->codec->sample_rate > 0)
            avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
        // find 'data' chunk
        while(avio_tell(pb) < c->vidpos && !url_feof(pb)){
            tag = avio_rl32(pb);
            fsize = avio_rl32(pb);
            if(tag == MKTAG('d', 'a', 't', 'a')) break;
            avio_skip(pb, fsize);
        }
        c->bpc = (fsize + c->frames - 1) / c->frames;
        if(ast->codec->block_align)
            c->bpc = ((c->bpc + ast->codec->block_align - 1) / ast->codec->block_align) * ast->codec->block_align;
        c->bytes_left = fsize;
        c->wavpos = avio_tell(pb);
        avio_seek(pb, c->vidpos, SEEK_SET);
    }

    /* now we are ready: build format streams */
    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    st->codec->codec_id   = CODEC_ID_DXA;
    st->codec->width      = w;
    st->codec->height     = h;
    av_reduce(&den, &num, den, num, (1UL<<31)-1);
    avpriv_set_pts_info(st, 33, num, den);
    /* flags & 0x80 means that image is interlaced,
     * flags & 0x40 means that image has double height
     * either way set true height
     */
    if(flags & 0xC0){
        st->codec->height >>= 1;
    }
Exemple #19
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;
}
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;

    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) {
        avio_seek(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 */
        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 = avio_r8(s->pb);
            size = size * 4 - 1;
            frame_size -= size;
            frame_size--;
            sz = 0;
            pos = avio_tell(s->pb) + size;
            while(sz < 256){
                t = avio_r8(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 = avio_r8(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[avio_r8(s->pb) & 0x3F];
                    *pal++ = smk_pal[avio_r8(s->pb) & 0x3F];
                    sz++;
                }
            }
            avio_seek(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 = avio_rl32(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 = avio_read(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 = avio_read(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 = avio_tell(s->pb);
    } else {
Exemple #21
0
/* write the header (used two times if non streamed) */
static int asf_write_header1(AVFormatContext *s, int64_t file_size, int64_t data_chunk_size)
{
    ASFContext *asf = s->priv_data;
    AVIOContext *pb = s->pb;
    AVDictionaryEntry *tags[5];
    int header_size, n, extra_size, extra_size2, wav_extra_size, file_time;
    int has_title;
    int metadata_count;
    AVCodecContext *enc;
    int64_t header_offset, cur_pos, hpos;
    int bit_rate;
    int64_t duration;

    ff_metadata_conv(&s->metadata, ff_asf_metadata_conv, NULL);

    tags[0] = av_dict_get(s->metadata, "title"    , NULL, 0);
    tags[1] = av_dict_get(s->metadata, "author"   , NULL, 0);
    tags[2] = av_dict_get(s->metadata, "copyright", NULL, 0);
    tags[3] = av_dict_get(s->metadata, "comment"  , NULL, 0);
    tags[4] = av_dict_get(s->metadata, "rating"   , NULL, 0);

    duration = asf->duration + PREROLL_TIME * 10000;
    has_title = tags[0] || tags[1] || tags[2] || tags[3] || tags[4];
    metadata_count = av_dict_count(s->metadata);

    bit_rate = 0;
    for(n=0;n<s->nb_streams;n++) {
        enc = s->streams[n]->codec;

        avpriv_set_pts_info(s->streams[n], 32, 1, 1000); /* 32 bit pts in ms */

        bit_rate += enc->bit_rate;
    }

    if (asf->is_streamed) {
        put_chunk(s, 0x4824, 0, 0xc00); /* start of stream (length will be patched later) */
    }

    ff_put_guid(pb, &ff_asf_header);
    avio_wl64(pb, -1); /* header length, will be patched after */
    avio_wl32(pb, 3 + has_title + !!metadata_count + s->nb_streams); /* number of chunks in header */
    avio_w8(pb, 1); /* ??? */
    avio_w8(pb, 2); /* ??? */

    /* file header */
    header_offset = avio_tell(pb);
    hpos = put_header(pb, &ff_asf_file_header);
    ff_put_guid(pb, &ff_asf_my_guid);
    avio_wl64(pb, file_size);
    file_time = 0;
    avio_wl64(pb, unix_to_file_time(file_time));
    avio_wl64(pb, asf->nb_packets); /* number of packets */
    avio_wl64(pb, duration); /* end time stamp (in 100ns units) */
    avio_wl64(pb, asf->duration); /* duration (in 100ns units) */
    avio_wl64(pb, PREROLL_TIME); /* start time stamp */
    avio_wl32(pb, (asf->is_streamed || !pb->seekable ) ? 3 : 2); /* ??? */
    avio_wl32(pb, s->packet_size); /* packet size */
    avio_wl32(pb, s->packet_size); /* packet size */
    avio_wl32(pb, bit_rate); /* Nominal data rate in bps */
    end_header(pb, hpos);

    /* unknown headers */
    hpos = put_header(pb, &ff_asf_head1_guid);
    ff_put_guid(pb, &ff_asf_head2_guid);
    avio_wl32(pb, 6);
    avio_wl16(pb, 0);
    end_header(pb, hpos);

    /* title and other infos */
    if (has_title) {
        int len;
        uint8_t *buf;
        AVIOContext *dyn_buf;

        if (avio_open_dyn_buf(&dyn_buf) < 0)
            return AVERROR(ENOMEM);

        hpos = put_header(pb, &ff_asf_comment_header);

        for (n = 0; n < FF_ARRAY_ELEMS(tags); n++) {
            len = tags[n] ? avio_put_str16le(dyn_buf, tags[n]->value) : 0;
            avio_wl16(pb, len);
        }
        len = avio_close_dyn_buf(dyn_buf, &buf);
        avio_write(pb, buf, len);
        av_freep(&buf);
        end_header(pb, hpos);
    }
    if (metadata_count) {
        AVDictionaryEntry *tag = NULL;
        hpos = put_header(pb, &ff_asf_extended_content_header);
        avio_wl16(pb, metadata_count);
        while ((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) {
            put_str16(pb, tag->key);
            avio_wl16(pb, 0);
            put_str16(pb, tag->value);
        }
        end_header(pb, hpos);
    }

    /* stream headers */
    for(n=0;n<s->nb_streams;n++) {
        int64_t es_pos;
        //        ASFStream *stream = &asf->streams[n];

        enc = s->streams[n]->codec;
        asf->streams[n].num = n + 1;
        asf->streams[n].seq = 1;


        switch(enc->codec_type) {
        case AVMEDIA_TYPE_AUDIO:
            wav_extra_size = 0;
            extra_size = 18 + wav_extra_size;
            extra_size2 = 8;
            break;
        default:
        case AVMEDIA_TYPE_VIDEO:
            wav_extra_size = enc->extradata_size;
            extra_size = 0x33 + wav_extra_size;
            extra_size2 = 0;
            break;
        }

        hpos = put_header(pb, &ff_asf_stream_header);
        if (enc->codec_type == AVMEDIA_TYPE_AUDIO) {
            ff_put_guid(pb, &ff_asf_audio_stream);
            ff_put_guid(pb, &ff_asf_audio_conceal_spread);
        } else {
            ff_put_guid(pb, &ff_asf_video_stream);
            ff_put_guid(pb, &ff_asf_video_conceal_none);
        }
        avio_wl64(pb, 0); /* ??? */
        es_pos = avio_tell(pb);
        avio_wl32(pb, extra_size); /* wav header len */
        avio_wl32(pb, extra_size2); /* additional data len */
        avio_wl16(pb, n + 1); /* stream number */
        avio_wl32(pb, 0); /* ??? */

        if (enc->codec_type == AVMEDIA_TYPE_AUDIO) {
            /* WAVEFORMATEX header */
            int wavsize = ff_put_wav_header(pb, enc);

            if (wavsize < 0)
                return -1;
            if (wavsize != extra_size) {
                cur_pos = avio_tell(pb);
                avio_seek(pb, es_pos, SEEK_SET);
                avio_wl32(pb, wavsize); /* wav header len */
                avio_seek(pb, cur_pos, SEEK_SET);
            }
            /* ERROR Correction */
            avio_w8(pb, 0x01);
            if(enc->codec_id == AV_CODEC_ID_ADPCM_G726 || !enc->block_align){
                avio_wl16(pb, 0x0190);
                avio_wl16(pb, 0x0190);
            }else{
                avio_wl16(pb, enc->block_align);
                avio_wl16(pb, enc->block_align);
            }
            avio_wl16(pb, 0x01);
            avio_w8(pb, 0x00);
        } else {
            avio_wl32(pb, enc->width);
            avio_wl32(pb, enc->height);
            avio_w8(pb, 2); /* ??? */
            avio_wl16(pb, 40 + enc->extradata_size); /* size */

            /* BITMAPINFOHEADER header */
            ff_put_bmp_header(pb, enc, ff_codec_bmp_tags, 1);
        }
        end_header(pb, hpos);
    }

    /* media comments */

    hpos = put_header(pb, &ff_asf_codec_comment_header);
    ff_put_guid(pb, &ff_asf_codec_comment1_header);
    avio_wl32(pb, s->nb_streams);
    for(n=0;n<s->nb_streams;n++) {
        AVCodec *p;
        const char *desc;
        int len;
        uint8_t *buf;
        AVIOContext *dyn_buf;

        enc = s->streams[n]->codec;
        p = avcodec_find_encoder(enc->codec_id);

        if(enc->codec_type == AVMEDIA_TYPE_AUDIO)
            avio_wl16(pb, 2);
        else if(enc->codec_type == AVMEDIA_TYPE_VIDEO)
            avio_wl16(pb, 1);
        else
            avio_wl16(pb, -1);

        if(enc->codec_id == AV_CODEC_ID_WMAV2)
            desc = "Windows Media Audio V8";
        else
            desc = p ? p->name : enc->codec_name;

        if ( avio_open_dyn_buf(&dyn_buf) < 0)
            return AVERROR(ENOMEM);

        avio_put_str16le(dyn_buf, desc);
        len = avio_close_dyn_buf(dyn_buf, &buf);
        avio_wl16(pb, len / 2); // "number of characters" = length in bytes / 2

        avio_write(pb, buf, len);
        av_freep(&buf);

        avio_wl16(pb, 0); /* no parameters */


        /* id */
        if (enc->codec_type == AVMEDIA_TYPE_AUDIO) {
            avio_wl16(pb, 2);
            avio_wl16(pb, enc->codec_tag);
        } else {
            avio_wl16(pb, 4);
            avio_wl32(pb, enc->codec_tag);
        }
        if(!enc->codec_tag)
            return -1;
    }
    end_header(pb, hpos);

    /* patch the header size fields */

    cur_pos = avio_tell(pb);
    header_size = cur_pos - header_offset;
    if (asf->is_streamed) {
        header_size += 8 + 30 + 50;

        avio_seek(pb, header_offset - 10 - 30, SEEK_SET);
        avio_wl16(pb, header_size);
        avio_seek(pb, header_offset - 2 - 30, SEEK_SET);
        avio_wl16(pb, header_size);

        header_size -= 8 + 30 + 50;
    }
    header_size += 24 + 6;
    avio_seek(pb, header_offset - 14, SEEK_SET);
    avio_wl64(pb, header_size);
    avio_seek(pb, cur_pos, SEEK_SET);

    /* movie chunk, followed by packets of packet_size */
    asf->data_offset = cur_pos;
    ff_put_guid(pb, &ff_asf_data_header);
    avio_wl64(pb, data_chunk_size);
    ff_put_guid(pb, &ff_asf_my_guid);
    avio_wl64(pb, asf->nb_packets); /* nb packets */
    avio_w8(pb, 1); /* ??? */
    avio_w8(pb, 1); /* ??? */
    return 0;
}
static int cmf_parser_next_slice(AVFormatContext *s, int *index, int first)
{
    int i, j, ret=-1;
    struct cmf *bs = s->priv_data;
    struct cmfvpb *oldvpb = bs->cmfvpb;
    struct cmfvpb *newvpb = NULL;
    AVInputFormat *in_fmt = NULL;
    av_log(s, AV_LOG_INFO, "cmf_parser_next_slice:%d\n", index);
    ret = cmfvpb_dup_pb(s->pb, &newvpb, index);
    if (ret < 0) {
        av_log(s, AV_LOG_INFO, "cmfvpb_dup_pb failed %s---%d [%d]\n",__FUNCTION__,__LINE__,ret);
        return ret;
    }
    if (bs->sctx) {
        avformat_free_context(bs->sctx);
    }
    bs->sctx = NULL;
    if (!(bs->sctx = avformat_alloc_context())) {
        av_log(s, AV_LOG_INFO, "cmf_parser_next_slice avformat_alloc_context failed!\n");
        return AVERROR(ENOMEM);
    }
    ret = av_probe_input_buffer(newvpb->pb, &in_fmt, "", NULL, 0, 0);
    if (ret < 0) {
        av_log(s, AV_LOG_INFO, "av_probe_input_buffer failed %s---%d [%d]\n",__FUNCTION__,__LINE__,ret);
		if (bs->sctx) {
        	avformat_free_context(bs->sctx);
			bs->sctx=NULL;
    	}
		return ret;
    }
    bs->sctx->pb = newvpb->pb;
    ret = avformat_open_input(&bs->sctx, "", NULL, NULL);
    if (ret < 0) {
        av_log(s, AV_LOG_INFO, "cmf_parser_next_slice:avformat_open_input failed \n");
		if (bs->sctx) {
        	avformat_free_context(bs->sctx);
			bs->sctx=NULL;
    	}
        goto fail;
    }
    if (!memcmp(bs->sctx->iformat->name,"flv",3)) {
        ret=av_find_stream_info(bs->sctx);
        av_log(s, AV_LOG_INFO, "xxx-------av_find_stream_info=%d",ret);
    }
    if (first) {
        /* Create new AVStreams for each stream in this chip
             Add into the Best format ;
        */
        if (!memcmp(bs->sctx->iformat->name,"mov",3))
            bs->next_mp4_flag = 1;
        for (j = 0; j < (int)bs->sctx->nb_streams ; j++)   {
            AVStream *st = av_new_stream(s, 0);
            if (!st) {
                ret = AVERROR(ENOMEM);
                goto fail;
            }
            avcodec_copy_context(st->codec, bs->sctx->streams[j]->codec);
        }
        for (i = 0; i < (int)s->nb_streams ; i++)   {
            AVStream *st = s->streams[i];
            AVStream *sst = bs->sctx->streams[i];
            st->id=sst->id;
            if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
                st->time_base.den =  sst->time_base.den;
                st->time_base.num = sst->time_base.num;
                bs->first_slice_audio_index = i;
            }
            if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
                st->time_base.den = sst->time_base.den;
                st->time_base.num = sst->time_base.num;
                bs->first_mp4_video_base_time_num = sst->time_base.num;
                bs->first_mp4_video_base_time_den = sst->time_base.den;
                bs->first_slice_video_index = i;
            }
        }
        s->duration = newvpb->total_duration*1000;
        av_log(s, AV_LOG_INFO, "get duration  [%lld]us [%lld]ms [%lld]s\n", s->duration,newvpb->total_duration,(newvpb->total_duration/1000));
    } else {
        bs->stream_index_changed = 0;
        if (!memcmp(bs->sctx->iformat->name,"mpegts",6)) {
            if(bs->sctx->streams[bs->first_slice_audio_index]->codec->codec_type != s->streams[bs->first_slice_audio_index]->codec->codec_type) {
                bs->stream_index_changed = 1;
                AVStream *temp = NULL;
                AVStream *audio = bs->sctx->streams[bs->first_slice_audio_index];
                temp = bs->sctx->streams[bs->first_slice_video_index];
                bs->sctx->streams[bs->first_slice_video_index] = audio;
                bs->sctx->streams[bs->first_slice_audio_index] = temp;
            }
        }
        if (!memcmp(bs->sctx->iformat->name,"mov",3)) {
            #if 1
            /*
            int audio_index = -1;
            int video_index = -1;
            AVStream *cmf_audio = NULL;
            AVStream *cmf_video = NULL;
            for (i = 0; i < (int)bs->sctx->nb_streams ; i++) {
                if(bs->sctx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO)
                    cmf_audio = bs->sctx->streams[i];
                if(bs->sctx->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO)
                    cmf_video = bs->sctx->streams[i];
            }
            if(cmf_audio && cmf_video) {*/
                for (i = 0; i < (int)s->nb_streams ; i++) {
                    AVStream *st = s->streams[i];
                    AVStream *sst = bs->sctx->streams[i];
                    if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
                        st->time_base.den =  sst->time_base.den;
                        st->time_base.num = sst->time_base.num;
                        //audio_index = i;
                    }
                    if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
                        st->time_base.den = sst->time_base.den;
                        st->time_base.num = sst->time_base.num;
                        //video_index = i;
                    }
                    if(st->codec->extradata)
                        av_freep(&(st->codec->extradata));
                    if(sst->codec->extradata && sst->codec->extradata_size > 0) {
                        st->codec->extradata = av_malloc(sst->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
                        if(st->codec->extradata) {
                             memcpy(st->codec->extradata, sst->codec->extradata, sst->codec->extradata_size);
                             memset(((uint8_t *) st->codec->extradata) + sst->codec->extradata_size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
                        }
                    }
                }
                /*
                if(audio_index >= 0 && bs->sctx->streams[bs->first_mp4_audio_index]->codec->codec_type != s->streams[audio_index]->codec->codec_type) {
                    bs->stream_index_changed = 1;
                    AVStream *temp = NULL;
                    AVStream *audio = s->streams[audio_index];
                    temp = s->streams[video_index];
                    s->streams[video_index] = audio;
                    s->streams[audio_index] = temp;
                    av_log(NULL,AV_LOG_INFO,"--------->tao_cmf_index_change first_mp4_audio_index=%d, audio_index=%d, video_index=%d",bs->first_mp4_audio_index,audio_index,video_index);
                }*/
                bs->next_mp4_flag = 1;
                #endif
            }
        }
    if (memcmp(bs->sctx->iformat->name,"flv",3)) {
        ret = avio_seek(bs->sctx->pb, bs->sctx->media_dataoffset, SEEK_SET);
        if (ret < 0) {
            av_log(s, AV_LOG_INFO, "avio_seek failed %s---%d \n",__FUNCTION__,__LINE__);
            return ret;
        }
    }
    bs->cmfvpb = newvpb;
fail:
    if (oldvpb) {
        cmfvpb_pb_free(oldvpb);
    }
    return ret;
}
Exemple #23
0
int ff_rm_read_mdpr_codecdata(AVFormatContext *s, AVIOContext *pb,
                              AVStream *st, RMStream *rst,
                              unsigned int codec_data_size, const uint8_t *mime)
{
    unsigned int v;
    int size;
    int64_t codec_pos;
    int ret;

    if (codec_data_size > INT_MAX)
        return AVERROR_INVALIDDATA;

    avpriv_set_pts_info(st, 64, 1, 1000);
    codec_pos = avio_tell(pb);
    v = avio_rb32(pb);

    if (v == MKBETAG('M', 'L', 'T', 'I')) {
        int number_of_streams = avio_rb16(pb);
        int number_of_mdpr;
        int i;
        for (i = 0; i<number_of_streams; i++)
            avio_rb16(pb);
        number_of_mdpr = avio_rb16(pb);
        if (number_of_mdpr != 1) {
            avpriv_request_sample(s, "MLTI with multiple MDPR");
        }
        avio_rb32(pb);
        v = avio_rb32(pb);
    }

    if (v == MKTAG(0xfd, 'a', 'r', '.')) {
        /* ra type header */
        if (rm_read_audio_stream_info(s, pb, st, rst, 0))
            return -1;
    } else if (v == MKBETAG('L', 'S', 'D', ':')) {
        avio_seek(pb, -4, SEEK_CUR);
        if ((ret = rm_read_extradata(pb, st->codec, codec_data_size)) < 0)
            return ret;

        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
        st->codec->codec_tag  = AV_RL32(st->codec->extradata);
        st->codec->codec_id   = ff_codec_get_id(ff_rm_codec_tags,
                                                st->codec->codec_tag);
    } else if(mime && !strcmp(mime, "logical-fileinfo")){
        int stream_count, rule_count, property_count, i;
        ff_free_stream(s, st);
        if (avio_rb16(pb) != 0) {
            av_log(s, AV_LOG_WARNING, "Unsupported version\n");
            goto skip;
        }
        stream_count = avio_rb16(pb);
        avio_skip(pb, 6*stream_count);
        rule_count = avio_rb16(pb);
        avio_skip(pb, 2*rule_count);
        property_count = avio_rb16(pb);
        for(i=0; i<property_count; i++){
            uint8_t name[128], val[128];
            avio_rb32(pb);
            if (avio_rb16(pb) != 0) {
                av_log(s, AV_LOG_WARNING, "Unsupported Name value property version\n");
                goto skip; //FIXME skip just this one
            }
            get_str8(pb, name, sizeof(name));
            switch(avio_rb32(pb)) {
            case 2: get_strl(pb, val, sizeof(val), avio_rb16(pb));
                av_dict_set(&s->metadata, name, val, 0);
                break;
            default: avio_skip(pb, avio_rb16(pb));
            }
        }
    } else {
        int fps;
        if (avio_rl32(pb) != MKTAG('V', 'I', 'D', 'O')) {
        fail1:
            av_log(s, AV_LOG_WARNING, "Unsupported stream type %08x\n", v);
            goto skip;
        }
        st->codec->codec_tag = avio_rl32(pb);
        st->codec->codec_id  = ff_codec_get_id(ff_rm_codec_tags,
                                               st->codec->codec_tag);
        av_dlog(s, "%X %X\n", st->codec->codec_tag, MKTAG('R', 'V', '2', '0'));
        if (st->codec->codec_id == AV_CODEC_ID_NONE)
            goto fail1;
        st->codec->width  = avio_rb16(pb);
        st->codec->height = avio_rb16(pb);
        avio_skip(pb, 2); // looks like bits per sample
        avio_skip(pb, 4); // always zero?
        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
        st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
        fps = avio_rb32(pb);

        if ((ret = rm_read_extradata(pb, st->codec, codec_data_size - (avio_tell(pb) - codec_pos))) < 0)
            return ret;

        if (fps > 0) {
            av_reduce(&st->avg_frame_rate.den, &st->avg_frame_rate.num,
                      0x10000, fps, (1 << 30) - 1);
#if FF_API_R_FRAME_RATE
            st->r_frame_rate = st->avg_frame_rate;
#endif
        } else if (s->error_recognition & AV_EF_EXPLODE) {
            av_log(s, AV_LOG_ERROR, "Invalid framerate\n");
            return AVERROR_INVALIDDATA;
        }
    }

skip:
    /* skip codec info */
    size = avio_tell(pb) - codec_pos;
    if (codec_data_size >= size) {
        avio_skip(pb, codec_data_size - size);
    } else {
        av_log(s, AV_LOG_WARNING, "codec_data_size %u < size %d\n", codec_data_size, size);
    }

    return 0;
}
Exemple #24
0
static int ape_read_header(AVFormatContext * s)
{
    AVIOContext *pb = s->pb;
    APEContext *ape = s->priv_data;
    AVStream *st;
    uint32_t tag;
    int i;
    int total_blocks, final_size = 0;
    int64_t pts, file_size;

    /* Skip any leading junk such as id3v2 tags */
    ape->junklength = avio_tell(pb);

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

    ape->fileversion = avio_rl16(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             = avio_rl16(pb);
        ape->descriptorlength     = avio_rl32(pb);
        ape->headerlength         = avio_rl32(pb);
        ape->seektablelength      = avio_rl32(pb);
        ape->wavheaderlength      = avio_rl32(pb);
        ape->audiodatalength      = avio_rl32(pb);
        ape->audiodatalength_high = avio_rl32(pb);
        ape->wavtaillength        = avio_rl32(pb);
        avio_read(pb, ape->md5, 16);

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

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

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

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

        if (ape->formatflags & MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS) {
            ape->seektablelength = avio_rl32(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))
            avio_skip(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: %"PRIu32"\n",
               ape->totalframes);
        return -1;
    }
    if (ape->seektablelength && (ape->seektablelength / sizeof(*ape->seektable)) < ape->totalframes) {
        av_log(s, AV_LOG_ERROR,
               "Number of seek entries is less than number of frames: %zu vs. %"PRIu32"\n",
               ape->seektablelength / sizeof(*ape->seektable), ape->totalframes);
        return AVERROR_INVALIDDATA;
    }
    ape->frames       = av_malloc(ape->totalframes * sizeof(APEFrame));
    if(!ape->frames)
        return AVERROR(ENOMEM);
    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] = avio_rl32(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->junklength;
        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].nblocks = ape->finalframeblocks;
    /* calculate final packet size from total file size, if available */
    file_size = avio_size(pb);
    if (file_size > 0) {
        final_size = file_size - ape->frames[ape->totalframes - 1].pos -
                     ape->wavtaillength;
        final_size -= final_size & 3;
    }
    if (file_size <= 0 || final_size <= 0)
        final_size = ape->finalframeblocks * 8;
    ape->frames[ape->totalframes - 1].size = final_size;

    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 (pb->seekable) {
        ff_ape_parse_tag(s);
        avio_seek(pb, 0, SEEK_SET);
    }

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

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

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

    st->codec->codec_type      = AVMEDIA_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->nb_frames = ape->totalframes;
    st->start_time = 0;
    st->duration  = total_blocks / MAC_SUBFRAME_SIZE;
    avpriv_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;
}
Exemple #25
0
static int wsvqa_read_header(AVFormatContext *s,
                             AVFormatParameters *ap)
{
    WsVqaDemuxContext *wsvqa = s->priv_data;
    AVIOContext *pb = s->pb;
    AVStream *st;
    unsigned char *header;
    unsigned char scratch[VQA_PREAMBLE_SIZE];
    unsigned int chunk_tag;
    unsigned int chunk_size;

    /* initialize the video decoder stream */
    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);
    avpriv_set_pts_info(st, 33, 1, VQA_FRAMERATE);
    wsvqa->video_stream_index = st->index;
    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    st->codec->codec_id = CODEC_ID_WS_VQA;
    st->codec->codec_tag = 0;  /* no fourcc */

    /* skip to the start of the VQA header */
    avio_seek(pb, 20, SEEK_SET);

    /* the VQA header needs to go to the decoder */
    st->codec->extradata_size = VQA_HEADER_SIZE;
    st->codec->extradata = av_mallocz(VQA_HEADER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
    header = (unsigned char *)st->codec->extradata;
    if (avio_read(pb, st->codec->extradata, VQA_HEADER_SIZE) !=
        VQA_HEADER_SIZE) {
        av_free(st->codec->extradata);
        return AVERROR(EIO);
    }
    st->codec->width = AV_RL16(&header[6]);
    st->codec->height = AV_RL16(&header[8]);

    /* initialize the audio decoder stream for VQA v1 or nonzero samplerate */
    if (AV_RL16(&header[24]) || (AV_RL16(&header[0]) == 1 && AV_RL16(&header[2]) == 1)) {
        st = avformat_new_stream(s, NULL);
        if (!st)
            return AVERROR(ENOMEM);
        avpriv_set_pts_info(st, 33, 1, VQA_FRAMERATE);
        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
        if (AV_RL16(&header[0]) == 1)
            st->codec->codec_id = CODEC_ID_WESTWOOD_SND1;
        else
            st->codec->codec_id = CODEC_ID_ADPCM_IMA_WS;
        st->codec->codec_tag = 0;  /* no tag */
        st->codec->sample_rate = AV_RL16(&header[24]);
        if (!st->codec->sample_rate)
            st->codec->sample_rate = 22050;
        st->codec->channels = header[26];
        if (!st->codec->channels)
            st->codec->channels = 1;
        st->codec->bits_per_coded_sample = 16;
        st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *
            st->codec->bits_per_coded_sample / 4;
        st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;

        wsvqa->audio_stream_index = st->index;
        wsvqa->audio_samplerate = st->codec->sample_rate;
        wsvqa->audio_channels = st->codec->channels;
        wsvqa->audio_frame_counter = 0;
    }

    /* there are 0 or more chunks before the FINF chunk; iterate until
     * FINF has been skipped and the file will be ready to be demuxed */
    do {
        if (avio_read(pb, scratch, VQA_PREAMBLE_SIZE) != VQA_PREAMBLE_SIZE)
            return AVERROR(EIO);
        chunk_tag = AV_RB32(&scratch[0]);
        chunk_size = AV_RB32(&scratch[4]);

        /* catch any unknown header tags, for curiousity */
        switch (chunk_tag) {
        case CINF_TAG:
        case CINH_TAG:
        case CIND_TAG:
        case PINF_TAG:
        case PINH_TAG:
        case PIND_TAG:
        case FINF_TAG:
        case CMDS_TAG:
            break;

        default:
            av_log (s, AV_LOG_ERROR, " note: unknown chunk seen (%c%c%c%c)\n",
                scratch[0], scratch[1],
                scratch[2], scratch[3]);
            break;
        }

        avio_skip(pb, chunk_size);
    } while (chunk_tag != FINF_TAG);

    return 0;
}
Exemple #26
0
static int iff_read_header(AVFormatContext *s,
                           AVFormatParameters *ap)
{
    IffDemuxContext *iff = s->priv_data;
    AVIOContext *pb = s->pb;
    AVStream *st;
    uint8_t *buf;
    uint32_t chunk_id, data_size;
    uint32_t screenmode = 0;
    unsigned transparency = 0;
    unsigned masking = 0; // no mask

    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);

    st->codec->channels = 1;
    avio_skip(pb, 8);
    // codec_tag used by ByteRun1 decoder to distinguish progressive (PBM) and interlaced (ILBM) content
    st->codec->codec_tag = avio_rl32(pb);

    while(!url_feof(pb)) {
        uint64_t orig_pos;
        int res;
        const char *metadata_tag = NULL;
        chunk_id = avio_rl32(pb);
        data_size = avio_rb32(pb);
        orig_pos = avio_tell(pb);

        switch(chunk_id) {
        case ID_VHDR:
            st->codec->codec_type = AVMEDIA_TYPE_AUDIO;

            if (data_size < 14)
                return AVERROR_INVALIDDATA;
            avio_skip(pb, 12);
            st->codec->sample_rate = avio_rb16(pb);
            if (data_size >= 16) {
                avio_skip(pb, 1);
                iff->svx8_compression = avio_r8(pb);
            }
            break;

        case ID_ABIT:
        case ID_BODY:
            iff->body_pos = avio_tell(pb);
            iff->body_size = data_size;
            break;

        case ID_CHAN:
            if (data_size < 4)
                return AVERROR_INVALIDDATA;
            st->codec->channels = (avio_rb32(pb) < 6) ? 1 : 2;
            break;

        case ID_CAMG:
            if (data_size < 4)
                return AVERROR_INVALIDDATA;
            screenmode                = avio_rb32(pb);
            break;

        case ID_CMAP:
            st->codec->extradata_size = data_size + IFF_EXTRA_VIDEO_SIZE;
            st->codec->extradata      = av_malloc(data_size + IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
            if (!st->codec->extradata)
                return AVERROR(ENOMEM);
            if (avio_read(pb, st->codec->extradata + IFF_EXTRA_VIDEO_SIZE, data_size) < 0)
                return AVERROR(EIO);
            break;

        case ID_BMHD:
            iff->bitmap_compression = -1;
            st->codec->codec_type            = AVMEDIA_TYPE_VIDEO;
            if (data_size <= 8)
                return AVERROR_INVALIDDATA;
            st->codec->width                 = avio_rb16(pb);
            st->codec->height                = avio_rb16(pb);
            avio_skip(pb, 4); // x, y offset
            st->codec->bits_per_coded_sample = avio_r8(pb);
            if (data_size >= 10)
                masking                      = avio_r8(pb);
            if (data_size >= 11)
                iff->bitmap_compression      = avio_r8(pb);
            if (data_size >= 14) {
                avio_skip(pb, 1); // padding
                transparency                 = avio_rb16(pb);
            }
            if (data_size >= 16) {
                st->sample_aspect_ratio.num  = avio_r8(pb);
                st->sample_aspect_ratio.den  = avio_r8(pb);
            }
            break;

        case ID_ANNO:
        case ID_TEXT:      metadata_tag = "comment";   break;
        case ID_AUTH:      metadata_tag = "artist";    break;
        case ID_COPYRIGHT: metadata_tag = "copyright"; break;
        case ID_NAME:      metadata_tag = "title";     break;
        }

        if (metadata_tag) {
            if ((res = get_metadata(s, metadata_tag, data_size)) < 0) {
                av_log(s, AV_LOG_ERROR, "cannot allocate metadata tag %s!", metadata_tag);
                return res;
            }
        }
        avio_skip(pb, data_size - (avio_tell(pb) - orig_pos) + (data_size & 1));
    }

    avio_seek(pb, iff->body_pos, SEEK_SET);

    switch(st->codec->codec_type) {
    case AVMEDIA_TYPE_AUDIO:
        avpriv_set_pts_info(st, 32, 1, st->codec->sample_rate);

        switch (iff->svx8_compression) {
        case COMP_NONE:
            st->codec->codec_id = CODEC_ID_PCM_S8_PLANAR;
            break;
        case COMP_FIB:
            st->codec->codec_id = CODEC_ID_8SVX_FIB;
            break;
        case COMP_EXP:
            st->codec->codec_id = CODEC_ID_8SVX_EXP;
            break;
        default:
            av_log(s, AV_LOG_ERROR,
                   "Unknown SVX8 compression method '%d'\n", iff->svx8_compression);
            return -1;
        }

        st->codec->bits_per_coded_sample = iff->svx8_compression == COMP_NONE ? 8 : 4;
        st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * st->codec->bits_per_coded_sample;
        st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample;
        break;

    case AVMEDIA_TYPE_VIDEO:
        iff->bpp          = st->codec->bits_per_coded_sample;
        if ((screenmode & 0x800 /* Hold And Modify */) && iff->bpp <= 8) {
            iff->ham      = iff->bpp > 6 ? 6 : 4;
            st->codec->bits_per_coded_sample = 24;
        }
        iff->flags        = (screenmode & 0x80 /* Extra HalfBrite */) && iff->bpp <= 8;
        iff->masking      = masking;
        iff->transparency = transparency;

        if (!st->codec->extradata) {
            st->codec->extradata_size = IFF_EXTRA_VIDEO_SIZE;
            st->codec->extradata      = av_malloc(IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
            if (!st->codec->extradata)
                return AVERROR(ENOMEM);
        }
        buf = st->codec->extradata;
        bytestream_put_be16(&buf, IFF_EXTRA_VIDEO_SIZE);
        bytestream_put_byte(&buf, iff->bitmap_compression);
        bytestream_put_byte(&buf, iff->bpp);
        bytestream_put_byte(&buf, iff->ham);
        bytestream_put_byte(&buf, iff->flags);
        bytestream_put_be16(&buf, iff->transparency);
        bytestream_put_byte(&buf, iff->masking);

        switch (iff->bitmap_compression) {
        case BITMAP_RAW:
            st->codec->codec_id = CODEC_ID_IFF_ILBM;
            break;
        case BITMAP_BYTERUN1:
            st->codec->codec_id = CODEC_ID_IFF_BYTERUN1;
            break;
        default:
            av_log(s, AV_LOG_ERROR,
                   "Unknown bitmap compression method '%d'\n", iff->bitmap_compression);
            return AVERROR_INVALIDDATA;
        }
        break;
    default:
        return -1;
    }

    return 0;
}
Exemple #27
0
int64_t avio_skip(AVIOContext *s, int64_t offset)
{
    return avio_seek(s, offset, SEEK_CUR);
}
Exemple #28
0
static int tak_read_header(AVFormatContext *s)
{
    TAKDemuxContext *tc = s->priv_data;
    AVIOContext *pb = s->pb;
    GetBitContext gb;
    AVStream *st;
    uint8_t *buffer = NULL;
    int ret;

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

    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
    st->codec->codec_id   = AV_CODEC_ID_TAK;
    st->need_parsing      = AVSTREAM_PARSE_FULL_RAW;

    tc->mlast_frame = 0;
    if (avio_rl32(pb) != MKTAG('t', 'B', 'a', 'K')) {
        avio_seek(pb, -4, SEEK_CUR);
        return 0;
    }

    while (!url_feof(pb)) {
        enum TAKMetaDataType type;
        int size;

        type = avio_r8(pb) & 0x7f;
        size = avio_rl24(pb);

        switch (type) {
        case TAK_METADATA_STREAMINFO:
        case TAK_METADATA_LAST_FRAME:
        case TAK_METADATA_ENCODER:
            buffer = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
            if (!buffer)
                return AVERROR(ENOMEM);

            if (avio_read(pb, buffer, size) != size) {
                av_freep(&buffer);
                return AVERROR(EIO);
            }

            init_get_bits(&gb, buffer, size * 8);
            break;
        case TAK_METADATA_MD5: {
            uint8_t md5[16];
            int i;

            if (size != 19)
                return AVERROR_INVALIDDATA;
            avio_read(pb, md5, 16);
            avio_skip(pb, 3);
            av_log(s, AV_LOG_VERBOSE, "MD5=");
            for (i = 0; i < 16; i++)
                av_log(s, AV_LOG_VERBOSE, "%02x", md5[i]);
            av_log(s, AV_LOG_VERBOSE, "\n");
            break;
            }
        case TAK_METADATA_END: {
            int64_t curpos = avio_tell(pb);

            if (pb->seekable) {
                ff_ape_parse_tag(s);
                avio_seek(pb, curpos, SEEK_SET);
            }

            tc->data_end += curpos;
            return 0;
            break;
            }
        default:
            ret = avio_skip(pb, size);
            if (ret < 0)
                return ret;
        }

        if (type == TAK_METADATA_STREAMINFO) {
            TAKStreamInfo ti;

            avpriv_tak_parse_streaminfo(&gb, &ti);
            if (ti.samples > 0)
                st->duration = ti.samples;
            st->codec->bits_per_coded_sample = ti.bps;
            if (ti.ch_layout)
                st->codec->channel_layout = ti.ch_layout;
            st->codec->sample_rate = ti.sample_rate;
            st->codec->channels    = ti.channels;
            st->start_time         = 0;
            avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
            st->codec->extradata      = buffer;
            st->codec->extradata_size = size;
            buffer = NULL;
        } else if (type == TAK_METADATA_LAST_FRAME) {
            if (size != 11)
                return AVERROR_INVALIDDATA;
            tc->mlast_frame = 1;
            tc->data_end = get_bits_longlong(&gb, TAK_LAST_FRAME_POS_BITS) +
                           get_bits(&gb, TAK_LAST_FRAME_SIZE_BITS);
            av_freep(&buffer);
        } else if (type == TAK_METADATA_ENCODER) {
            av_log(s, AV_LOG_VERBOSE, "encoder version: %0X\n",
                   get_bits_long(&gb, TAK_ENCODER_VERSION_BITS));
            av_freep(&buffer);
        }
    }

    return AVERROR_EOF;
}
static int wc3_read_packet(AVFormatContext *s,
                           AVPacket *pkt)
{
    Wc3DemuxContext *wc3 = s->priv_data;
    AVIOContext *pb = s->pb;
    unsigned int fourcc_tag;
    unsigned int size;
    int packet_read = 0;
    int ret = 0;
    unsigned char text[1024];

    while (!packet_read) {

        fourcc_tag = avio_rl32(pb);
        /* chunk sizes are 16-bit aligned */
        size = (avio_rb32(pb) + 1) & (~1);
        if (avio_feof(pb))
            return AVERROR(EIO);

        switch (fourcc_tag) {

        case BRCH_TAG:
            /* no-op */
            break;

        case SHOT_TAG:
            /* load up new palette */
            avio_seek(pb, -8, SEEK_CUR);
            av_append_packet(pb, &wc3->vpkt, 8 + 4);
            break;

        case VGA__TAG:
            /* send out video chunk */
            avio_seek(pb, -8, SEEK_CUR);
            ret= av_append_packet(pb, &wc3->vpkt, 8 + size);
            // ignore error if we have some data
            if (wc3->vpkt.size > 0)
                ret = 0;
            *pkt = wc3->vpkt;
            wc3->vpkt.data = NULL; wc3->vpkt.size = 0;
            pkt->stream_index = wc3->video_stream_index;
            pkt->pts = wc3->pts;
            packet_read = 1;
            break;

        case TEXT_TAG:
            /* subtitle chunk */
            if ((unsigned)size > sizeof(text) || (ret = avio_read(pb, text, size)) != size)
                ret = AVERROR(EIO);
            else {
                int i = 0;
                av_log (s, AV_LOG_DEBUG, "Subtitle time!\n");
                if (i >= size || av_strnlen(&text[i + 1], size - i - 1) >= size - i - 1)
                    return AVERROR_INVALIDDATA;
                av_log (s, AV_LOG_DEBUG, "  inglish: %s\n", &text[i + 1]);
                i += text[i] + 1;
                if (i >= size || av_strnlen(&text[i + 1], size - i - 1) >= size - i - 1)
                    return AVERROR_INVALIDDATA;
                av_log (s, AV_LOG_DEBUG, "  doytsch: %s\n", &text[i + 1]);
                i += text[i] + 1;
                if (i >= size || av_strnlen(&text[i + 1], size - i - 1) >= size - i - 1)
                    return AVERROR_INVALIDDATA;
                av_log (s, AV_LOG_DEBUG, "  fronsay: %s\n", &text[i + 1]);
            }
            break;

        case AUDI_TAG:
            /* send out audio chunk */
            ret= av_get_packet(pb, pkt, size);
            pkt->stream_index = wc3->audio_stream_index;
            pkt->pts = wc3->pts;

            /* time to advance pts */
            wc3->pts++;

            packet_read = 1;
            break;

        default:
            av_log(s, AV_LOG_ERROR, "unrecognized WC3 chunk: %s\n",
                   av_fourcc2str(fourcc_tag));
            ret = AVERROR_INVALIDDATA;
            packet_read = 1;
            break;
        }
    }

    return ret;
}
Exemple #30
0
static int ffm2_read_header(AVFormatContext *s)
{
    FFMContext *ffm = s->priv_data;
    AVStream *st;
    AVIOContext *pb = s->pb;
    AVCodecContext *codec;
    int ret;
    int f_main = 0, f_cprv = -1, f_stvi = -1, f_stau = -1;
    AVCodec *enc;
    char *buffer;

    ffm->packet_size = avio_rb32(pb);
    if (ffm->packet_size != FFM_PACKET_SIZE) {
        av_log(s, AV_LOG_ERROR, "Invalid packet size %d, expected size was %d\n",
               ffm->packet_size, FFM_PACKET_SIZE);
        ret = AVERROR_INVALIDDATA;
        goto fail;
    }

    ffm->write_index = avio_rb64(pb);
    /* get also filesize */
    if (pb->seekable) {
        ffm->file_size = avio_size(pb);
        if (ffm->write_index && 0)
            adjust_write_index(s);
    } else {
        ffm->file_size = (UINT64_C(1) << 63) - 1;
    }

    while(!avio_feof(pb)) {
        unsigned id = avio_rb32(pb);
        unsigned size = avio_rb32(pb);
        int64_t next = avio_tell(pb) + size;
        char rc_eq_buf[128];

        if(!id)
            break;

        switch(id) {
        case MKBETAG('M', 'A', 'I', 'N'):
            if (f_main++) {
                ret = AVERROR(EINVAL);
                goto fail;
            }
            avio_rb32(pb); /* nb_streams */
            avio_rb32(pb); /* total bitrate */
            break;
        case MKBETAG('C', 'O', 'M', 'M'):
            f_cprv = f_stvi = f_stau = 0;
            st = avformat_new_stream(s, NULL);
            if (!st) {
                ret = AVERROR(ENOMEM);
                goto fail;
            }

            avpriv_set_pts_info(st, 64, 1, 1000000);

            codec = st->codec;
            /* generic info */
            codec->codec_id = avio_rb32(pb);
            codec->codec_type = avio_r8(pb);
            codec->bit_rate = avio_rb32(pb);
            codec->flags = avio_rb32(pb);
            codec->flags2 = avio_rb32(pb);
            codec->debug = avio_rb32(pb);
            if (codec->flags & CODEC_FLAG_GLOBAL_HEADER) {
                if (ff_get_extradata(codec, pb, avio_rb32(pb)) < 0)
                    return AVERROR(ENOMEM);
            }
            break;
        case MKBETAG('S', 'T', 'V', 'I'):
            if (f_stvi++) {
                ret = AVERROR(EINVAL);
                goto fail;
            }
            codec->time_base.num = avio_rb32(pb);
            codec->time_base.den = avio_rb32(pb);
            if (codec->time_base.num <= 0 || codec->time_base.den <= 0) {
                av_log(s, AV_LOG_ERROR, "Invalid time base %d/%d\n",
                       codec->time_base.num, codec->time_base.den);
                ret = AVERROR_INVALIDDATA;
                goto fail;
            }
            codec->width = avio_rb16(pb);
            codec->height = avio_rb16(pb);
            codec->gop_size = avio_rb16(pb);
            codec->pix_fmt = avio_rb32(pb);
            codec->qmin = avio_r8(pb);
            codec->qmax = avio_r8(pb);
            codec->max_qdiff = avio_r8(pb);
            codec->qcompress = avio_rb16(pb) / 10000.0;
            codec->qblur = avio_rb16(pb) / 10000.0;
            codec->bit_rate_tolerance = avio_rb32(pb);
            avio_get_str(pb, INT_MAX, rc_eq_buf, sizeof(rc_eq_buf));
            codec->rc_eq = av_strdup(rc_eq_buf);
            codec->rc_max_rate = avio_rb32(pb);
            codec->rc_min_rate = avio_rb32(pb);
            codec->rc_buffer_size = avio_rb32(pb);
            codec->i_quant_factor = av_int2double(avio_rb64(pb));
            codec->b_quant_factor = av_int2double(avio_rb64(pb));
            codec->i_quant_offset = av_int2double(avio_rb64(pb));
            codec->b_quant_offset = av_int2double(avio_rb64(pb));
            codec->dct_algo = avio_rb32(pb);
            codec->strict_std_compliance = avio_rb32(pb);
            codec->max_b_frames = avio_rb32(pb);
            codec->mpeg_quant = avio_rb32(pb);
            codec->intra_dc_precision = avio_rb32(pb);
            codec->me_method = avio_rb32(pb);
            codec->mb_decision = avio_rb32(pb);
            codec->nsse_weight = avio_rb32(pb);
            codec->frame_skip_cmp = avio_rb32(pb);
            codec->rc_buffer_aggressivity = av_int2double(avio_rb64(pb));
            codec->codec_tag = avio_rb32(pb);
            codec->thread_count = avio_r8(pb);
            codec->coder_type = avio_rb32(pb);
            codec->me_cmp = avio_rb32(pb);
            codec->me_subpel_quality = avio_rb32(pb);
            codec->me_range = avio_rb32(pb);
            codec->keyint_min = avio_rb32(pb);
            codec->scenechange_threshold = avio_rb32(pb);
            codec->b_frame_strategy = avio_rb32(pb);
            codec->qcompress = av_int2double(avio_rb64(pb));
            codec->qblur = av_int2double(avio_rb64(pb));
            codec->max_qdiff = avio_rb32(pb);
            codec->refs = avio_rb32(pb);
            break;
        case MKBETAG('S', 'T', 'A', 'U'):
            if (f_stau++) {
                ret = AVERROR(EINVAL);
                goto fail;
            }
            codec->sample_rate = avio_rb32(pb);
            codec->channels = avio_rl16(pb);
            codec->frame_size = avio_rl16(pb);
            break;
        case MKBETAG('C', 'P', 'R', 'V'):
            if (f_cprv++) {
                ret = AVERROR(EINVAL);
                goto fail;
            }
            enc = avcodec_find_encoder(codec->codec_id);
            if (enc && enc->priv_data_size && enc->priv_class) {
                buffer = av_malloc(size + 1);
                if (!buffer) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
                avio_get_str(pb, size, buffer, size + 1);
                if ((ret = ffm_append_recommended_configuration(st, &buffer)) < 0)
                    goto fail;
            }
            break;
        case MKBETAG('S', '2', 'V', 'I'):
            if (f_stvi++) {
                ret = AVERROR(EINVAL);
                goto fail;
            }
            buffer = av_malloc(size);
            if (!buffer) {
                ret = AVERROR(ENOMEM);
                goto fail;
            }
            avio_get_str(pb, INT_MAX, buffer, size);
            av_set_options_string(codec, buffer, "=", ",");
            if ((ret = ffm_append_recommended_configuration(st, &buffer)) < 0)
                goto fail;
            break;
        case MKBETAG('S', '2', 'A', 'U'):
            if (f_stau++) {
                ret = AVERROR(EINVAL);
                goto fail;
            }
            buffer = av_malloc(size);
            if (!buffer) {
                ret = AVERROR(ENOMEM);
                goto fail;
            }
            avio_get_str(pb, INT_MAX, buffer, size);
            av_set_options_string(codec, buffer, "=", ",");
            if ((ret = ffm_append_recommended_configuration(st, &buffer)) < 0)
                goto fail;
            break;
        }
        avio_seek(pb, next, SEEK_SET);
    }

    /* get until end of block reached */
    while ((avio_tell(pb) % ffm->packet_size) != 0 && !pb->eof_reached)
        avio_r8(pb);

    /* init packet demux */
    ffm->packet_ptr = ffm->packet;
    ffm->packet_end = ffm->packet;
    ffm->frame_offset = 0;
    ffm->dts = 0;
    ffm->read_state = READ_HEADER;
    ffm->first_packet = 1;
    return 0;
 fail:
    ffm_close(s);
    return ret;
}