Beispiel #1
0
static int ffm_write_packet(AVFormatContext *s, AVPacket *pkt)
{
    int64_t dts;
    uint8_t header[FRAME_HEADER_SIZE+4];
    int header_size = FRAME_HEADER_SIZE;

    dts = s->timestamp + pkt->dts;
    /* packet size & key_frame */
    header[0] = pkt->stream_index;
    header[1] = 0;
    if (pkt->flags & PKT_FLAG_KEY)
        header[1] |= FLAG_KEY_FRAME;
    AV_WB24(header+2, pkt->size);
    AV_WB24(header+5, pkt->duration);
    AV_WB64(header+8, s->timestamp + pkt->pts);
    if (pkt->pts != pkt->dts) {
        header[1] |= FLAG_DTS;
        AV_WB32(header+16, pkt->pts - pkt->dts);
        header_size += 4;
    }
    ffm_write_data(s, header, header_size, dts, 1);
    ffm_write_data(s, pkt->data, pkt->size, dts, 0);

    return 0;
}
Beispiel #2
0
static int cuvid_h264_decode_slice(AVCodecContext *avctx, const uint8_t *buffer,
                                   uint32_t size)
{
    CUVIDContext *ctx = avctx->internal->hwaccel_priv_data;
    void *tmp;

    tmp = av_fast_realloc(ctx->bitstream, &ctx->bitstream_allocated,
                          ctx->bitstream_len + size + 3);
    if (!tmp)
        return AVERROR(ENOMEM);
    ctx->bitstream = tmp;

    tmp = av_fast_realloc(ctx->slice_offsets, &ctx->slice_offsets_allocated,
                          (ctx->nb_slices + 1) * sizeof(*ctx->slice_offsets));
    if (!tmp)
        return AVERROR(ENOMEM);
    ctx->slice_offsets = tmp;

    AV_WB24(ctx->bitstream + ctx->bitstream_len, 1);
    memcpy(ctx->bitstream + ctx->bitstream_len + 3, buffer, size);
    ctx->slice_offsets[ctx->nb_slices] = ctx->bitstream_len ;
    ctx->bitstream_len += size + 3;
    ctx->nb_slices++;

    return 0;
}
Beispiel #3
0
static int nvdec_h264_decode_slice(AVCodecContext *avctx, const uint8_t *buffer,
                                   uint32_t size)
{
    NVDECContext *ctx = avctx->internal->hwaccel_priv_data;
    CUVIDPICPARAMS *pp = &ctx->pic_params;
    const H264Context *h = avctx->priv_data;
    const H264SliceContext *sl = &h->slice_ctx[0];
    void *tmp;

    tmp = av_fast_realloc(ctx->bitstream, &ctx->bitstream_allocated,
                          ctx->bitstream_len + size + 3);
    if (!tmp)
        return AVERROR(ENOMEM);
    ctx->bitstream = tmp;

    tmp = av_fast_realloc(ctx->slice_offsets, &ctx->slice_offsets_allocated,
                          (ctx->nb_slices + 1) * sizeof(*ctx->slice_offsets));
    if (!tmp)
        return AVERROR(ENOMEM);
    ctx->slice_offsets = tmp;

    AV_WB24(ctx->bitstream + ctx->bitstream_len, 1);
    memcpy(ctx->bitstream + ctx->bitstream_len + 3, buffer, size);
    ctx->slice_offsets[ctx->nb_slices] = ctx->bitstream_len ;
    ctx->bitstream_len += size + 3;
    ctx->nb_slices++;

    if (sl->slice_type != AV_PICTURE_TYPE_I && sl->slice_type != AV_PICTURE_TYPE_SI)
        pp->intra_pic_flag = 0;

    return 0;
}
Beispiel #4
0
static int find_expected_header(AVCodecContext *c, int size, int key_frame, uint8_t out[64]){
    int sample_rate= c->sample_rate;

    if(size>4096)
        return 0;

    AV_WB24(out, 1);

    if(c->codec_id == CODEC_ID_MPEG4){
        if(key_frame){
            return 3;
        }else{
            out[3]= 0xB6;
            return 4;
        }
    }else if(c->codec_id == CODEC_ID_MPEG1VIDEO || c->codec_id == CODEC_ID_MPEG2VIDEO){
        return 3;
    }else if(c->codec_id == CODEC_ID_H264){
        return 3;
    }else if(c->codec_id == CODEC_ID_MP3 || c->codec_id == CODEC_ID_MP2){
        int lsf, mpeg25, sample_rate_index, bitrate_index, frame_size;
        int layer= c->codec_id == CODEC_ID_MP3 ? 3 : 2;
        unsigned int header= 0xFFF00000;

        lsf     = sample_rate < (24000+32000)/2;
        mpeg25  = sample_rate < (12000+16000)/2;
        sample_rate <<= lsf + mpeg25;
        if     (sample_rate < (32000 + 44100)/2) sample_rate_index=2;
        else if(sample_rate < (44100 + 48000)/2) sample_rate_index=0;
        else                                     sample_rate_index=1;

        sample_rate= avpriv_mpa_freq_tab[sample_rate_index] >> (lsf + mpeg25);

        for(bitrate_index=2; bitrate_index<30; bitrate_index++){
            frame_size = avpriv_mpa_bitrate_tab[lsf][layer-1][bitrate_index>>1];
            frame_size = (frame_size * 144000) / (sample_rate << lsf) + (bitrate_index&1);

            if(frame_size == size)
                break;
        }

        header |= (!lsf)<<19;
        header |= (4-layer)<<17;
        header |= 1<<16; //no crc
        AV_WB32(out, header);
        if(size <= 0)
            return 2; //we guess there is no crc, if there is one the user clearly does not care about overhead
        if(bitrate_index == 30)
            return -1; //something is wrong ...

        header |= (bitrate_index>>1)<<12;
        header |= sample_rate_index<<10;
        header |= (bitrate_index&1)<<9;

        return 2; //FIXME actually put the needed ones in build_elision_headers()
        return 3; //we guess that the private bit is not set
//FIXME the above assumptions should be checked, if these turn out false too often something should be done
    }
Beispiel #5
0
static inline void transpose_block_24_c(uint8_t *src, ptrdiff_t src_linesize,
                                        uint8_t *dst, ptrdiff_t dst_linesize,
                                        int w, int h)
{
    int x, y;
    for (y = 0; y < h; y++, dst += dst_linesize) {
        for (x = 0; x < w; x++) {
            int32_t v = AV_RB24(src + x*src_linesize + y*3);
            AV_WB24(dst + 3*x, v);
        }
    }
}
Beispiel #6
0
static av_always_inline void copy_elem(uint8_t *pout, const uint8_t *pin, int elem_size)
{
    int v;
    switch (elem_size) {
    case 1:
        *pout = *pin;
        break;
    case 2:
        *((uint16_t *)pout) = *((uint16_t *)pin);
        break;
    case 3:
        v = AV_RB24(pin);
        AV_WB24(pout, v);
        break;
    case 4:
        *((uint32_t *)pout) = *((uint32_t *)pin);
        break;
    default:
        memcpy(pout, pin, elem_size);
        break;
    }
}
Beispiel #7
0
static int filter_frame(AVFilterLink *inlink, AVFrame *in)
{
    AVFilterContext *ctx  = inlink->dst;
    FlipContext *s     = ctx->priv;
    AVFilterLink *outlink = ctx->outputs[0];
    AVFrame *out;
    uint8_t *inrow, *outrow;
    int i, j, plane, step;

    out = ff_get_video_buffer(outlink, outlink->w, outlink->h);
    if (!out) {
        av_frame_free(&in);
        return AVERROR(ENOMEM);
    }
    av_frame_copy_props(out, in);

    /* copy palette if required */
    if (av_pix_fmt_desc_get(inlink->format)->flags & AV_PIX_FMT_FLAG_PAL)
        memcpy(out->data[1], in->data[1], AVPALETTE_SIZE);

    for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane]; plane++) {
        const int width  = (plane == 1 || plane == 2) ? FF_CEIL_RSHIFT(inlink->w, s->hsub) : inlink->w;
        const int height = (plane == 1 || plane == 2) ? FF_CEIL_RSHIFT(inlink->h, s->vsub) : inlink->h;
        step = s->max_step[plane];

        outrow = out->data[plane];
        inrow  = in ->data[plane] + (width - 1) * step;
        for (i = 0; i < height; i++) {
            switch (step) {
            case 1:
                for (j = 0; j < width; j++)
                    outrow[j] = inrow[-j];
            break;

            case 2:
            {
                uint16_t *outrow16 = (uint16_t *)outrow;
                uint16_t * inrow16 = (uint16_t *) inrow;
                for (j = 0; j < width; j++)
                    outrow16[j] = inrow16[-j];
            }
            break;

            case 3:
            {
                uint8_t *in  =  inrow;
                uint8_t *out = outrow;
                for (j = 0; j < width; j++, out += 3, in -= 3) {
                    int32_t v = AV_RB24(in);
                    AV_WB24(out, v);
                }
            }
            break;

            case 4:
            {
                uint32_t *outrow32 = (uint32_t *)outrow;
                uint32_t * inrow32 = (uint32_t *) inrow;
                for (j = 0; j < width; j++)
                    outrow32[j] = inrow32[-j];
            }
            break;

            default:
                for (j = 0; j < width; j++)
                    memcpy(outrow + j*step, inrow - j*step, step);
            }

            inrow  += in ->linesize[plane];
            outrow += out->linesize[plane];
        }
    }

    av_frame_free(&in);
    return ff_filter_frame(outlink, out);
}
static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt,
                                   uint8_t **data, int *size)
{
    static const int extradata_nal_types_hevc[] = {
        HEVC_NAL_VPS, HEVC_NAL_SPS, HEVC_NAL_PPS,
    };
    static const int extradata_nal_types_h264[] = {
        H264_NAL_SPS, H264_NAL_PPS,
    };

    ExtractExtradataContext *s = ctx->priv_data;

    H2645Packet h2645_pkt = { 0 };
    int extradata_size = 0;
    const int *extradata_nal_types;
    int nb_extradata_nal_types;
    int i, ret = 0;

    if (ctx->par_in->codec_id == AV_CODEC_ID_HEVC) {
        extradata_nal_types    = extradata_nal_types_hevc;
        nb_extradata_nal_types = FF_ARRAY_ELEMS(extradata_nal_types_hevc);
    } else {
        extradata_nal_types    = extradata_nal_types_h264;
        nb_extradata_nal_types = FF_ARRAY_ELEMS(extradata_nal_types_h264);
    }

    ret = ff_h2645_packet_split(&h2645_pkt, pkt->data, pkt->size,
                                ctx, 0, 0, ctx->par_in->codec_id);
    if (ret < 0)
        return ret;

    for (i = 0; i < h2645_pkt.nb_nals; i++) {
        H2645NAL *nal = &h2645_pkt.nals[i];
        if (val_in_array(extradata_nal_types, nb_extradata_nal_types, nal->type))
            extradata_size += nal->raw_size + 3;
    }

    if (extradata_size) {
        AVBufferRef *filtered_buf;
        uint8_t *extradata, *filtered_data;

        if (s->remove) {
            filtered_buf = av_buffer_alloc(pkt->size + AV_INPUT_BUFFER_PADDING_SIZE);
            if (!filtered_buf)
                goto fail;
            filtered_data = filtered_buf->data;
        }

        extradata = av_malloc(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
        if (!extradata) {
            av_buffer_unref(&filtered_buf);
            goto fail;
        }

        *data = extradata;
        *size = extradata_size;

        for (i = 0; i < h2645_pkt.nb_nals; i++) {
            H2645NAL *nal = &h2645_pkt.nals[i];
            if (val_in_array(extradata_nal_types, nb_extradata_nal_types,
                             nal->type)) {
                AV_WB24(extradata, 1); // startcode
                memcpy(extradata + 3, nal->raw_data, nal->raw_size);
                extradata += 3 + nal->raw_size;
            } else if (s->remove) {
                AV_WB24(filtered_data, 1); // startcode
                memcpy(filtered_data + 3, nal->raw_data, nal->raw_size);
                filtered_data += 3 + nal->raw_size;
            }
        }

        if (s->remove) {
            av_buffer_unref(&pkt->buf);
            pkt->buf  = filtered_buf;
            pkt->data = filtered_buf->data;
            pkt->size = filtered_data - filtered_buf->data;
        }
    }

fail:
    ff_h2645_packet_uninit(&h2645_pkt);
    return ret;
}
Beispiel #9
0
static int filter_slice(AVFilterContext *ctx, void *arg, int job, int nb_jobs)
{
    FlipContext *s = ctx->priv;
    ThreadData *td = arg;
    AVFrame *in = td->in;
    AVFrame *out = td->out;
    uint8_t *inrow, *outrow;
    int i, j, plane, step;

    for (plane = 0; plane < 4 && in->data[plane] && in->linesize[plane]; plane++) {
        const int width  = s->planewidth[plane];
        const int height = s->planeheight[plane];
        const int start = (height *  job   ) / nb_jobs;
        const int end   = (height * (job+1)) / nb_jobs;

        step = s->max_step[plane];

        outrow = out->data[plane] + start * out->linesize[plane];
        inrow  = in ->data[plane] + start * in->linesize[plane] + (width - 1) * step;
        for (i = start; i < end; i++) {
            switch (step) {
            case 1:
                for (j = 0; j < width; j++)
                    outrow[j] = inrow[-j];
            break;

            case 2:
            {
                uint16_t *outrow16 = (uint16_t *)outrow;
                uint16_t * inrow16 = (uint16_t *) inrow;
                for (j = 0; j < width; j++)
                    outrow16[j] = inrow16[-j];
            }
            break;

            case 3:
            {
                uint8_t *in  =  inrow;
                uint8_t *out = outrow;
                for (j = 0; j < width; j++, out += 3, in -= 3) {
                    int32_t v = AV_RB24(in);
                    AV_WB24(out, v);
                }
            }
            break;

            case 4:
            {
                uint32_t *outrow32 = (uint32_t *)outrow;
                uint32_t * inrow32 = (uint32_t *) inrow;
                for (j = 0; j < width; j++)
                    outrow32[j] = inrow32[-j];
            }
            break;

            default:
                for (j = 0; j < width; j++)
                    memcpy(outrow + j*step, inrow - j*step, step);
            }

            inrow  += in ->linesize[plane];
            outrow += out->linesize[plane];
        }
    }

    return 0;
}
Beispiel #10
0
static int extract_extradata_h2645(AVBSFContext *ctx, AVPacket *pkt,
                                   uint8_t **data, int *size)
{
    static const int extradata_nal_types_hevc[] = {
        HEVC_NAL_VPS, HEVC_NAL_SPS, HEVC_NAL_PPS,
    };
    static const int extradata_nal_types_h264[] = {
        H264_NAL_SPS, H264_NAL_PPS,
    };

    ExtractExtradataContext *s = ctx->priv_data;

    int extradata_size = 0, filtered_size = 0;
    const int *extradata_nal_types;
    int nb_extradata_nal_types;
    int i, has_sps = 0, has_vps = 0, ret = 0;

    if (ctx->par_in->codec_id == AV_CODEC_ID_HEVC) {
        extradata_nal_types    = extradata_nal_types_hevc;
        nb_extradata_nal_types = FF_ARRAY_ELEMS(extradata_nal_types_hevc);
    } else {
        extradata_nal_types    = extradata_nal_types_h264;
        nb_extradata_nal_types = FF_ARRAY_ELEMS(extradata_nal_types_h264);
    }

    ret = ff_h2645_packet_split(&s->h2645_pkt, pkt->data, pkt->size,
                                ctx, 0, 0, ctx->par_in->codec_id, 1, 0);
    if (ret < 0)
        return ret;

    for (i = 0; i < s->h2645_pkt.nb_nals; i++) {
        H2645NAL *nal = &s->h2645_pkt.nals[i];
        if (val_in_array(extradata_nal_types, nb_extradata_nal_types, nal->type)) {
            extradata_size += nal->raw_size + 3;
            if (ctx->par_in->codec_id == AV_CODEC_ID_HEVC) {
                if (nal->type == HEVC_NAL_SPS) has_sps = 1;
                if (nal->type == HEVC_NAL_VPS) has_vps = 1;
            } else {
                if (nal->type == H264_NAL_SPS) has_sps = 1;
            }
        } else if (s->remove) {
            filtered_size += nal->raw_size + 3;
        }
    }

    if (extradata_size &&
        ((ctx->par_in->codec_id == AV_CODEC_ID_HEVC && has_sps && has_vps) ||
         (ctx->par_in->codec_id == AV_CODEC_ID_H264 && has_sps))) {
        AVBufferRef *filtered_buf;
        uint8_t *extradata, *filtered_data;

        if (s->remove) {
            filtered_buf = av_buffer_alloc(filtered_size + AV_INPUT_BUFFER_PADDING_SIZE);
            if (!filtered_buf) {
                return AVERROR(ENOMEM);
            }
            memset(filtered_buf->data + filtered_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);

            filtered_data = filtered_buf->data;
        }

        extradata = av_malloc(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
        if (!extradata) {
            av_buffer_unref(&filtered_buf);
            return AVERROR(ENOMEM);
        }
        memset(extradata + extradata_size, 0, AV_INPUT_BUFFER_PADDING_SIZE);

        *data = extradata;
        *size = extradata_size;

        for (i = 0; i < s->h2645_pkt.nb_nals; i++) {
            H2645NAL *nal = &s->h2645_pkt.nals[i];
            if (val_in_array(extradata_nal_types, nb_extradata_nal_types,
                             nal->type)) {
                AV_WB24(extradata, 1); // startcode
                memcpy(extradata + 3, nal->raw_data, nal->raw_size);
                extradata += 3 + nal->raw_size;
            } else if (s->remove) {
                AV_WB24(filtered_data, 1); // startcode
                memcpy(filtered_data + 3, nal->raw_data, nal->raw_size);
                filtered_data += 3 + nal->raw_size;
            }
        }

        if (s->remove) {
            av_buffer_unref(&pkt->buf);
            pkt->buf  = filtered_buf;
            pkt->data = filtered_buf->data;
            pkt->size = filtered_size;
        }
    }

    return 0;
}
Beispiel #11
0
static void end_frame(AVFilterLink *inlink)
{
    TransContext *trans = inlink->dst->priv;
    AVFilterBufferRef *inpic  = inlink->cur_buf;
    AVFilterBufferRef *outpic = inlink->dst->outputs[0]->out_buf;
    AVFilterLink *outlink = inlink->dst->outputs[0];
    int plane;

    for (plane = 0; outpic->data[plane]; plane++) {
        int hsub = plane == 1 || plane == 2 ? trans->hsub : 0;
        int vsub = plane == 1 || plane == 2 ? trans->vsub : 0;
        int pixstep = trans->pixsteps[plane];
        int inh  = inpic->video->h>>vsub;
        int outw = outpic->video->w>>hsub;
        int outh = outpic->video->h>>vsub;
        uint8_t *out, *in;
        int outlinesize, inlinesize;
        int x, y;

        out = outpic->data[plane]; outlinesize = outpic->linesize[plane];
        in  = inpic ->data[plane]; inlinesize  = inpic ->linesize[plane];

        if (trans->dir&1) {
            in +=  inpic->linesize[plane] * (inh-1);
            inlinesize *= -1;
        }

        if (trans->dir&2) {
            out += outpic->linesize[plane] * (outh-1);
            outlinesize *= -1;
        }

        for (y = 0; y < outh; y++) {
            switch (pixstep) {
            case 1:
                for (x = 0; x < outw; x++)
                    out[x] = in[x*inlinesize + y];
                break;
            case 2:
                for (x = 0; x < outw; x++)
                    *((uint16_t *)(out + 2*x)) = *((uint16_t *)(in + x*inlinesize + y*2));
                break;
            case 3:
                for (x = 0; x < outw; x++) {
                    int32_t v = AV_RB24(in + x*inlinesize + y*3);
                    AV_WB24(out + 3*x, v);
                }
                break;
            case 4:
                for (x = 0; x < outw; x++)
                    *((uint32_t *)(out + 4*x)) = *((uint32_t *)(in + x*inlinesize + y*4));
                break;
            }
            out += outlinesize;
        }
    }

    avfilter_unref_buffer(inpic);
    avfilter_draw_slice(outlink, 0, outpic->video->h, 1);
    avfilter_end_frame(outlink);
    avfilter_unref_buffer(outpic);
}
Beispiel #12
0
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                        AVPacket *avpkt)
{
    AVFrame *f = data;
    GetByteContext gb;
    int width, height, ret, bits_pixel, pixel;
    uint8_t *out_buf;
    uint8_t count;
    int x, y;

    bytestream2_init(&gb, avpkt->data, avpkt->size);

    if (bytestream2_get_bytes_left(&gb) < ALIAS_HEADER_SIZE) {
        av_log(avctx, AV_LOG_ERROR, "Header too small %d.\n", avpkt->size);
        return AVERROR_INVALIDDATA;
    }

    width  = bytestream2_get_be16u(&gb);
    height = bytestream2_get_be16u(&gb);
    bytestream2_skipu(&gb, 4); // obsolete X, Y offset
    bits_pixel = bytestream2_get_be16u(&gb);

    if (bits_pixel == 24)
        avctx->pix_fmt = AV_PIX_FMT_BGR24;
    else if (bits_pixel == 8)
        avctx->pix_fmt = AV_PIX_FMT_GRAY8;
    else {
        av_log(avctx, AV_LOG_ERROR, "Invalid pixel format.\n");
        return AVERROR_INVALIDDATA;
    }

    ret = ff_set_dimensions(avctx, width, height);
    if (ret < 0)
        return ret;

    ret = ff_get_buffer(avctx, f, 0);
    if (ret < 0)
        return ret;

    f->pict_type = AV_PICTURE_TYPE_I;
    f->key_frame = 1;

    x = 0;
    y = 1;
    out_buf = f->data[0];
    while (bytestream2_get_bytes_left(&gb) > 0) {
        int i;

        /* set buffer at the right position at every new line */
        if (x == avctx->width) {
            x = 0;
            out_buf = f->data[0] + f->linesize[0] * y++;
            if (y > avctx->height) {
                av_log(avctx, AV_LOG_ERROR,
                       "Ended frame decoding with %d bytes left.\n",
                       bytestream2_get_bytes_left(&gb));
                return AVERROR_INVALIDDATA;
            }
        }

        /* read packet and copy data */
        count = bytestream2_get_byteu(&gb);
        if (!count || x + count > avctx->width) {
            av_log(avctx, AV_LOG_ERROR, "Invalid run length %d.\n", count);
            return AVERROR_INVALIDDATA;
        }

        if (avctx->pix_fmt == AV_PIX_FMT_BGR24) {
            pixel = bytestream2_get_be24(&gb);
            for (i = 0; i < count; i++) {
                AV_WB24(out_buf, pixel);
                out_buf += 3;
            }
        } else { // AV_PIX_FMT_GRAY8
            pixel = bytestream2_get_byte(&gb);
            for (i = 0; i < count; i++)
                *out_buf++ = pixel;
        }

        x += i;
    }

    if (x != width || y != height) {
        av_log(avctx, AV_LOG_ERROR, "Picture stopped at %d,%d.\n", x, y);
        return AVERROR_INVALIDDATA;
    }

    *got_frame = 1;
    return avpkt->size;
}
Beispiel #13
0
static int filter_slice(RotContext *rot, ThreadData *td, int job, int nb_jobs)
{
    AVFrame *in = td->in;
    AVFrame *out = td->out;
    const int outw = td->outw, outh = td->outh;
    const int inw = td->inw, inh = td->inh;
    const int plane = td->plane;
    const int xi = td->xi, yi = td->yi;
    const int c = td->c, s = td->s;
    const int start = (outh *  job   ) / nb_jobs;
    const int end   = (outh * (job+1)) / nb_jobs;
    int xprime = td->xprime + start * s;
    int yprime = td->yprime + start * c;
    int i, j, x, y;

    for (j = start; j < end; j++) {
        x = xprime + xi + FIXP*(inw-1)/2;
        y = yprime + yi + FIXP*(inh-1)/2;

        if (fabs(rot->angle - 0) < FLT_EPSILON && outw == inw && outh == inh) {
            simple_rotate(out->data[plane] + j * out->linesize[plane],
                           in->data[plane] + j *  in->linesize[plane],
                          in->linesize[plane], 0, rot->draw.pixelstep[plane], outw);
        } else if (fabs(rot->angle - M_PI/2) < FLT_EPSILON && outw == inh && outh == inw) {
            simple_rotate(out->data[plane] + j * out->linesize[plane],
                           in->data[plane] + j * rot->draw.pixelstep[plane],
                          in->linesize[plane], 1, rot->draw.pixelstep[plane], outw);
        } else if (fabs(rot->angle - M_PI) < FLT_EPSILON && outw == inw && outh == inh) {
            simple_rotate(out->data[plane] + j * out->linesize[plane],
                           in->data[plane] + (outh-j-1) *  in->linesize[plane],
                          in->linesize[plane], 2, rot->draw.pixelstep[plane], outw);
        } else if (fabs(rot->angle - 3*M_PI/2) < FLT_EPSILON && outw == inh && outh == inw) {
            simple_rotate(out->data[plane] + j * out->linesize[plane],
                           in->data[plane] + (outh-j-1) * rot->draw.pixelstep[plane],
                          in->linesize[plane], 3, rot->draw.pixelstep[plane], outw);
        } else {

        for (i = 0; i < outw; i++) {
            int32_t v;
            int x1, y1;
            uint8_t *pin, *pout;
            x1 = x>>16;
            y1 = y>>16;

            /* the out-of-range values avoid border artifacts */
            if (x1 >= -1 && x1 <= inw && y1 >= -1 && y1 <= inh) {
                uint8_t inp_inv[4]; /* interpolated input value */
                pout = out->data[plane] + j * out->linesize[plane] + i * rot->draw.pixelstep[plane];
                if (rot->use_bilinear) {
                    pin = rot->interpolate_bilinear(inp_inv,
                                                    in->data[plane], in->linesize[plane], rot->draw.pixelstep[plane],
                                                    x, y, inw-1, inh-1);
                } else {
                    int x2 = av_clip(x1, 0, inw-1);
                    int y2 = av_clip(y1, 0, inh-1);
                    pin = in->data[plane] + y2 * in->linesize[plane] + x2 * rot->draw.pixelstep[plane];
                }
                switch (rot->draw.pixelstep[plane]) {
                case 1:
                    *pout = *pin;
                    break;
                case 2:
                    v = AV_RL16(pin);
                    AV_WL16(pout, v);
                    break;
                case 3:
                    v = AV_RB24(pin);
                    AV_WB24(pout, v);
                    break;
                case 4:
                    *((uint32_t *)pout) = *((uint32_t *)pin);
                    break;
                default:
                    memcpy(pout, pin, rot->draw.pixelstep[plane]);
                    break;
                }
            }
            x += c;
            y -= s;
        }
        }
        xprime += s;
        yprime += c;
    }

    return 0;
}
Beispiel #14
0
static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in)
{
    AVFilterLink *outlink = inlink->dst->outputs[0];
    TransContext *trans = inlink->dst->priv;
    AVFilterBufferRef *out;
    int plane;

    out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h);
    if (!out) {
        avfilter_unref_bufferp(&in);
        return AVERROR(ENOMEM);
    }

    out->pts = in->pts;

    if (in->video->pixel_aspect.num == 0) {
        out->video->pixel_aspect = in->video->pixel_aspect;
    } else {
        out->video->pixel_aspect.num = in->video->pixel_aspect.den;
        out->video->pixel_aspect.den = in->video->pixel_aspect.num;
    }

    for (plane = 0; out->data[plane]; plane++) {
        int hsub = plane == 1 || plane == 2 ? trans->hsub : 0;
        int vsub = plane == 1 || plane == 2 ? trans->vsub : 0;
        int pixstep = trans->pixsteps[plane];
        int inh  = in->video->h>>vsub;
        int outw = out->video->w>>hsub;
        int outh = out->video->h>>vsub;
        uint8_t *dst, *src;
        int dstlinesize, srclinesize;
        int x, y;

        dst = out->data[plane];
        dstlinesize = out->linesize[plane];
        src = in->data[plane];
        srclinesize = in->linesize[plane];

        if (trans->dir&1) {
            src +=  in->linesize[plane] * (inh-1);
            srclinesize *= -1;
        }

        if (trans->dir&2) {
            dst += out->linesize[plane] * (outh-1);
            dstlinesize *= -1;
        }

        for (y = 0; y < outh; y++) {
            switch (pixstep) {
            case 1:
                for (x = 0; x < outw; x++)
                    dst[x] = src[x*srclinesize + y];
                break;
            case 2:
                for (x = 0; x < outw; x++)
                    *((uint16_t *)(dst + 2*x)) = *((uint16_t *)(src + x*srclinesize + y*2));
                break;
            case 3:
                for (x = 0; x < outw; x++) {
                    int32_t v = AV_RB24(src + x*srclinesize + y*3);
                    AV_WB24(dst + 3*x, v);
                }
                break;
            case 4:
                for (x = 0; x < outw; x++)
                    *((uint32_t *)(dst + 4*x)) = *((uint32_t *)(src + x*srclinesize + y*4));
                break;
            }
            dst += dstlinesize;
        }
    }

    avfilter_unref_bufferp(&in);
    return ff_filter_frame(outlink, out);
}