コード例 #1
0
ファイル: caf.c プロジェクト: MarkAufdencamp/ffmpeg4ios
void ff_read_chan_chunk(AVFormatContext *s, int64_t size, AVCodecContext *codec)
{
    uint32_t layout_tag;
    AVIOContext *pb = s->pb;
    const CafChannelLayout *caf_layout = caf_channel_layout;
    if (size != 12) {
        // Channel descriptions not implemented
        av_log_ask_for_sample(s, "Unimplemented channel layout.\n");
        avio_skip(pb, size);
        return;
    }
    layout_tag = avio_rb32(pb);
    if (layout_tag == 0x10000) { //< kCAFChannelLayoutTag_UseChannelBitmap
        codec->channel_layout = avio_rb32(pb);
        avio_skip(pb, 4);
        return;
    }
    while (caf_layout->channel_layout) {
        if (layout_tag == caf_layout->layout_tag) {
            codec->channel_layout = caf_layout->channel_layout;
            break;
        }
        caf_layout++;
    }
    if (!codec->channel_layout)
        av_log(s, AV_LOG_WARNING, "Unknown channel layout.\n");
    avio_skip(pb, 8);
}
コード例 #2
0
ファイル: isom.c プロジェクト: wfrisby/FFmpeg
void ff_mov_read_chan(AVFormatContext *s, int64_t size, AVCodecContext *codec)
{
    uint32_t layout_tag;
    AVIOContext *pb = s->pb;
    const MovChannelLayout *layouts = mov_channel_layout;
    layout_tag = avio_rb32(pb);
    size -= 4;
    if (layout_tag == 0) { // kCAFChannelLayoutTag_UseChannelDescriptions
        // Channel descriptions not implemented
        av_log_ask_for_sample(s, "Unimplemented container channel layout.\n");
        avio_skip(pb, size);
        return;
    }
    if (layout_tag == 0x10000) { // kCAFChannelLayoutTag_UseChannelBitmap
        codec->channel_layout = avio_rb32(pb);
        size -= 4;
        avio_skip(pb, size);
        return;
    }
    while (layouts->channel_layout) {
        if (layout_tag == layouts->layout_tag) {
            codec->channel_layout = layouts->channel_layout;
            break;
        }
        layouts++;
    }
    if (!codec->channel_layout)
        av_log(s, AV_LOG_WARNING, "Unknown container channel layout.\n");
    avio_skip(pb, size);
}
コード例 #3
0
ファイル: au.c プロジェクト: ebichu/dd-wrt
/* au input */
static int au_read_header(AVFormatContext *s)
{
    int size, bps, data_size = 0;
    unsigned int tag;
    AVIOContext *pb = s->pb;
    unsigned int id, channels, rate;
    enum AVCodecID codec;
    AVStream *st;

    /* check ".snd" header */
    tag = avio_rl32(pb);
    if (tag != MKTAG('.', 's', 'n', 'd'))
        return AVERROR_INVALIDDATA;
    size = avio_rb32(pb); /* header size */
    data_size = avio_rb32(pb); /* data size in bytes */

    if (data_size < 0 && data_size != AU_UNKNOWN_SIZE) {
        av_log(s, AV_LOG_ERROR, "Invalid negative data size '%d' found\n", data_size);
        return AVERROR_INVALIDDATA;
    }

    id = avio_rb32(pb);
    rate = avio_rb32(pb);
    channels = avio_rb32(pb);

    codec = ff_codec_get_id(codec_au_tags, id);

    if (!(bps = av_get_bits_per_sample(codec))) {
        av_log_ask_for_sample(s, "could not determine bits per sample\n");
        return AVERROR_PATCHWELCOME;
    }

    if (channels == 0 || channels > 64) {
        av_log(s, AV_LOG_ERROR, "Invalid number of channels %d\n", channels);
        return AVERROR_INVALIDDATA;
    }

    if (size >= 24) {
        /* skip unused data */
        avio_skip(pb, size - 24);
    }

    /* now we are ready: build format streams */
    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);
    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
    st->codec->codec_tag = id;
    st->codec->codec_id = codec;
    st->codec->channels = channels;
    st->codec->sample_rate = rate;
    st->codec->block_align = FFMAX(bps * st->codec->channels / 8, 1);
    if (data_size != AU_UNKNOWN_SIZE)
    st->duration = (((int64_t)data_size)<<3) / (st->codec->channels * (int64_t)bps);
    avpriv_set_pts_info(st, 64, 1, rate);
    return 0;
}
コード例 #4
0
static int wsaud_read_header(AVFormatContext *s)
{
    AVIOContext *pb = s->pb;
    AVStream *st;
    unsigned char header[AUD_HEADER_SIZE];
    int sample_rate, channels, codec;

    if (avio_read(pb, header, AUD_HEADER_SIZE) != AUD_HEADER_SIZE)
        return AVERROR(EIO);

    sample_rate = AV_RL16(&header[0]);
    channels    = (header[10] & 0x1) + 1;
    codec       = header[11];

    /* initialize the audio decoder stream */
    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);

    switch (codec) {
    case  1:
        if (channels != 1) {
            av_log_ask_for_sample(s, "Stereo WS-SND1 is not supported.\n");
            return AVERROR_PATCHWELCOME;
        }
        st->codec->codec_id = CODEC_ID_WESTWOOD_SND1;
        break;
    case 99:
        st->codec->codec_id = CODEC_ID_ADPCM_IMA_WS;
        st->codec->bits_per_coded_sample = 4;
        st->codec->bit_rate = channels * sample_rate * 4;
        break;
    default:
        av_log_ask_for_sample(s, "Unknown codec: %d\n", codec);
        return AVERROR_PATCHWELCOME;
    }
    avpriv_set_pts_info(st, 64, 1, sample_rate);
    st->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
    st->codec->channels    = channels;
    st->codec->sample_rate = sample_rate;

    return 0;
}
コード例 #5
0
ファイル: ws-snd1.c プロジェクト: ElfSundae/FFmpegAudioTest
static av_cold int ws_snd_decode_init(AVCodecContext * avctx)
{
//    WSSNDContext *c = avctx->priv_data;

    if (avctx->channels != 1) {
        av_log_ask_for_sample(avctx, "unsupported number of channels\n");
        return AVERROR(EINVAL);
    }

    avctx->sample_fmt = AV_SAMPLE_FMT_U8;
    return 0;
}
コード例 #6
0
ファイル: adx.c プロジェクト: 0MasteR0/xbmc
int avpriv_adx_decode_header(AVCodecContext *avctx, const uint8_t *buf,
                             int bufsize, int *header_size, int *coeff)
{
    int offset, cutoff;

    if (bufsize < 24)
        return AVERROR_INVALIDDATA;

    if (AV_RB16(buf) != 0x8000)
        return AVERROR_INVALIDDATA;
    offset = AV_RB16(buf + 2) + 4;

    if (offset < 6) {
        av_log(avctx, AV_LOG_ERROR, "offset is prior data\n");
        return AVERROR_INVALIDDATA;
    }

    /* if copyright string is within the provided data, validate it */
    if (bufsize >= offset && memcmp(buf + offset - 6, "(c)CRI", 6))
        return AVERROR_INVALIDDATA;

    /* check for encoding=3 block_size=18, sample_size=4 */
    if (buf[4] != 3 || buf[5] != 18 || buf[6] != 4) {
        av_log_ask_for_sample(avctx, "unsupported ADX format\n");
        return AVERROR_PATCHWELCOME;
    }

    /* channels */
    avctx->channels = buf[7];
    if (avctx->channels <= 0 || avctx->channels > 2)
        return AVERROR_INVALIDDATA;

    /* sample rate */
    avctx->sample_rate = AV_RB32(buf + 8);
    if (avctx->sample_rate < 1 ||
        avctx->sample_rate > INT_MAX / (avctx->channels * BLOCK_SIZE * 8))
        return AVERROR_INVALIDDATA;

    /* bit rate */
    avctx->bit_rate = avctx->sample_rate * avctx->channels * BLOCK_SIZE * 8 / BLOCK_SAMPLES;

    /* LPC coefficients */
    if (coeff) {
        cutoff = AV_RB16(buf + 16);
        ff_adx_calculate_coeffs(cutoff, avctx->sample_rate, COEFF_BITS, coeff);
    }

    *header_size = offset;
    return 0;
}
コード例 #7
0
ファイル: au.c プロジェクト: Flameeyes/libav
/* au input */
static int au_read_header(AVFormatContext *s)
{
    int size;
    unsigned int tag;
    AVIOContext *pb = s->pb;
    unsigned int id, channels, rate;
    enum AVCodecID codec;
    AVStream *st;

    /* check ".snd" header */
    tag = avio_rl32(pb);
    if (tag != MKTAG('.', 's', 'n', 'd'))
        return -1;
    size = avio_rb32(pb); /* header size */
    avio_rb32(pb); /* data size */

    id = avio_rb32(pb);
    rate = avio_rb32(pb);
    channels = avio_rb32(pb);

    codec = ff_codec_get_id(codec_au_tags, id);

    if (!av_get_bits_per_sample(codec)) {
        av_log_ask_for_sample(s, "could not determine bits per sample\n");
        return AVERROR_INVALIDDATA;
    }

    if (channels == 0 || channels > 64) {
        av_log(s, AV_LOG_ERROR, "Invalid number of channels %d\n", channels);
        return AVERROR_INVALIDDATA;
    }

    if (size >= 24) {
        /* skip unused data */
        avio_skip(pb, size - 24);
    }

    /* now we are ready: build format streams */
    st = avformat_new_stream(s, NULL);
    if (!st)
        return -1;
    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
    st->codec->codec_tag = id;
    st->codec->codec_id = codec;
    st->codec->channels = channels;
    st->codec->sample_rate = rate;
    avpriv_set_pts_info(st, 64, 1, rate);
    return 0;
}
コード例 #8
0
static av_cold int ws_snd_decode_init(AVCodecContext *avctx)
{
    WSSndContext *s = (WSSndContext *)avctx->priv_data;

    if (avctx->channels != 1) {
        av_log_ask_for_sample(avctx, "unsupported number of channels\n");
        return AVERROR(EINVAL);
    }

    avctx->sample_fmt = AV_SAMPLE_FMT_U8;

    avcodec_get_frame_defaults(&s->frame);
    avctx->coded_frame = &s->frame;

    return 0;
}
コード例 #9
0
ファイル: 012v.c プロジェクト: 0MasteR0/xbmc
static av_cold int zero12v_decode_init(AVCodecContext *avctx)
{
    avctx->pix_fmt             = PIX_FMT_YUV422P16;
    avctx->bits_per_raw_sample = 10;

    avctx->coded_frame = avcodec_alloc_frame();
    if (!avctx->coded_frame)
        return AVERROR(ENOMEM);

    if (avctx->codec_tag == MKTAG('a', '1', '2', 'v'))
        av_log_ask_for_sample(avctx, "Samples with actual transparency needed\n");

    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
    avctx->coded_frame->key_frame = 1;
    return 0;
}
コード例 #10
0
ファイル: au.c プロジェクト: 119/dropcam_for_iphone
/* au input */
static int au_read_header(AVFormatContext *s,
                          AVFormatParameters *ap)
{
    int size;
    unsigned int tag;
    ByteIOContext *pb = s->pb;
    unsigned int id, channels, rate;
    enum CodecID codec;
    AVStream *st;

    /* check ".snd" header */
    tag = get_le32(pb);
    if (tag != MKTAG('.', 's', 'n', 'd'))
        return -1;
    size = get_be32(pb); /* header size */
    get_be32(pb); /* data size */

    id = get_be32(pb);
    rate = get_be32(pb);
    channels = get_be32(pb);

    codec = ff_codec_get_id(codec_au_tags, id);

    if (!av_get_bits_per_sample(codec)) {
        av_log_ask_for_sample(s, "could not determine bits per sample\n");
        return AVERROR_INVALIDDATA;
    }

    if (size >= 24) {
        /* skip unused data */
        url_fseek(pb, size - 24, SEEK_CUR);
    }

    /* now we are ready: build format streams */
    st = av_new_stream(s, 0);
    if (!st)
        return -1;
    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
    st->codec->codec_tag = id;
    st->codec->codec_id = codec;
    st->codec->channels = channels;
    st->codec->sample_rate = rate;
    av_set_pts_info(st, 64, 1, rate);
    return 0;
}
コード例 #11
0
ファイル: truespeech.c プロジェクト: 2BReality/xbmc
static av_cold int truespeech_decode_init(AVCodecContext * avctx)
{
    TSContext *c = avctx->priv_data;

    if (avctx->channels != 1) {
        av_log_ask_for_sample(avctx, "Unsupported channel count: %d\n", avctx->channels);
        return AVERROR(EINVAL);
    }

    avctx->sample_fmt = AV_SAMPLE_FMT_S16;

    dsputil_init(&c->dsp, avctx);

    avcodec_get_frame_defaults(&c->frame);
    avctx->coded_frame = &c->frame;

    return 0;
}
コード例 #12
0
ファイル: rsodec.c プロジェクト: tesoknyra/libav
static int rso_read_header(AVFormatContext *s)
{
    AVIOContext *pb = s->pb;
    int id, rate, bps;
    unsigned int size;
    enum AVCodecID codec;
    AVStream *st;

    id   = avio_rb16(pb);
    size = avio_rb16(pb);
    rate = avio_rb16(pb);
    avio_rb16(pb);   /* play mode ? (0x0000 = don't loop) */

    codec = ff_codec_get_id(ff_codec_rso_tags, id);

    if (codec == AV_CODEC_ID_ADPCM_IMA_WAV) {
        av_log(s, AV_LOG_ERROR, "ADPCM in RSO not implemented\n");
        return AVERROR_PATCHWELCOME;
    }

    bps = av_get_bits_per_sample(codec);
    if (!bps) {
        av_log_ask_for_sample(s, "could not determine bits per sample\n");
        return AVERROR_INVALIDDATA;
    }

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

    st->duration            = (size * 8) / bps;
    st->codec->codec_type   = AVMEDIA_TYPE_AUDIO;
    st->codec->codec_tag    = id;
    st->codec->codec_id     = codec;
    st->codec->channels     = 1;
    st->codec->channel_layout = AV_CH_LAYOUT_MONO;
    st->codec->sample_rate  = rate;

    avpriv_set_pts_info(st, 64, 1, rate);

    return 0;
}
コード例 #13
0
ファイル: pmpdec.c プロジェクト: ALEXGUOQ/FFmpeg
static int pmp_packet(AVFormatContext *s, AVPacket *pkt)
{
    PMPContext *pmp = s->priv_data;
    AVIOContext *pb = s->pb;
    int ret = 0;
    int i;

    if (url_feof(pb))
        return AVERROR_EOF;
    if (pmp->cur_stream == 0) {
        int num_packets;
        pmp->audio_packets = avio_r8(pb);
        if (!pmp->audio_packets) {
            av_log_ask_for_sample(s, "0 audio packets\n");
            return AVERROR_PATCHWELCOME;
        }
        num_packets = (pmp->num_streams - 1) * pmp->audio_packets + 1;
        avio_skip(pb, 8);
        pmp->current_packet = 0;
        av_fast_malloc(&pmp->packet_sizes,
                       &pmp->packet_sizes_alloc,
                       num_packets * sizeof(*pmp->packet_sizes));
        if (!pmp->packet_sizes_alloc) {
            av_log(s, AV_LOG_ERROR, "Cannot (re)allocate packet buffer\n");
            return AVERROR(ENOMEM);
        }
        for (i = 0; i < num_packets; i++)
            pmp->packet_sizes[i] = avio_rl32(pb);
    }
    ret = av_get_packet(pb, pkt, pmp->packet_sizes[pmp->current_packet]);
    if (ret >= 0) {
        ret = 0;
        // FIXME: this is a hack that should be removed once
        // compute_pkt_fields() can handle timestamps properly
        if (pmp->cur_stream == 0)
            pkt->dts = s->streams[0]->cur_dts++;
        pkt->stream_index = pmp->cur_stream;
    }
    if (pmp->current_packet % pmp->audio_packets == 0)
        pmp->cur_stream = (pmp->cur_stream + 1) % pmp->num_streams;
    pmp->current_packet++;
    return ret;
}
コード例 #14
0
static int read_header(AVFormatContext *s,
                       AVFormatParameters *ap)
{
	FilmstripDemuxContext *film = s->priv_data;
	AVIOContext *pb = s->pb;
	AVStream *st;

	if (!s->pb->seekable)
		return AVERROR(EIO);

	avio_seek(pb, avio_size(pb) - 36, SEEK_SET);
	if (avio_rb32(pb) != RAND_TAG)
	{
		av_log(s, AV_LOG_ERROR, "magic number not found");
		return AVERROR_INVALIDDATA;
	}

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

	st->nb_frames = avio_rb32(pb);
	if (avio_rb16(pb) != 0)
	{
		av_log_ask_for_sample(s, "unsupported packing method\n");
		return AVERROR_INVALIDDATA;
	}

	avio_skip(pb, 2);
	st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
	st->codec->codec_id   = CODEC_ID_RAWVIDEO;
	st->codec->pix_fmt    = PIX_FMT_RGBA;
	st->codec->codec_tag  = 0; /* no fourcc */
	st->codec->width      = avio_rb16(pb);
	st->codec->height     = avio_rb16(pb);
	film->leading         = avio_rb16(pb);
	av_set_pts_info(st, 64, 1, avio_rb16(pb));

	avio_seek(pb, 0, SEEK_SET);

	return 0;
}
コード例 #15
0
ファイル: anm.c プロジェクト: JDsolution/ipnc
static int read_header(AVFormatContext *s,
                       AVFormatParameters *ap)
{
    AnmDemuxContext *anm = s->priv_data;
    ByteIOContext *pb = s->pb;
    AVStream *st;
    int i, ret;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    anm->record = -1;
    return 0;

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

close_and_return:
    av_close_input_stream(s);
    return ret;
}
コード例 #16
0
ファイル: bethsoftvid.c プロジェクト: Brhett/FFmpeg
static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt,
                      uint8_t block_type, AVFormatContext *s)
{
    uint8_t * vidbuf_start = NULL;
    int vidbuf_nbytes = 0;
    int code;
    int bytes_copied = 0;
    int position, duration, npixels;
    unsigned int vidbuf_capacity;
    int ret = 0;
    AVStream *st;

    if (vid->video_index < 0) {
        st = avformat_new_stream(s, NULL);
        if (!st)
            return AVERROR(ENOMEM);
        vid->video_index = st->index;
        if (vid->audio_index < 0) {
            av_log_ask_for_sample(s, "No audio packet before first video "
                                  "packet. Using default video time base.\n");
        }
        avpriv_set_pts_info(st, 64, 185, vid->sample_rate);
        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
        st->codec->codec_id   = AV_CODEC_ID_BETHSOFTVID;
        st->codec->width      = vid->width;
        st->codec->height     = vid->height;
    }
    st      = s->streams[vid->video_index];
    npixels = st->codec->width * st->codec->height;

    vidbuf_start = av_malloc(vidbuf_capacity = BUFFER_PADDING_SIZE);
    if(!vidbuf_start)
        return AVERROR(ENOMEM);

    // save the file position for the packet, include block type
    position = avio_tell(pb) - 1;

    vidbuf_start[vidbuf_nbytes++] = block_type;

    // get the current packet duration
    duration = vid->bethsoft_global_delay + avio_rl16(pb);

    // set the y offset if it exists (decoder header data should be in data section)
    if(block_type == VIDEO_YOFF_P_FRAME){
        if (avio_read(pb, &vidbuf_start[vidbuf_nbytes], 2) != 2) {
            ret = AVERROR(EIO);
            goto fail;
        }
        vidbuf_nbytes += 2;
    }

    do{
        vidbuf_start = av_fast_realloc(vidbuf_start, &vidbuf_capacity, vidbuf_nbytes + BUFFER_PADDING_SIZE);
        if(!vidbuf_start)
            return AVERROR(ENOMEM);

        code = avio_r8(pb);
        vidbuf_start[vidbuf_nbytes++] = code;

        if(code >= 0x80){ // rle sequence
            if(block_type == VIDEO_I_FRAME)
                vidbuf_start[vidbuf_nbytes++] = avio_r8(pb);
        } else if(code){ // plain sequence
            if (avio_read(pb, &vidbuf_start[vidbuf_nbytes], code) != code) {
                ret = AVERROR(EIO);
                goto fail;
            }
            vidbuf_nbytes += code;
        }
        bytes_copied += code & 0x7F;
        if(bytes_copied == npixels){ // sometimes no stop character is given, need to keep track of bytes copied
            // may contain a 0 byte even if read all pixels
            if(avio_r8(pb))
                avio_seek(pb, -1, SEEK_CUR);
            break;
        }
        if (bytes_copied > npixels) {
            ret = AVERROR_INVALIDDATA;
            goto fail;
        }
    } while(code);

    // copy data into packet
    if ((ret = av_new_packet(pkt, vidbuf_nbytes)) < 0)
        goto fail;
    memcpy(pkt->data, vidbuf_start, vidbuf_nbytes);
    av_free(vidbuf_start);

    pkt->pos = position;
    pkt->stream_index = vid->video_index;
    pkt->duration = duration;
    if (block_type == VIDEO_I_FRAME)
        pkt->flags |= AV_PKT_FLAG_KEY;

    /* if there is a new palette available, add it to packet side data */
    if (vid->palette) {
        uint8_t *pdata = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE,
                                                 BVID_PALETTE_SIZE);
        memcpy(pdata, vid->palette, BVID_PALETTE_SIZE);
        av_freep(&vid->palette);
    }

    vid->nframes--;  // used to check if all the frames were read
    return 0;
