Ejemplo n.º 1
0
static int flashsv_encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size, void *data)
{
    FlashSVContext * const s = avctx->priv_data;
    AVFrame *pict = data;
    AVFrame * const p = &s->frame;
    uint8_t *pfptr;
    int res;
    int I_frame = 0;
    int opt_w, opt_h;

    *p = *pict;

    /* First frame needs to be a keyframe */
    if (avctx->frame_number == 0) {
        s->previous_frame = av_mallocz(FFABS(p->linesize[0])*s->image_height);
        if (!s->previous_frame) {
            av_log(avctx, AV_LOG_ERROR, "Memory allocation failed.\n");
            return -1;
        }
        I_frame = 1;
    }

    if (p->linesize[0] < 0)
        pfptr = s->previous_frame - ((s->image_height-1) * p->linesize[0]);
    else
        pfptr = s->previous_frame;

    /* Check the placement of keyframes */
    if (avctx->gop_size > 0) {
        if (avctx->frame_number >= s->last_key_frame + avctx->gop_size) {
            I_frame = 1;
        }
    }

    opt_w=4;
    opt_h=4;

    if (buf_size < s->image_width*s->image_height*3) {
        //Conservative upper bound check for compressed data
        av_log(avctx, AV_LOG_ERROR, "buf_size %d <  %d\n", buf_size, s->image_width*s->image_height*3);
        return -1;
    }

    res = encode_bitstream(s, p, buf, buf_size, opt_w*16, opt_h*16, pfptr, &I_frame);

    //save the current frame
    if(p->linesize[0] > 0)
        memcpy(s->previous_frame, p->data[0], s->image_height*p->linesize[0]);
    else
        memcpy(s->previous_frame, p->data[0] + p->linesize[0] * (s->image_height-1), s->image_height*FFABS(p->linesize[0]));

    //mark the frame type so the muxer can mux it correctly
    if (I_frame) {
        p->pict_type = FF_I_TYPE;
        p->key_frame = 1;
        s->last_key_frame = avctx->frame_number;
        av_log(avctx, AV_LOG_DEBUG, "Inserting key frame at frame %d\n",avctx->frame_number);
    } else {
        p->pict_type = FF_P_TYPE;
        p->key_frame = 0;
    }

    avctx->coded_frame = p;

    return res;
}
Ejemplo n.º 2
0
static int flashsv_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
                                const AVFrame *pict, int *got_packet)
{
    FlashSVContext * const s = avctx->priv_data;
    const AVFrame * const p = pict;
    uint8_t *pfptr;
    int res;
    int I_frame = 0;
    int opt_w = 4, opt_h = 4;

    /* First frame needs to be a keyframe */
    if (avctx->frame_number == 0) {
        s->previous_frame = av_mallocz(FFABS(p->linesize[0]) * s->image_height);
        if (!s->previous_frame) {
            av_log(avctx, AV_LOG_ERROR, "Memory allocation failed.\n");
            return AVERROR(ENOMEM);
        }
        I_frame = 1;
    }

    if (p->linesize[0] < 0)
        pfptr = s->previous_frame - (s->image_height - 1) * p->linesize[0];
    else
        pfptr = s->previous_frame;

    /* Check the placement of keyframes */
    if (avctx->gop_size > 0 &&
        avctx->frame_number >= s->last_key_frame + avctx->gop_size) {
        I_frame = 1;
    }

    if ((res = ff_alloc_packet(pkt, s->image_width * s->image_height * 3)) < 0) {
        //Conservative upper bound check for compressed data
        av_log(avctx, AV_LOG_ERROR, "Error getting output packet of size %d.\n",
               s->image_width * s->image_height * 3);
        return res;
    }

    pkt->size = encode_bitstream(s, p, pkt->data, pkt->size, opt_w * 16, opt_h * 16,
                                 pfptr, &I_frame);

    //save the current frame
    if (p->linesize[0] > 0)
        memcpy(s->previous_frame, p->data[0], s->image_height * p->linesize[0]);
    else
        memcpy(s->previous_frame,
               p->data[0] + p->linesize[0] * (s->image_height - 1),
               s->image_height * FFABS(p->linesize[0]));

    //mark the frame type so the muxer can mux it correctly
    if (I_frame) {
        avctx->coded_frame->pict_type      = AV_PICTURE_TYPE_I;
        avctx->coded_frame->key_frame      = 1;
        s->last_key_frame = avctx->frame_number;
        av_dlog(avctx, "Inserting keyframe at frame %d\n", avctx->frame_number);
    } else {
        avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P;
        avctx->coded_frame->key_frame = 0;
    }

    if (avctx->coded_frame->key_frame)
        pkt->flags |= AV_PKT_FLAG_KEY;
    *got_packet = 1;

    return 0;
}