コード例 #1
0
ファイル: adx_parser.c プロジェクト: Arcen/FFmpeg
static int adx_parse(AVCodecParserContext *s1,
                           AVCodecContext *avctx,
                           const uint8_t **poutbuf, int *poutbuf_size,
                           const uint8_t *buf, int buf_size)
{
    ADXParseContext *s = s1->priv_data;
    ParseContext *pc = &s->pc;
    int next = END_NOT_FOUND;

    if (!avctx->extradata_size) {
        int ret;

        ff_combine_frame(pc, END_NOT_FOUND, &buf, &buf_size);

        if (!s->header_size && pc->index >= MIN_HEADER_SIZE) {
            if (ret = avpriv_adx_decode_header(avctx, pc->buffer, pc->index,
                                               &s->header_size, NULL))
                return AVERROR_INVALIDDATA;
            s->block_size = BLOCK_SIZE * avctx->channels;
        }
        if (s->header_size && s->header_size <= pc->index) {
            avctx->extradata = av_mallocz(s->header_size + FF_INPUT_BUFFER_PADDING_SIZE);
            if (!avctx->extradata)
                return AVERROR(ENOMEM);
            avctx->extradata_size = s->header_size;
            memcpy(avctx->extradata, pc->buffer, s->header_size);
            memmove(pc->buffer, pc->buffer + s->header_size, s->header_size);
            pc->index -= s->header_size;
        }
        *poutbuf      = NULL;
        *poutbuf_size = 0;
        return buf_size;
    }

    if (pc->index - s->buf_pos >= s->block_size) {
        *poutbuf      = &pc->buffer[s->buf_pos];
        *poutbuf_size = s->block_size;
        s->buf_pos   += s->block_size;
        return 0;
    }
    if (pc->index && s->buf_pos) {
        memmove(pc->buffer, &pc->buffer[s->buf_pos], pc->index - s->buf_pos);
        pc->index -= s->buf_pos;
        s->buf_pos = 0;
    }
    if (buf_size + pc->index >= s->block_size)
        next = s->block_size - pc->index;

    if (ff_combine_frame(pc, next, &buf, &buf_size) < 0 || !buf_size) {
        *poutbuf      = NULL;
        *poutbuf_size = 0;
        return buf_size;
    }
    *poutbuf = buf;
    *poutbuf_size = buf_size;
    return next;
}
コード例 #2
0
ファイル: adxdec.c プロジェクト: Bjelijah/EcamTurnH265
static av_cold int adx_decode_init(AVCodecContext *avctx)
{
    ADXContext *c = avctx->priv_data;
    int ret, header_size;

    if (avctx->extradata_size >= 24) {
        if ((ret = avpriv_adx_decode_header(avctx, avctx->extradata,
                                            avctx->extradata_size, &header_size,
                                            c->coeff)) < 0) {
            av_log(avctx, AV_LOG_ERROR, "error parsing ADX header\n");
            return AVERROR_INVALIDDATA;
        }
        c->channels      = avctx->channels;
        c->header_parsed = 1;
    }

    avctx->sample_fmt = AV_SAMPLE_FMT_S16P;

    return 0;
}
コード例 #3
0
ファイル: adxdec.c プロジェクト: szatmary/FFmpeg
static int adx_read_header(AVFormatContext *s)
{
    ADXDemuxerContext *c = s->priv_data;
    AVCodecContext *avctx;
    int ret;

    AVStream *st = avformat_new_stream(s, NULL);
    if (!st)
        return AVERROR(ENOMEM);
    avctx = s->streams[0]->codec;

    if (avio_rb16(s->pb) != 0x8000)
        return AVERROR_INVALIDDATA;
    c->header_size = avio_rb16(s->pb) + 4;
    avio_seek(s->pb, -4, SEEK_CUR);

    avctx->extradata = av_mallocz(c->header_size + FF_INPUT_BUFFER_PADDING_SIZE);
    if (!avctx->extradata)
        return AVERROR(ENOMEM);
    if (avio_read(s->pb, avctx->extradata, c->header_size) < c->header_size) {
        av_freep(&avctx->extradata);
        return AVERROR(EIO);
    }
    avctx->extradata_size = c->header_size;

    ret = avpriv_adx_decode_header(avctx, avctx->extradata,
                                   avctx->extradata_size, &c->header_size,
                                   NULL);
    if (ret)
        return ret;

    st->codec->codec_type  = AVMEDIA_TYPE_AUDIO;
    st->codec->codec_id    = s->iformat->value;

    avpriv_set_pts_info(st, 64, BLOCK_SAMPLES, avctx->sample_rate);

    return 0;
}
コード例 #4
0
static int adx_decode_frame(AVCodecContext *avctx, void *data,
                            int *got_frame_ptr, AVPacket *avpkt)
{
    int buf_size        = avpkt->size;
    ADXContext *c       = (ADXContext *)avctx->priv_data;
    int16_t *samples;
    const uint8_t *buf  = avpkt->data;
    int num_blocks, ch, ret;

    if (c->eof) {
        *got_frame_ptr = 0;
        return buf_size;
    }

    if (!c->header_parsed && buf_size >= 2 && AV_RB16(buf) == 0x8000) {
        int header_size;
        if ((ret = avpriv_adx_decode_header(avctx, buf, buf_size, &header_size,
                                            c->coeff)) < 0) {
            av_log(avctx, AV_LOG_ERROR, "error parsing ADX header\n");
            return AVERROR_INVALIDDATA;
        }
        c->channels      = avctx->channels;
        c->header_parsed = 1;
        if (buf_size < header_size)
            return AVERROR_INVALIDDATA;
        buf      += header_size;
        buf_size -= header_size;
    }
    if (!c->header_parsed)
        return AVERROR_INVALIDDATA;

    /* calculate number of blocks in the packet */
    num_blocks = buf_size / (BLOCK_SIZE * c->channels);

    /* if the packet is not an even multiple of BLOCK_SIZE, check for an EOF
       packet */
    if (!num_blocks || buf_size % (BLOCK_SIZE * avctx->channels)) {
        if (buf_size >= 4 && (AV_RB16(buf) & 0x8000)) {
            c->eof = 1;
            *got_frame_ptr = 0;
            return avpkt->size;
        }
        return AVERROR_INVALIDDATA;
    }

    /* get output buffer */
    c->frame.nb_samples = num_blocks * BLOCK_SAMPLES;
    if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0) {
        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
        return ret;
    }
    samples = (int16_t *)c->frame.data[0];

    while (num_blocks--) {
        for (ch = 0; ch < c->channels; ch++) {
            if (adx_decode(c, samples + ch, buf, ch)) {
                c->eof = 1;
                buf = avpkt->data + avpkt->size;
                break;
            }
            buf_size -= BLOCK_SIZE;
            buf      += BLOCK_SIZE;
        }
        samples += BLOCK_SAMPLES * c->channels;
    }

    *got_frame_ptr   = 1;
    *(AVFrame *)data = c->frame;

    return buf - avpkt->data;
}
コード例 #5
0
ファイル: adxdec.c プロジェクト: Bjelijah/EcamTurnH265
static int adx_decode_frame(AVCodecContext *avctx, void *data,
                            int *got_frame_ptr, AVPacket *avpkt)
{
    AVFrame *frame      = data;
    int buf_size        = avpkt->size;
    ADXContext *c       = avctx->priv_data;
    int16_t **samples;
    int samples_offset;
    const uint8_t *buf  = avpkt->data;
    const uint8_t *buf_end = buf + avpkt->size;
    int num_blocks, ch, ret;

    if (c->eof) {
        *got_frame_ptr = 0;
        return buf_size;
    }

    if (!c->header_parsed && buf_size >= 2 && AV_RB16(buf) == 0x8000) {
        int header_size;
        if ((ret = avpriv_adx_decode_header(avctx, buf, buf_size, &header_size,
                                            c->coeff)) < 0) {
            av_log(avctx, AV_LOG_ERROR, "error parsing ADX header\n");
            return AVERROR_INVALIDDATA;
        }
        c->channels      = avctx->channels;
        c->header_parsed = 1;
        if (buf_size < header_size)
            return AVERROR_INVALIDDATA;
        buf      += header_size;
        buf_size -= header_size;
    }
    if (!c->header_parsed)
        return AVERROR_INVALIDDATA;

    /* calculate number of blocks in the packet */
    num_blocks = buf_size / (BLOCK_SIZE * c->channels);

    /* if the packet is not an even multiple of BLOCK_SIZE, check for an EOF
       packet */
    if (!num_blocks || buf_size % (BLOCK_SIZE * avctx->channels)) {
        if (buf_size >= 4 && (AV_RB16(buf) & 0x8000)) {
            c->eof = 1;
            *got_frame_ptr = 0;
            return avpkt->size;
        }
        return AVERROR_INVALIDDATA;
    }

    /* get output buffer */
    frame->nb_samples = num_blocks * BLOCK_SAMPLES;
    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
        return ret;
    samples = (int16_t **)frame->extended_data;
    samples_offset = 0;

    while (num_blocks--) {
        for (ch = 0; ch < c->channels; ch++) {
            if (buf_end - buf < BLOCK_SIZE || adx_decode(c, samples[ch], samples_offset, buf, ch)) {
                c->eof = 1;
                buf = avpkt->data + avpkt->size;
                break;
            }
            buf_size -= BLOCK_SIZE;
            buf      += BLOCK_SIZE;
        }
        if (!c->eof)
            samples_offset += BLOCK_SAMPLES;
    }

    frame->nb_samples = samples_offset;
    *got_frame_ptr = 1;

    return buf - avpkt->data;
}