fail:
    av_free(vidbuf_start);
    return ret;
}
コード例 #17
0
ファイル: pictordec.c プロジェクト: adesurya/gst-mobile
static int decode_frame(AVCodecContext *avctx,
                        void *data, int *data_size,
                        AVPacket *avpkt)
{
    PicContext *s = avctx->priv_data;
    uint32_t *palette;
    int bits_per_plane, bpp, etype, esize, npal, pos_after_pal;
    int i, x, y, plane, tmp;

    bytestream2_init(&s->g, avpkt->data, avpkt->size);

    if (bytestream2_get_bytes_left(&s->g) < 11)
        return AVERROR_INVALIDDATA;

    if (bytestream2_get_le16u(&s->g) != 0x1234)
        return AVERROR_INVALIDDATA;

    s->width       = bytestream2_get_le16u(&s->g);
    s->height      = bytestream2_get_le16u(&s->g);
    bytestream2_skip(&s->g, 4);
    tmp            = bytestream2_get_byteu(&s->g);
    bits_per_plane = tmp & 0xF;
    s->nb_planes   = (tmp >> 4) + 1;
    bpp            = bits_per_plane * s->nb_planes;
    if (bits_per_plane > 8 || bpp < 1 || bpp > 32) {
        av_log_ask_for_sample(s, "unsupported bit depth\n");
        return AVERROR_INVALIDDATA;
    }

    if (bytestream2_peek_byte(&s->g) == 0xFF) {
        bytestream2_skip(&s->g, 2);
        etype = bytestream2_get_le16(&s->g);
        esize = bytestream2_get_le16(&s->g);
        if (bytestream2_get_bytes_left(&s->g) < esize)
            return AVERROR_INVALIDDATA;
    } else {
        etype = -1;
        esize = 0;
    }

    avctx->pix_fmt = PIX_FMT_PAL8;

    if (s->width != avctx->width && s->height != avctx->height) {
        if (av_image_check_size(s->width, s->height, 0, avctx) < 0)
            return -1;
        avcodec_set_dimensions(avctx, s->width, s->height);
        if (s->frame.data[0])
            avctx->release_buffer(avctx, &s->frame);
    }

    if (avctx->get_buffer(avctx, &s->frame) < 0){
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
        return -1;
    }
    memset(s->frame.data[0], 0, s->height * s->frame.linesize[0]);
    s->frame.pict_type           = AV_PICTURE_TYPE_I;
    s->frame.palette_has_changed = 1;

    pos_after_pal = bytestream2_tell(&s->g) + esize;
    palette = (uint32_t*)s->frame.data[1];
    if (etype == 1 && esize > 1 && bytestream2_peek_byte(&s->g) < 6) {
        int idx = bytestream2_get_byte(&s->g);
        npal = 4;
        for (i = 0; i < npal; i++)
            palette[i] = ff_cga_palette[ cga_mode45_index[idx][i] ];
    } else if (etype == 2) {
        npal = FFMIN(esize, 16);
        for (i = 0; i < npal; i++) {
            int pal_idx = bytestream2_get_byte(&s->g);
            palette[i]  = ff_cga_palette[FFMIN(pal_idx, 16)];
        }
    } else if (etype == 3) {
        npal = FFMIN(esize, 16);
        for (i = 0; i < npal; i++) {
            int pal_idx = bytestream2_get_byte(&s->g);
            palette[i]  = ff_ega_palette[FFMIN(pal_idx, 63)];
        }
    } else if (etype == 4 || etype == 5) {
        npal = FFMIN(esize / 3, 256);
        for (i = 0; i < npal; i++)
            palette[i] = bytestream2_get_be24(&s->g) << 2;
    } else {
        if (bpp == 1) {
            npal = 2;
            palette[0] = 0x000000;
            palette[1] = 0xFFFFFF;
        } else if (bpp == 2) {
            npal = 4;
            for (i = 0; i < npal; i++)
                palette[i] = ff_cga_palette[ cga_mode45_index[0][i] ];
        } else {
            npal = 16;
            memcpy(palette, ff_cga_palette, npal * 4);
        }
    }
    // fill remaining palette entries
    memset(palette + npal, 0, AVPALETTE_SIZE - npal * 4);
    // skip remaining palette bytes
    bytestream2_seek(&s->g, pos_after_pal, SEEK_SET);

    x = 0;
    y = s->height - 1;
    plane = 0;
    if (bytestream2_get_le16(&s->g)) {
        while (bytestream2_get_bytes_left(&s->g) >= 6) {
            int stop_size, marker, t1, t2;

            t1        = bytestream2_get_bytes_left(&s->g);
            t2        = bytestream2_get_le16(&s->g);
            stop_size = t1 - FFMIN(t1, t2);
            // ignore uncompressed block size
            bytestream2_skip(&s->g, 2);
            marker    = bytestream2_get_byte(&s->g);

            while (plane < s->nb_planes &&
                   bytestream2_get_bytes_left(&s->g) > stop_size) {
                int run = 1;
                int val = bytestream2_get_byte(&s->g);
                if (val == marker) {
                    run = bytestream2_get_byte(&s->g);
                    if (run == 0)
                        run = bytestream2_get_le16(&s->g);
                    val = bytestream2_get_byte(&s->g);
                }
                if (!bytestream2_get_bytes_left(&s->g))
                    break;

                if (bits_per_plane == 8) {
                    picmemset_8bpp(s, val, run, &x, &y);
                    if (y < 0)
                        break;
                } else {
                    picmemset(s, val, run, &x, &y, &plane, bits_per_plane);
                }
            }
        }
    } else {
        av_log_ask_for_sample(s, "uncompressed image\n");
        return avpkt->size;
    }

    *data_size = sizeof(AVFrame);
    *(AVFrame*)data = s->frame;
    return avpkt->size;
}
コード例 #18
0
ファイル: cdxl.c プロジェクト: KindDragon/FFmpeg
static int cdxl_decode_frame(AVCodecContext *avctx, void *data,
                             int *data_size, AVPacket *pkt)
{
    CDXLVideoContext *c = avctx->priv_data;
    AVFrame * const p = &c->frame;
    int ret, w, h, encoding, aligned_width, buf_size = pkt->size;
    const uint8_t *buf = pkt->data;

    if (buf_size < 32)
        return AVERROR_INVALIDDATA;
    encoding        = buf[1] & 7;
    c->format       = buf[1] & 0xE0;
    w               = AV_RB16(&buf[14]);
    h               = AV_RB16(&buf[16]);
    c->bpp          = buf[19];
    c->palette_size = AV_RB16(&buf[20]);
    c->palette      = buf + 32;
    c->video        = c->palette + c->palette_size;
    c->video_size   = buf_size - c->palette_size - 32;

    if (c->palette_size > 512)
        return AVERROR_INVALIDDATA;
    if (buf_size < c->palette_size + 32)
        return AVERROR_INVALIDDATA;
    if (c->bpp < 1)
        return AVERROR_INVALIDDATA;
    if (c->format != BIT_PLANAR && c->format != BIT_LINE) {
        av_log_ask_for_sample(avctx, "unsupported pixel format: 0x%0x\n", c->format);
        return AVERROR_PATCHWELCOME;
    }

    if ((ret = av_image_check_size(w, h, 0, avctx)) < 0)
        return ret;
    if (w != avctx->width || h != avctx->height)
        avcodec_set_dimensions(avctx, w, h);

    aligned_width = FFALIGN(c->avctx->width, 16);
    c->padded_bits  = aligned_width - c->avctx->width;
    if (c->video_size < aligned_width * avctx->height * c->bpp / 8)
        return AVERROR_INVALIDDATA;
    if (!encoding && c->palette_size && c->bpp <= 8) {
        avctx->pix_fmt = PIX_FMT_PAL8;
    } else if (encoding == 1 && (c->bpp == 6 || c->bpp == 8)) {
        if (c->palette_size != (1 << (c->bpp - 1)))
            return AVERROR_INVALIDDATA;
        avctx->pix_fmt = PIX_FMT_BGR24;
    } else {
        av_log_ask_for_sample(avctx, "unsupported encoding %d and bpp %d\n",
                              encoding, c->bpp);
        return AVERROR_PATCHWELCOME;
    }

    if (p->data[0])
        avctx->release_buffer(avctx, p);

    p->reference = 0;
    if ((ret = avctx->get_buffer(avctx, p)) < 0) {
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
        return ret;
    }
    p->pict_type = AV_PICTURE_TYPE_I;

    if (encoding) {
        av_fast_padded_malloc(&c->new_video, &c->new_video_size,
                              h * w + FF_INPUT_BUFFER_PADDING_SIZE);
        if (!c->new_video)
            return AVERROR(ENOMEM);
        if (c->bpp == 8)
            cdxl_decode_ham8(c);
        else
            cdxl_decode_ham6(c);
    } else {
        cdxl_decode_rgb(c);
    }
    *data_size      = sizeof(AVFrame);
    *(AVFrame*)data = c->frame;

    return buf_size;
}
コード例 #19
0
ファイル: sunrast.c プロジェクト: simock85/libav
static int sunrast_decode_frame(AVCodecContext *avctx, void *data,
                                int *data_size, AVPacket *avpkt) {
    const uint8_t *buf       = avpkt->data;
    const uint8_t *buf_end   = avpkt->data + avpkt->size;
    SUNRASTContext * const s = avctx->priv_data;
    AVFrame *picture         = data;
    AVFrame * const p        = &s->picture;
    unsigned int w, h, depth, type, maptype, maplength, stride, x, y, len, alen;
    uint8_t *ptr;
    const uint8_t *bufstart = buf;

    if (avpkt->size < 32)
        return AVERROR_INVALIDDATA;

    if (AV_RB32(buf) != RAS_MAGIC) {
        av_log(avctx, AV_LOG_ERROR, "this is not sunras encoded data\n");
        return -1;
    }

    w         = AV_RB32(buf + 4);
    h         = AV_RB32(buf + 8);
    depth     = AV_RB32(buf + 12);
    type      = AV_RB32(buf + 20);
    maptype   = AV_RB32(buf + 24);
    maplength = AV_RB32(buf + 28);
    buf      += 32;

    if (type == RT_FORMAT_TIFF || type == RT_FORMAT_IFF || type == RT_EXPERIMENTAL) {
        av_log_ask_for_sample(avctx, "unsupported (compression) type\n");
        return AVERROR_PATCHWELCOME;
    }
    if (type > RT_FORMAT_IFF) {
        av_log(avctx, AV_LOG_ERROR, "invalid (compression) type\n");
        return -1;
    }
    if (av_image_check_size(w, h, 0, avctx)) {
        av_log(avctx, AV_LOG_ERROR, "invalid image size\n");
        return -1;
    }
    if (maptype & ~1) {
        av_log(avctx, AV_LOG_ERROR, "invalid colormap type\n");
        return -1;
    }


    switch (depth) {
        case 1:
            avctx->pix_fmt = PIX_FMT_MONOWHITE;
            break;
        case 8:
            avctx->pix_fmt = PIX_FMT_PAL8;
            break;
        case 24:
            avctx->pix_fmt = (type == RT_FORMAT_RGB) ? PIX_FMT_RGB24 : PIX_FMT_BGR24;
            break;
        default:
            av_log(avctx, AV_LOG_ERROR, "invalid depth\n");
            return -1;
    }

    if (p->data[0])
        avctx->release_buffer(avctx, p);

    if (w != avctx->width || h != avctx->height)
        avcodec_set_dimensions(avctx, w, h);
    if (avctx->get_buffer(avctx, p) < 0) {
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
        return -1;
    }

    p->pict_type = AV_PICTURE_TYPE_I;

    if (buf_end - buf < maplength)
        return AVERROR_INVALIDDATA;

    if (depth != 8 && maplength) {
        av_log(avctx, AV_LOG_WARNING, "useless colormap found or file is corrupted, trying to recover\n");

    } else if (depth == 8) {
        unsigned int len = maplength / 3;

        if (!maplength) {
            av_log(avctx, AV_LOG_ERROR, "colormap expected\n");
            return -1;
        }
        if (maplength % 3 || maplength > 768) {
            av_log(avctx, AV_LOG_WARNING, "invalid colormap length\n");
            return -1;
        }

        ptr = p->data[1];
        for (x = 0; x < len; x++, ptr += 4)
            *(uint32_t *)ptr = (buf[x] << 16) + (buf[len + x] << 8) + buf[len + len + x];
    }

    buf += maplength;

    ptr    = p->data[0];
    stride = p->linesize[0];

    /* scanlines are aligned on 16 bit boundaries */
    len  = (depth * w + 7) >> 3;
    alen = len + (len & 1);

    if (type == RT_BYTE_ENCODED) {
        int value, run;
        uint8_t *end = ptr + h * stride;

        x = 0;
        while (ptr != end && buf < buf_end) {
            run = 1;
            if (buf_end - buf < 1)
                return AVERROR_INVALIDDATA;

            if ((value = *buf++) == 0x80) {
                run = *buf++ + 1;
                if (run != 1)
                    value = *buf++;
            }
            while (run--) {
                if (x < len)
                    ptr[x] = value;
                if (++x >= alen) {
                    x = 0;
                    ptr += stride;
                    if (ptr == end)
                        break;
                }
            }
        }
    } else {
        for (y = 0; y < h; y++) {
            if (buf_end - buf < len)
                break;
            memcpy(ptr, buf, len);
            ptr += stride;
            buf += alen;
        }
    }

    *picture   = s->picture;
    *data_size = sizeof(AVFrame);

    return buf - bufstart;
}
コード例 #20
0
ファイル: spdifdec.c プロジェクト: Tjoppen/FFmpeg
static int spdif_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    AVIOContext *pb = s->pb;
    enum IEC61937DataType data_type;
    enum CodecID codec_id;
    uint32_t state = 0;
    int pkt_size_bits, offset, ret;

    while (state != (AV_BSWAP16C(SYNCWORD1) << 16 | AV_BSWAP16C(SYNCWORD2))) {
        state = (state << 8) | avio_r8(pb);
        if (url_feof(pb))
            return AVERROR_EOF;
    }

    data_type = avio_rl16(pb);
    pkt_size_bits = avio_rl16(pb);

    if (pkt_size_bits % 16)
        av_log_ask_for_sample(s, "Packet does not end to a 16-bit boundary.");

    ret = av_new_packet(pkt, FFALIGN(pkt_size_bits, 16) >> 3);
    if (ret)
        return ret;

    pkt->pos = avio_tell(pb) - BURST_HEADER_SIZE;

    if (avio_read(pb, pkt->data, pkt->size) < pkt->size) {
        av_free_packet(pkt);
        return AVERROR_EOF;
    }
    ff_spdif_bswap_buf16((uint16_t *)pkt->data, (uint16_t *)pkt->data, pkt->size >> 1);

    ret = spdif_get_offset_and_codec(s, data_type, pkt->data,
                                     &offset, &codec_id);
    if (ret) {
        av_free_packet(pkt);
        return ret;
    }

    /* skip over the padding to the beginning of the next frame */
    avio_skip(pb, offset - pkt->size - BURST_HEADER_SIZE);

    if (!s->nb_streams) {
        /* first packet, create a stream */
        AVStream *st = av_new_stream(s, 0);
        if (!st) {
            av_free_packet(pkt);
            return AVERROR(ENOMEM);
        }
        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
        st->codec->codec_id = codec_id;
    } else if (codec_id != s->streams[0]->codec->codec_id) {
        av_log_missing_feature(s, "codec change in IEC 61937", 0);
        return AVERROR_PATCHWELCOME;
    }

    if (!s->bit_rate && s->streams[0]->codec->sample_rate)
        /* stream bitrate matches 16-bit stereo PCM bitrate for currently
           supported codecs */
        s->bit_rate = 2 * 16 * s->streams[0]->codec->sample_rate;

    return 0;
}
コード例 #21
0
ファイル: pictordec.c プロジェクト: AndyA/ffmbc
static int decode_frame(AVCodecContext *avctx,
                        void *data, int *data_size,
                        AVPacket *avpkt)
{
    PicContext *s = avctx->priv_data;
    int buf_size = avpkt->size;
    const uint8_t *buf = avpkt->data;
    const uint8_t *buf_end = avpkt->data + buf_size;
    uint32_t *palette;
    int bits_per_plane, bpp, etype, esize, npal;
    int i, x, y, plane;

    if (buf_size < 11)
        return AVERROR_INVALIDDATA;

    if (bytestream_get_le16(&buf) != 0x1234)
        return AVERROR_INVALIDDATA;
    s->width  = bytestream_get_le16(&buf);
    s->height = bytestream_get_le16(&buf);
    buf += 4;
    bits_per_plane    = *buf & 0xF;
    s->nb_planes      = (*buf++ >> 4) + 1;
    bpp               = s->nb_planes ? bits_per_plane*s->nb_planes : bits_per_plane;
    if (bits_per_plane > 8 || bpp < 1 || bpp > 32) {
        av_log_ask_for_sample(s, "unsupported bit depth\n");
        return AVERROR_INVALIDDATA;
    }

    if (*buf == 0xFF) {
        buf += 2;
        etype  = bytestream_get_le16(&buf);
        esize  = bytestream_get_le16(&buf);
        if (buf_end - buf < esize)
            return AVERROR_INVALIDDATA;
    } else {
        etype = -1;
        esize = 0;
    }

    avctx->pix_fmt = PIX_FMT_PAL8;

    if (s->width != avctx->width && s->height != avctx->height) {
        if (av_image_check_size(s->width, s->height, 0, avctx) < 0)
            return -1;
        avcodec_set_dimensions(avctx, s->width, s->height);
        if (s->frame.data[0])
            avctx->release_buffer(avctx, &s->frame);
    }

    if (avctx->get_buffer(avctx, &s->frame) < 0){
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
        return -1;
    }
    memset(s->frame.data[0], 0, s->height * s->frame.linesize[0]);
    s->frame.pict_type           = FF_I_TYPE;
    s->frame.palette_has_changed = 1;

    palette = (uint32_t*)s->frame.data[1];
    if (etype == 1 && esize > 1 && *buf < 6) {
        int idx = *buf;
        npal = 4;
        for (i = 0; i < npal; i++)
            palette[i] = ff_cga_palette[ cga_mode45_index[idx][i] ];
    } else if (etype == 2) {
        npal = FFMIN(esize, 16);
        for (i = 0; i < npal; i++)
            palette[i] = ff_cga_palette[ FFMIN(buf[i], 16)];
    } else if (etype == 3) {
        npal = FFMIN(esize, 16);
        for (i = 0; i < npal; i++)
            palette[i] = ff_ega_palette[ FFMIN(buf[i], 63)];
    } else if (etype == 4 || etype == 5) {
        npal = FFMIN(esize / 3, 256);
        for (i = 0; i < npal; i++)
            palette[i] = AV_RB24(buf + i*3) << 2;
    } else {
        if (bpp == 1) {
            npal = 2;
            palette[0] = 0x000000;
            palette[1] = 0xFFFFFF;
        } else if (bpp == 2) {
            npal = 4;
            for (i = 0; i < npal; i++)
                palette[i] = ff_cga_palette[ cga_mode45_index[0][i] ];
        } else {
            npal = 16;
            memcpy(palette, ff_cga_palette, npal * 4);
        }
    }
    // fill remaining palette entries
    memset(palette + npal, 0, AVPALETTE_SIZE - npal * 4);
    buf += esize;


    x = 0;
    y = s->height - 1;
    plane = 0;
    if (bytestream_get_le16(&buf)) {
        while (buf_end - buf >= 6) {
            const uint8_t *buf_pend = buf + FFMIN(AV_RL16(buf), buf_end - buf);
            //ignore uncompressed block size reported at buf[2]
            int marker = buf[4];
            buf += 5;

            while (plane < s->nb_planes && buf_pend - buf >= 1) {
                int run = 1;
                int val = *buf++;
                if (val == marker) {
                    run = *buf++;
                    if (run == 0)
                        run = bytestream_get_le16(&buf);
                    val = *buf++;
                }
                if (buf > buf_end)
                    break;

                if (bits_per_plane == 8) {
                    picmemset_8bpp(s, val, run, &x, &y);
                    if (y < 0)
                        break;
                } else {
                    picmemset(s, val, run, &x, &y, &plane, bits_per_plane);
                }
            }
        }
    } else {
        av_log_ask_for_sample(s, "uncompressed image\n");
        return buf_size;
    }

    *data_size = sizeof(AVFrame);
    *(AVFrame*)data = s->frame;
    return buf_size;
}
コード例 #22
0
ファイル: v210x.c プロジェクト: AdamCDunlap/hmc-robot-drivers
static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
{
    int y=0;
    int width= avctx->width;
    AVFrame *pic= avctx->coded_frame;
    const uint32_t *src= (const uint32_t *)avpkt->data;
    uint16_t *ydst, *udst, *vdst, *yend;

    if(pic->data[0])
        avctx->release_buffer(avctx, pic);

    if(avpkt->size < avctx->width * avctx->height * 8 / 3){
        av_log(avctx, AV_LOG_ERROR, "Packet too small\n");
        return -1;
    }

    if(avpkt->size > avctx->width * avctx->height * 8 / 3){
        av_log_ask_for_sample(avctx, "Probably padded data\n");
    }

    pic->reference= 0;
    if(avctx->get_buffer(avctx, pic) < 0)
        return -1;

    ydst= (uint16_t *)pic->data[0];
    udst= (uint16_t *)pic->data[1];
    vdst= (uint16_t *)pic->data[2];
    yend= ydst + width;
    pic->pict_type= AV_PICTURE_TYPE_I;
    pic->key_frame= 1;

    for(;;){
        uint32_t v= av_be2ne32(*src++);
        *udst++= (v>>16) & 0xFFC0;
        *ydst++= (v>>6 ) & 0xFFC0;
        *vdst++= (v<<4 ) & 0xFFC0;

        v= av_be2ne32(*src++);
        *ydst++= (v>>16) & 0xFFC0;

        if(ydst >= yend){
            ydst+= pic->linesize[0]/2 - width;
            udst+= pic->linesize[1]/2 - width/2;
            vdst+= pic->linesize[2]/2 - width/2;
            yend= ydst + width;
            if(++y >= avctx->height)
                break;
        }

        *udst++= (v>>6 ) & 0xFFC0;
        *ydst++= (v<<4 ) & 0xFFC0;

        v= av_be2ne32(*src++);
        *vdst++= (v>>16) & 0xFFC0;
        *ydst++= (v>>6 ) & 0xFFC0;

        if(ydst >= yend){
            ydst+= pic->linesize[0]/2 - width;
            udst+= pic->linesize[1]/2 - width/2;
            vdst+= pic->linesize[2]/2 - width/2;
            yend= ydst + width;
            if(++y >= avctx->height)
                break;
        }

        *udst++= (v<<4 ) & 0xFFC0;

        v= av_be2ne32(*src++);
        *ydst++= (v>>16) & 0xFFC0;
        *vdst++= (v>>6 ) & 0xFFC0;
        *ydst++= (v<<4 ) & 0xFFC0;
        if(ydst >= yend){
            ydst+= pic->linesize[0]/2 - width;
            udst+= pic->linesize[1]/2 - width/2;
            vdst+= pic->linesize[2]/2 - width/2;
            yend= ydst + width;
            if(++y >= avctx->height)
                break;
        }
    }

    *data_size=sizeof(AVFrame);
    *(AVFrame*)data= *avctx->coded_frame;

    return avpkt->size;
}
コード例 #23
0
ファイル: ansi.c プロジェクト: AirDev/linphone-android
/**
 * Execute ANSI escape code
 * @param <0 error
 */
static int execute_code(AVCodecContext * avctx, int c)
{
    AnsiContext *s = avctx->priv_data;
    int ret, i, width, height;
    switch(c) {
    case 'A': //Cursor Up
        s->y = FFMAX(s->y - (s->nb_args > 0 ? s->args[0]*s->font_height : s->font_height), 0);
        break;
    case 'B': //Cursor Down
        s->y = FFMIN(s->y + (s->nb_args > 0 ? s->args[0]*s->font_height : s->font_height), avctx->height - s->font_height);
        break;
    case 'C': //Cursor Right
        s->x = FFMIN(s->x + (s->nb_args > 0 ? s->args[0]*FONT_WIDTH : FONT_WIDTH), avctx->width  - FONT_WIDTH);
        break;
    case 'D': //Cursor Left
        s->x = FFMAX(s->x - (s->nb_args > 0 ? s->args[0]*FONT_WIDTH : FONT_WIDTH), 0);
        break;
    case 'H': //Cursor Position
    case 'f': //Horizontal and Vertical Position
        s->y = s->nb_args > 0 ? av_clip((s->args[0] - 1)*s->font_height, 0, avctx->height - s->font_height) : 0;
        s->x = s->nb_args > 1 ? av_clip((s->args[1] - 1)*FONT_WIDTH,     0, avctx->width  - FONT_WIDTH) : 0;
        break;
    case 'h': //set creen mode
    case 'l': //reset screen mode
        if (s->nb_args < 2)
            s->args[0] = DEFAULT_SCREEN_MODE;
        switch(s->args[0]) {
        case 0: case 1: case 4: case 5: case 13: case 19: //320x200 (25 rows)
            s->font = ff_cga_font;
            s->font_height = 8;
            width  = 40<<3;
            height = 25<<3;
            break;
        case 2: case 3: //640x400 (25 rows)
            s->font = ff_vga16_font;
            s->font_height = 16;
            width  = 80<<3;
            height = 25<<4;
            break;
        case 6: case 14: //640x200 (25 rows)
            s->font = ff_cga_font;
            s->font_height = 8;
            width  = 80<<3;
            height = 25<<3;
            break;
        case 7: //set line wrapping
            break;
        case 15: case 16: //640x350 (43 rows)
            s->font = ff_cga_font;
            s->font_height = 8;
            width  = 80<<3;
            height = 43<<3;
            break;
        case 17: case 18: //640x480 (60 rows)
            s->font = ff_cga_font;
            s->font_height = 8;
            width  = 80<<3;
            height = 60<<4;
            break;
        default:
            av_log_ask_for_sample(avctx, "unsupported screen mode\n");
        }
        if (width != avctx->width || height != avctx->height) {
            if (s->frame.data[0])
                avctx->release_buffer(avctx, &s->frame);
            avcodec_set_dimensions(avctx, width, height);
            ret = avctx->get_buffer(avctx, &s->frame);
            if (ret < 0) {
                av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
                return ret;
            }
            s->frame.pict_type           = FF_I_TYPE;
            s->frame.palette_has_changed = 1;
            memcpy(s->frame.data[1], ff_cga_palette, 16 * 4);
            erase_screen(avctx);
        } else if (c == 'l') {
            erase_screen(avctx);
        }
        break;
    case 'J': //Erase in Page
        switch (s->args[0]) {
        case 0:
            erase_line(avctx, s->x, avctx->width - s->x);
            if (s->y < avctx->height - s->font_height)
                memset(s->frame.data[0] + (s->y + s->font_height)*s->frame.linesize[0],
                    DEFAULT_BG_COLOR, (avctx->height - s->y - s->font_height)*s->frame.linesize[0]);
            break;
        case 1:
            erase_line(avctx, 0, s->x);
            if (s->y > 0)
                memset(s->frame.data[0], DEFAULT_BG_COLOR, s->y * s->frame.linesize[0]);
            break;
        case 2:
            erase_screen(avctx);
        }
        break;
    case 'K': //Erase in Line
        switch(s->args[0]) {
        case 0:
            erase_line(avctx, s->x, avctx->width - s->x);
            break;
        case 1:
            erase_line(avctx, 0, s->x);
            break;
        case 2:
            erase_line(avctx, 0, avctx->width);
        }
        break;
    case 'm': //Select Graphics Rendition
        if (s->nb_args == 0) {
            s->nb_args = 1;
            s->args[0] = 0;
        }
        for (i = 0; i < FFMIN(s->nb_args, MAX_NB_ARGS); i++) {
            int m = s->args[i];
            if (m == 0) {
                s->attributes = 0;
                s->fg = DEFAULT_FG_COLOR;
                s->bg = DEFAULT_BG_COLOR;
            } else if (m == 1 || m == 2 || m == 4 || m == 5 || m == 7 || m == 8) {
                s->attributes |= 1 << (m - 1);
            } else if (m >= 30 && m <= 38) {
                s->fg = ansi_to_cga[m - 30];
            } else if (m == 39) {
                s->fg = ansi_to_cga[DEFAULT_FG_COLOR];
            } else if (m >= 40 && m <= 47) {
                s->bg = ansi_to_cga[m - 40];
            } else if (m == 49) {
                s->fg = ansi_to_cga[DEFAULT_BG_COLOR];
            } else {
                av_log_ask_for_sample(avctx, "unsupported rendition parameter\n");
            }
        }
        break;
    case 'n': //Device Status Report
    case 'R': //report current line and column
        /* ignore */
        break;
    case 's': //Save Cursor Position
        s->sx = s->x;
        s->sy = s->y;
        break;
    case 'u': //Restore Cursor Position
        s->x = av_clip(s->sx, 0, avctx->width  - FONT_WIDTH);
        s->y = av_clip(s->sy, 0, avctx->height - s->font_height);
        break;
    default:
        av_log_ask_for_sample(avctx, "unsupported escape code\n");
        break;
    }
    return 0;
}
コード例 #24
0
ファイル: smjpegdec.c プロジェクト: komh/kmp
static int smjpeg_read_header(AVFormatContext *s)
{
    SMJPEGContext *sc = s->priv_data;
    AVStream *ast = NULL, *vst = NULL;
    AVIOContext *pb = s->pb;
    uint32_t version, htype, hlength, duration;
    char *comment;

    avio_skip(pb, 8); // magic
    version = avio_rb32(pb);
    if (version)
        av_log_ask_for_sample(s, "unknown version %d\n", version);

    duration = avio_rb32(pb); // in msec

    while (!pb->eof_reached) {
        htype = avio_rl32(pb);
        switch (htype) {
        case SMJPEG_TXT:
            hlength = avio_rb32(pb);
            if (!hlength || hlength > 512)
                return AVERROR_INVALIDDATA;
            comment = av_malloc(hlength + 1);
            if (!comment)
                return AVERROR(ENOMEM);
            if (avio_read(pb, comment, hlength) != hlength) {
                av_freep(&comment);
                av_log(s, AV_LOG_ERROR, "error when reading comment\n");
                return AVERROR_INVALIDDATA;
            }
            comment[hlength] = 0;
            av_dict_set(&s->metadata, "comment", comment,
                        AV_DICT_DONT_STRDUP_VAL);
            break;
        case SMJPEG_SND:
            if (ast) {
                av_log_ask_for_sample(s, "multiple audio streams not supported\n");
                return AVERROR_INVALIDDATA;
            }
            hlength = avio_rb32(pb);
            if (hlength < 8)
                return AVERROR_INVALIDDATA;
            ast = avformat_new_stream(s, 0);
            if (!ast)
                return AVERROR(ENOMEM);
            ast->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
            ast->codec->sample_rate = avio_rb16(pb);
            ast->codec->bits_per_coded_sample = avio_r8(pb);
            ast->codec->channels    = avio_r8(pb);
            ast->codec->codec_tag   = avio_rl32(pb);
            ast->codec->codec_id    = ff_codec_get_id(ff_codec_smjpeg_audio_tags,
                                                      ast->codec->codec_tag);
            ast->duration           = duration;
            sc->audio_stream_index  = ast->index;
            avpriv_set_pts_info(ast, 32, 1, 1000);
            avio_skip(pb, hlength - 8);
            break;
        case SMJPEG_VID:
            if (vst) {
                av_log_ask_for_sample(s, "multiple video streams not supported\n");
                return AVERROR_INVALIDDATA;
            }
            hlength = avio_rb32(pb);
            if (hlength < 12)
                return AVERROR_INVALIDDATA;
            avio_skip(pb, 4); // number of frames
            vst = avformat_new_stream(s, 0);
            if (!vst)
                return AVERROR(ENOMEM);
            vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
            vst->codec->width      = avio_rb16(pb);
            vst->codec->height     = avio_rb16(pb);
            vst->codec->codec_tag  = avio_rl32(pb);
            vst->codec->codec_id   = ff_codec_get_id(ff_codec_smjpeg_video_tags,
                                                     vst->codec->codec_tag);
            vst->duration          = duration;
            sc->video_stream_index = vst->index;
            avpriv_set_pts_info(vst, 32, 1, 1000);
            avio_skip(pb, hlength - 12);
            break;
        case SMJPEG_HEND:
            return 0;
        default:
            av_log(s, AV_LOG_ERROR, "unknown header %x\n", htype);
            return AVERROR_INVALIDDATA;
        }
    }

    return AVERROR_EOF;
}
コード例 #25
0
/* Returns the number of bytes consumed from the bytestream. Returns -1 if
 * there was an error while decoding the header */
static int truemotion1_decode_header(TrueMotion1Context *s)
{
    int i;
    int width_shift = 0;
    int new_pix_fmt;
    struct frame_header header;
    uint8_t header_buffer[128];  /* logical maximum size of the header */
    const uint8_t *sel_vector_table;

    header.header_size = ((s->buf[0] >> 5) | (s->buf[0] << 3)) & 0x7f;
    if (s->buf[0] < 0x10)
    {
        av_log(s->avctx, AV_LOG_ERROR, "invalid header size (%d)\n", s->buf[0]);
        return -1;
    }

    /* unscramble the header bytes with a XOR operation */
    memset(header_buffer, 0, 128);
    for (i = 1; i < header.header_size; i++)
        header_buffer[i - 1] = s->buf[i] ^ s->buf[i + 1];

    header.compression = header_buffer[0];
    header.deltaset = header_buffer[1];
    header.vectable = header_buffer[2];
    header.ysize = AV_RL16(&header_buffer[3]);
    header.xsize = AV_RL16(&header_buffer[5]);
    header.checksum = AV_RL16(&header_buffer[7]);
    header.version = header_buffer[9];
    header.header_type = header_buffer[10];
    header.flags = header_buffer[11];
    header.control = header_buffer[12];

    /* Version 2 */
    if (header.version >= 2)
    {
        if (header.header_type > 3)
        {
            av_log(s->avctx, AV_LOG_ERROR, "invalid header type (%d)\n", header.header_type);
            return -1;
        } else if ((header.header_type == 2) || (header.header_type == 3)) {
            s->flags = header.flags;
            if (!(s->flags & FLAG_INTERFRAME))
                s->flags |= FLAG_KEYFRAME;
        } else
            s->flags = FLAG_KEYFRAME;
    } else /* Version 1 */
        s->flags = FLAG_KEYFRAME;

    if (s->flags & FLAG_SPRITE) {
        av_log_ask_for_sample(s->avctx, "SPRITE frame found.\n");
        /* FIXME header.width, height, xoffset and yoffset aren't initialized */
#if 0
        s->w = header.width;
        s->h = header.height;
        s->x = header.xoffset;
        s->y = header.yoffset;
#else
        return -1;
#endif
    } else {
        s->w = header.xsize;
        s->h = header.ysize;
        if (header.header_type < 2) {
            if ((s->w < 213) && (s->h >= 176))
            {
                s->flags |= FLAG_INTERPOLATED;
                av_log_ask_for_sample(s->avctx, "INTERPOLATION selected.\n");
            }
        }
    }

    if (header.compression >= 17) {
        av_log(s->avctx, AV_LOG_ERROR, "invalid compression type (%d)\n", header.compression);
        return -1;
    }

    if ((header.deltaset != s->last_deltaset) ||
        (header.vectable != s->last_vectable))
        select_delta_tables(s, header.deltaset);

    if ((header.compression & 1) && header.header_type)
        sel_vector_table = pc_tbl2;
    else {
        if (header.vectable > 0 && header.vectable < 4)
            sel_vector_table = tables[header.vectable - 1];
        else {
            av_log(s->avctx, AV_LOG_ERROR, "invalid vector table id (%d)\n", header.vectable);
            return -1;
        }
    }

    if (compression_types[header.compression].algorithm == ALGO_RGB24H) {
        new_pix_fmt = PIX_FMT_RGB32;
        width_shift = 1;
    } else
        new_pix_fmt = PIX_FMT_RGB555; // RGB565 is supported as well

    s->w >>= width_shift;
    if (av_image_check_size(s->w, s->h, 0, s->avctx) < 0)
        return -1;

    if (s->w != s->avctx->width || s->h != s->avctx->height ||
        new_pix_fmt != s->avctx->pix_fmt) {
        if (s->frame.data[0])
            s->avctx->release_buffer(s->avctx, &s->frame);
        s->avctx->sample_aspect_ratio = (AVRational){ 1 << width_shift, 1 };
        s->avctx->pix_fmt = new_pix_fmt;
        avcodec_set_dimensions(s->avctx, s->w, s->h);
        av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int));
    }

    /* There is 1 change bit per 4 pixels, so each change byte represents
     * 32 pixels; divide width by 4 to obtain the number of change bits and
     * then round up to the nearest byte. */
    s->mb_change_bits_row_size = ((s->avctx->width >> (2 - width_shift)) + 7) >> 3;

    if ((header.deltaset != s->last_deltaset) || (header.vectable != s->last_vectable))
    {
        if (compression_types[header.compression].algorithm == ALGO_RGB24H)
            gen_vector_table24(s, sel_vector_table);
        else
        if (s->avctx->pix_fmt == PIX_FMT_RGB555)
            gen_vector_table15(s, sel_vector_table);
        else
            gen_vector_table16(s, sel_vector_table);
    }

    /* set up pointers to the other key data chunks */
    s->mb_change_bits = s->buf + header.header_size;
    if (s->flags & FLAG_KEYFRAME) {
        /* no change bits specified for a keyframe; only index bytes */
        s->index_stream = s->mb_change_bits;
    } else {
        /* one change bit per 4x4 block */
        s->index_stream = s->mb_change_bits +
            (s->mb_change_bits_row_size * (s->avctx->height >> 2));
    }
    s->index_stream_size = s->size - (s->index_stream - s->buf);

    s->last_deltaset = header.deltaset;
    s->last_vectable = header.vectable;
    s->compression = header.compression;
    s->block_width = compression_types[header.compression].block_width;
    s->block_height = compression_types[header.compression].block_height;
    s->block_type = compression_types[header.compression].block_type;

    if (s->avctx->debug & FF_DEBUG_PICT_INFO)
        av_log(s->avctx, AV_LOG_INFO, "tables: %d / %d c:%d %dx%d t:%d %s%s%s%s\n",
            s->last_deltaset, s->last_vectable, s->compression, s->block_width,
            s->block_height, s->block_type,
            s->flags & FLAG_KEYFRAME ? " KEY" : "",
            s->flags & FLAG_INTERFRAME ? " INTER" : "",
            s->flags & FLAG_SPRITE ? " SPRITE" : "",
            s->flags & FLAG_INTERPOLATED ? " INTERPOL" : "");

    return header.header_size;
}
コード例 #26
0
ファイル: brstm.c プロジェクト: svn2github/MPlayer-SB
static int read_header(AVFormatContext *s)
{
    BRSTMDemuxContext *b = s->priv_data;
    int bom, major, minor, codec, chunk;
    int64_t pos, h1offset, toffset;
    uint32_t size, start, asize;
    AVStream *st;
    int ret = AVERROR_EOF;

    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);
    st->codec->codec_type = AVMEDIA_TYPE_AUDIO;

    avio_skip(s->pb, 4);

    bom = avio_rb16(s->pb);
    if (bom != 0xFEFF && bom != 0xFFFE) {
        av_log(s, AV_LOG_ERROR, "invalid byte order: %X\n", bom);
        return AVERROR_INVALIDDATA;
    }
    if (bom == 0xFFFE) {
        av_log_ask_for_sample(s, "unsupported byte order");
        return AVERROR_PATCHWELCOME;
    }

    major = avio_r8(s->pb);
    minor = avio_r8(s->pb);
    avio_skip(s->pb, 4); // size of file
    size = avio_rb16(s->pb);
    if (size < 14)
        return AVERROR_INVALIDDATA;

    avio_skip(s->pb, size - 14);
    pos = avio_tell(s->pb);
    if (avio_rl32(s->pb) != MKTAG('H','E','A','D'))
        return AVERROR_INVALIDDATA;
    size = avio_rb32(s->pb);
    if (size < 256)
        return AVERROR_INVALIDDATA;
    avio_skip(s->pb, 4); // unknown
    h1offset = avio_rb32(s->pb);
    if (h1offset > size)
        return AVERROR_INVALIDDATA;
    avio_skip(s->pb, 12);
    toffset = avio_rb32(s->pb) + 16LL;
    if (toffset > size)
        return AVERROR_INVALIDDATA;

    avio_skip(s->pb, pos + h1offset + 8 - avio_tell(s->pb));
    codec = avio_r8(s->pb);

    switch (codec) {
    case 0: codec = AV_CODEC_ID_PCM_S8_PLANAR;    break;
    case 1: codec = AV_CODEC_ID_PCM_S16BE_PLANAR; break;
    case 2: codec = AV_CODEC_ID_ADPCM_THP;        break;
    default:
        av_log_ask_for_sample(s, "unsupported codec: %d", codec);
        return AVERROR_PATCHWELCOME;
    }

    avio_skip(s->pb, 1); // loop flag
    st->codec->codec_id = codec;
    st->codec->channels = avio_r8(s->pb);
    if (!st->codec->channels)
        return AVERROR_INVALIDDATA;

    avio_skip(s->pb, 1); // padding
    st->codec->sample_rate = avio_rb16(s->pb);
    if (!st->codec->sample_rate)
        return AVERROR_INVALIDDATA;

    avio_skip(s->pb, 2); // padding
    avio_skip(s->pb, 4); // loop start sample
    st->start_time = 0;
    st->duration = avio_rb32(s->pb);
    avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);

    start = avio_rb32(s->pb);
    b->current_block = 0;
    b->block_count = avio_rb32(s->pb);
    if (b->block_count > UINT16_MAX) {
        av_log(s, AV_LOG_WARNING, "too many blocks: %u\n", b->block_count);
        return AVERROR_INVALIDDATA;
    }

    b->block_size = avio_rb32(s->pb);
    if (b->block_size > UINT16_MAX / st->codec->channels)
        return AVERROR_INVALIDDATA;
    b->block_size *= st->codec->channels;

    b->samples_per_block = avio_rb32(s->pb);
    b->last_block_used_bytes = avio_rb32(s->pb);
    if (b->last_block_used_bytes > UINT16_MAX / st->codec->channels)
        return AVERROR_INVALIDDATA;
    b->last_block_used_bytes *= st->codec->channels;

    avio_skip(s->pb, 4); // last block samples
    avio_skip(s->pb, 4); // last block size

    if (codec == AV_CODEC_ID_ADPCM_THP) {
        int ch;

        avio_skip(s->pb, pos + toffset - avio_tell(s->pb));
        toffset = avio_rb32(s->pb) + 16LL;
        if (toffset > size)
            return AVERROR_INVALIDDATA;

        avio_skip(s->pb, pos + toffset - avio_tell(s->pb));
        b->table = av_mallocz(32 * st->codec->channels);
        if (!b->table)
            return AVERROR(ENOMEM);

        for (ch = 0; ch < st->codec->channels; ch++) {
            if (avio_read(s->pb, b->table + ch * 32, 32) != 32) {
                ret = AVERROR_INVALIDDATA;
                goto fail;
            }
            avio_skip(s->pb, 24);
        }
    }

    if (size < (avio_tell(s->pb) - pos)) {
        ret = AVERROR_INVALIDDATA;
        goto fail;
    }
    avio_skip(s->pb, size - (avio_tell(s->pb) - pos));

    while (!url_feof(s->pb)) {
        chunk = avio_rl32(s->pb);
        size  = avio_rb32(s->pb);
        if (size < 8) {
            ret = AVERROR_INVALIDDATA;
            goto fail;
        }
        size -= 8;
        switch (chunk) {
        case MKTAG('A','D','P','C'):
            if (codec != AV_CODEC_ID_ADPCM_THP)
                goto skip;

            asize = b->block_count * st->codec->channels * 4;
            if (size < asize) {
                ret = AVERROR_INVALIDDATA;
                goto fail;
            }
            if (b->adpc) {
                av_log(s, AV_LOG_WARNING, "skipping additonal ADPC chunk\n");
                goto skip;
            } else {
                b->adpc = av_mallocz(asize);
                if (!b->adpc) {
                    ret = AVERROR(ENOMEM);
                    goto fail;
                }
                avio_read(s->pb, b->adpc, asize);
                avio_skip(s->pb, size - asize);
            }
            break;
        case MKTAG('D','A','T','A'):
            if ((start < avio_tell(s->pb)) ||
                (!b->adpc && codec == AV_CODEC_ID_ADPCM_THP)) {
                ret = AVERROR_INVALIDDATA;
                goto fail;
            }
            avio_skip(s->pb, start - avio_tell(s->pb));
            return 0;
        default:
            av_log(s, AV_LOG_WARNING, "skipping unknown chunk: %X\n", chunk);
skip:
            avio_skip(s->pb, size);
        }
    }

fail:
    read_close(s);

    return ret;
}
コード例 #27
0
ファイル: cook.c プロジェクト: GenomeXP/mpc-hc
/**
 * Cook initialization
 *
 * @param avctx     pointer to the AVCodecContext
 */
static av_cold int cook_decode_init(AVCodecContext *avctx)
{
    COOKContext *q = avctx->priv_data;
    const uint8_t *edata_ptr = avctx->extradata;
    const uint8_t *edata_ptr_end = edata_ptr + avctx->extradata_size;
    int extradata_size = avctx->extradata_size;
    int s = 0;
    unsigned int channel_mask = 0;
    int samples_per_frame = 0;
    int ret;
    q->avctx = avctx;

    /* Take care of the codec specific extradata. */
    if (extradata_size <= 0) {
        av_log(avctx, AV_LOG_ERROR, "Necessary extradata missing!\n");
        return AVERROR_INVALIDDATA;
    }
    av_log(avctx, AV_LOG_DEBUG, "codecdata_length=%d\n", avctx->extradata_size);

    /* Take data from the AVCodecContext (RM container). */
    if (!avctx->channels) {
        av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n");
        return AVERROR_INVALIDDATA;
    }

    /* Initialize RNG. */
    av_lfg_init(&q->random_state, 0);

    ff_dsputil_init(&q->dsp, avctx);

    while (edata_ptr < edata_ptr_end) {
        /* 8 for mono, 16 for stereo, ? for multichannel
           Swap to right endianness so we don't need to care later on. */
        if (extradata_size >= 8) {
            q->subpacket[s].cookversion = bytestream_get_be32(&edata_ptr);
            samples_per_frame           = bytestream_get_be16(&edata_ptr);
            q->subpacket[s].subbands = bytestream_get_be16(&edata_ptr);
            extradata_size -= 8;
        }
        if (extradata_size >= 8) {
            bytestream_get_be32(&edata_ptr);    // Unknown unused
            q->subpacket[s].js_subband_start = bytestream_get_be16(&edata_ptr);
            q->subpacket[s].js_vlc_bits = bytestream_get_be16(&edata_ptr);
            extradata_size -= 8;
        }

        /* Initialize extradata related variables. */
        q->subpacket[s].samples_per_channel = samples_per_frame / avctx->channels;
        q->subpacket[s].bits_per_subpacket = avctx->block_align * 8;

        /* Initialize default data states. */
        q->subpacket[s].log2_numvector_size = 5;
        q->subpacket[s].total_subbands = q->subpacket[s].subbands;
        q->subpacket[s].num_channels = 1;

        /* Initialize version-dependent variables */

        av_log(avctx, AV_LOG_DEBUG, "subpacket[%i].cookversion=%x\n", s,
               q->subpacket[s].cookversion);
        q->subpacket[s].joint_stereo = 0;
        switch (q->subpacket[s].cookversion) {
        case MONO:
            if (avctx->channels != 1) {
                av_log_ask_for_sample(avctx, "Container channels != 1.\n");
                return AVERROR_PATCHWELCOME;
            }
            av_log(avctx, AV_LOG_DEBUG, "MONO\n");
            break;
        case STEREO:
            if (avctx->channels != 1) {
                q->subpacket[s].bits_per_subpdiv = 1;
                q->subpacket[s].num_channels = 2;
            }
            av_log(avctx, AV_LOG_DEBUG, "STEREO\n");
            break;
        case JOINT_STEREO:
            if (avctx->channels != 2) {
                av_log_ask_for_sample(avctx, "Container channels != 2.\n");
                return AVERROR_PATCHWELCOME;
            }
            av_log(avctx, AV_LOG_DEBUG, "JOINT_STEREO\n");
            if (avctx->extradata_size >= 16) {
                q->subpacket[s].total_subbands = q->subpacket[s].subbands +
                                                 q->subpacket[s].js_subband_start;
                q->subpacket[s].joint_stereo = 1;
                q->subpacket[s].num_channels = 2;
            }
            if (q->subpacket[s].samples_per_channel > 256) {
                q->subpacket[s].log2_numvector_size = 6;
            }
            if (q->subpacket[s].samples_per_channel > 512) {
                q->subpacket[s].log2_numvector_size = 7;
            }
            break;
        case MC_COOK:
            av_log(avctx, AV_LOG_DEBUG, "MULTI_CHANNEL\n");
            if (extradata_size >= 4)
                channel_mask |= q->subpacket[s].channel_mask = bytestream_get_be32(&edata_ptr);

            if (av_get_channel_layout_nb_channels(q->subpacket[s].channel_mask) > 1) {
                q->subpacket[s].total_subbands = q->subpacket[s].subbands +
                                                 q->subpacket[s].js_subband_start;
                q->subpacket[s].joint_stereo = 1;
                q->subpacket[s].num_channels = 2;
                q->subpacket[s].samples_per_channel = samples_per_frame >> 1;

                if (q->subpacket[s].samples_per_channel > 256) {
                    q->subpacket[s].log2_numvector_size = 6;
                }
                if (q->subpacket[s].samples_per_channel > 512) {
                    q->subpacket[s].log2_numvector_size = 7;
                }
            } else
                q->subpacket[s].samples_per_channel = samples_per_frame;

            break;
        default:
            av_log_ask_for_sample(avctx, "Unknown Cook version.\n");
            return AVERROR_PATCHWELCOME;
        }
コード例 #28
0
ファイル: anm.c プロジェクト: biddyweb/libav
static int decode_frame(AVCodecContext *avctx,
                        void *data, int *data_size,
                        AVPacket *avpkt)
{
    AnmContext *s = avctx->priv_data;
    const uint8_t *buf = avpkt->data;
    const int buf_size = avpkt->size;
    const uint8_t *buf_end = buf + buf_size;
    uint8_t *dst, *dst_end;
    int count;

    if(avctx->reget_buffer(avctx, &s->frame) < 0){
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
        return -1;
    }
    dst     = s->frame.data[0];
    dst_end = s->frame.data[0] + s->frame.linesize[0]*avctx->height;

    if (buf[0] != 0x42) {
        av_log_ask_for_sample(avctx, "unknown record type\n");
        return buf_size;
    }
    if (buf[1]) {
        av_log_ask_for_sample(avctx, "padding bytes not supported\n");
        return buf_size;
    }
    buf += 4;

    s->x = 0;
    do {
        /* if statements are ordered by probability */
#define OP(buf, pixel, count) \
    op(&dst, dst_end, (buf), buf_end, (pixel), (count), &s->x, avctx->width, s->frame.linesize[0])

        int type = bytestream_get_byte(&buf);
        count = type & 0x7F;
        type >>= 7;
        if (count) {
            if (OP(type ? NULL : &buf, -1, count)) break;
        } else if (!type) {
            int pixel;
            count = bytestream_get_byte(&buf);  /* count==0 gives nop */
            pixel = bytestream_get_byte(&buf);
            if (OP(NULL, pixel, count)) break;
        } else {
            int pixel;
            type = bytestream_get_le16(&buf);
            count = type & 0x3FFF;
            type >>= 14;
            if (!count) {
                if (type == 0)
                    break; // stop
                if (type == 2) {
                    av_log_ask_for_sample(avctx, "unknown opcode");
                    return AVERROR_INVALIDDATA;
                }
                continue;
            }
            pixel = type == 3 ? bytestream_get_byte(&buf) : -1;
            if (type == 1) count += 0x4000;
            if (OP(type == 2 ? &buf : NULL, pixel, count)) break;
        }
    } while (buf + 1 < buf_end);

    *data_size = sizeof(AVFrame);
    *(AVFrame*)data = s->frame;
    return buf_size;
}
コード例 #29
0
ファイル: iff.c プロジェクト: acharneski/FFmpeg
static int iff_read_header(AVFormatContext *s)
{
    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
    uint8_t fmt[16];
    int fmt_size;

    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:
        case ID_DBOD:
            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_DPEL:
            if (data_size < 4 || (data_size & 3))
                return AVERROR_INVALIDDATA;
            if ((fmt_size = avio_read(pb, fmt, sizeof(fmt))) < 0)
                return fmt_size;
            if (fmt_size == sizeof(deep_rgb24) && !memcmp(fmt, deep_rgb24, sizeof(deep_rgb24)))
                st->codec->pix_fmt = PIX_FMT_RGB24;
            else if (fmt_size == sizeof(deep_rgba) && !memcmp(fmt, deep_rgba, sizeof(deep_rgba)))
                st->codec->pix_fmt = PIX_FMT_RGBA;
            else {
                av_log_ask_for_sample(s, "unsupported color format\n");
                return AVERROR_PATCHWELCOME;
            }
            break;

        case ID_DGBL:
            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);
            iff->bitmap_compression          = avio_rb16(pb);
            if (iff->bitmap_compression != 0) {
                av_log(s, AV_LOG_ERROR,
                       "compression %i not supported\n", iff->bitmap_compression);
                return AVERROR_PATCHWELCOME;
            }
            st->sample_aspect_ratio.num      = avio_r8(pb);
            st->sample_aspect_ratio.den      = avio_r8(pb);
            st->codec->bits_per_coded_sample = 24;
            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 = AV_CODEC_ID_PCM_S8_PLANAR;
            break;
        case COMP_FIB:
            st->codec->codec_id = AV_CODEC_ID_8SVX_FIB;
            break;
        case COMP_EXP:
            st->codec->codec_id = AV_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 = AV_CODEC_ID_IFF_ILBM;
            break;
        case BITMAP_BYTERUN1:
            st->codec->codec_id = AV_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;
}
コード例 #30
0
ファイル: xwma.c プロジェクト: LibXenonProject/libav-libxenon
static int xwma_read_header(AVFormatContext *s, AVFormatParameters *ap)
{
    int64_t size, av_uninit(data_size);
    int ret;
    uint32_t dpds_table_size = 0;
    uint32_t *dpds_table = 0;
    unsigned int tag;
    AVIOContext *pb = s->pb;
    AVStream *st;
    XWMAContext *xwma = s->priv_data;
    int i;

    /* The following code is mostly copied from wav.c, with some
     * minor alterations.
     */

    /* check RIFF header */
    tag = avio_rl32(pb);
    if (tag != MKTAG('R', 'I', 'F', 'F'))
        return -1;
    avio_rl32(pb); /* file size */
    tag = avio_rl32(pb);
    if (tag != MKTAG('X', 'W', 'M', 'A'))
        return -1;

    /* parse fmt header */
    tag = avio_rl32(pb);
    if (tag != MKTAG('f', 'm', 't', ' '))
        return -1;
    size = avio_rl32(pb);
    st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);

    ret = ff_get_wav_header(pb, st->codec, size);
    if (ret < 0)
        return ret;
    st->need_parsing = AVSTREAM_PARSE_NONE;

    /* All xWMA files I have seen contained WMAv2 data. If there are files
     * using WMA Pro or some other codec, then we need to figure out the right
     * extradata for that. Thus, ask the user for feedback, but try to go on
     * anyway.
     */
    if (st->codec->codec_id != CODEC_ID_WMAV2) {
        av_log(s, AV_LOG_WARNING, "unexpected codec (tag 0x04%x; id %d)\n",
                              st->codec->codec_tag, st->codec->codec_id);
        av_log_ask_for_sample(s, NULL);
    } else {
        /* In all xWMA files I have seen, there is no extradata. But the WMA
         * codecs require extradata, so we provide our own fake extradata.
         *
         * First, check that there really was no extradata in the header. If
         * there was, then try to use it, after asking the user to provide a
         * sample of this unusual file.
         */
        if (st->codec->extradata_size != 0) {
            /* Surprise, surprise: We *did* get some extradata. No idea
             * if it will work, but just go on and try it, after asking
             * the user for a sample.
             */
            av_log(s, AV_LOG_WARNING, "unexpected extradata (%d bytes)\n",
                                  st->codec->extradata_size);
            av_log_ask_for_sample(s, NULL);
        } else {
            st->codec->extradata_size = 6;
            st->codec->extradata      = av_mallocz(6 + FF_INPUT_BUFFER_PADDING_SIZE);
            if (!st->codec->extradata)
                return AVERROR(ENOMEM);

            /* setup extradata with our experimentally obtained value */
            st->codec->extradata[4] = 31;
        }
    }

    /* set the sample rate */
    av_set_pts_info(st, 64, 1, st->codec->sample_rate);

    /* parse the remaining RIFF chunks */
    for (;;) {
        if (pb->eof_reached)
            return -1;
        /* read next chunk tag */
        tag = avio_rl32(pb);
        size = avio_rl32(pb);
        if (tag == MKTAG('d', 'a', 't', 'a')) {
            /* We assume that the data chunk comes last. */
            break;
        } else if (tag == MKTAG('d','p','d','s')) {
            /* Quoting the MSDN xWMA docs on the dpds chunk: "Contains the
             * decoded packet cumulative data size array, each element is the
             * number of bytes accumulated after the corresponding xWMA packet
             * is decoded in order."
             *
             * Each packet has size equal to st->codec->block_align, which in
             * all cases I saw so far was always 2230. Thus, we can use the
             * dpds data to compute a seeking index.
             */

            /* Error out if there is more than one dpds chunk. */
            if (dpds_table) {
                av_log(s, AV_LOG_ERROR, "two dpds chunks present\n");
                return -1;
            }

            /* Compute the number of entries in the dpds chunk. */
            if (size & 3) {  /* Size should be divisible by four */
                av_log(s, AV_LOG_WARNING,
                       "dpds chunk size %"PRId64" not divisible by 4\n", size);
            }
            dpds_table_size = size / 4;
            if (dpds_table_size == 0 || dpds_table_size >= INT_MAX / 4) {
                av_log(s, AV_LOG_ERROR,
                       "dpds chunk size %"PRId64" invalid\n", size);
                return -1;
            }

            /* Allocate some temporary storage to keep the dpds data around.
             * for processing later on.
             */
            dpds_table = av_malloc(dpds_table_size * sizeof(uint32_t));
            if (!dpds_table) {
                return AVERROR(ENOMEM);
            }

            for (i = 0; i < dpds_table_size; ++i) {
                dpds_table[i] = avio_rl32(pb);
                size -= 4;
            }
        }
        avio_skip(pb, size);
    }

    /* Determine overall data length */
    if (size < 0)
        return -1;
    if (!size) {
        xwma->data_end = INT64_MAX;
    } else
        xwma->data_end = avio_tell(pb) + size;


    if (dpds_table && dpds_table_size) {
        int64_t cur_pos;
        const uint32_t bytes_per_sample
                = (st->codec->channels * st->codec->bits_per_coded_sample) >> 3;

        /* Estimate the duration from the total number of output bytes. */
        const uint64_t total_decoded_bytes = dpds_table[dpds_table_size - 1];
        st->duration = total_decoded_bytes / bytes_per_sample;

        /* Use the dpds data to build a seek table.  We can only do this after
         * we know the offset to the data chunk, as we need that to determine
         * the actual offset to each input block.
         * Note: If we allowed ourselves to assume that the data chunk always
         * follows immediately after the dpds block, we could of course guess
         * the data block's start offset already while reading the dpds chunk.
         * I decided against that, just in case other chunks ever are
         * discovered.
         */
        cur_pos = avio_tell(pb);
        for (i = 0; i < dpds_table_size; ++i) {
            /* From the number of output bytes that would accumulate in the
             * output buffer after decoding the first (i+1) packets, we compute
             * an offset / timestamp pair.
             */
            av_add_index_entry(st,
                               cur_pos + (i+1) * st->codec->block_align, /* pos */
                               dpds_table[i] / bytes_per_sample,         /* timestamp */
                               st->codec->block_align,                   /* size */
                               0,                                        /* duration */
                               AVINDEX_KEYFRAME);
        }
    } else if (st->codec->bit_rate) {