X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavcodec%2Fsvq1enc.c;h=24251ff02c8ac44c366f506ce3d0ad1ac3482ef8;hb=40cf1bbacc6220a0aa6bed5c331871d43f9ce370;hp=361c465569042c91870c902c2985a99bcb74f286;hpb=835f798c7d20bca89eb4f3593846251ad0d84e4b;p=ffmpeg diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c index 361c4655690..24251ff02c8 100644 --- a/libavcodec/svq1enc.c +++ b/libavcodec/svq1enc.c @@ -238,14 +238,13 @@ static int svq1_encode_plane(SVQ1EncContext *s, int plane, unsigned char *decoded_plane, int width, int height, int src_stride, int stride) { - const AVFrame *f = s->avctx->coded_frame; int x, y; int i; int block_width, block_height; int level; int threshold[6]; uint8_t *src = s->scratchbuf + stride * 16; - const int lambda = (f->quality * f->quality) >> + const int lambda = (s->quality * s->quality) >> (2 * FF_LAMBDA_SHIFT); /* figure out the acceptable level thresholds in advance */ @@ -256,7 +255,7 @@ static int svq1_encode_plane(SVQ1EncContext *s, int plane, block_width = (width + 15) / 16; block_height = (height + 15) / 16; - if (f->pict_type == AV_PICTURE_TYPE_P) { + if (s->pict_type == AV_PICTURE_TYPE_P) { s->m.avctx = s->avctx; s->m.current_picture_ptr = &s->m.current_picture; s->m.last_picture_ptr = &s->m.last_picture; @@ -272,13 +271,12 @@ static int svq1_encode_plane(SVQ1EncContext *s, int plane, s->m.mb_stride = s->m.mb_width + 1; s->m.b8_stride = 2 * s->m.mb_width + 1; s->m.f_code = 1; - s->m.pict_type = f->pict_type; + s->m.pict_type = s->pict_type; s->m.me_method = s->avctx->me_method; s->m.me.scene_change_score = 0; - s->m.flags = s->avctx->flags; // s->m.out_format = FMT_H263; // s->m.unrestricted_mv = 1; - s->m.lambda = f->quality; + s->m.lambda = s->quality; s->m.qscale = s->m.lambda * 139 + FF_LAMBDA_SCALE * 64 >> FF_LAMBDA_SHIFT + 7; @@ -293,6 +291,8 @@ static int svq1_encode_plane(SVQ1EncContext *s, int plane, s->motion_val16[plane] = av_mallocz((s->m.mb_stride * (block_height + 2) + 1) * 2 * sizeof(int16_t)); + if (!s->motion_val8[plane] || !s->motion_val16[plane]) + return AVERROR(ENOMEM); } s->m.mb_type = s->mb_type; @@ -371,13 +371,13 @@ static int svq1_encode_plane(SVQ1EncContext *s, int plane, ff_init_block_index(&s->m); ff_update_block_index(&s->m); - if (f->pict_type == AV_PICTURE_TYPE_I || + if (s->pict_type == AV_PICTURE_TYPE_I || (s->m.mb_type[x + y * s->m.mb_stride] & CANDIDATE_MB_TYPE_INTRA)) { for (i = 0; i < 6; i++) init_put_bits(&s->reorder_pb[i], reorder_buffer[0][i], 7 * 32); - if (f->pict_type == AV_PICTURE_TYPE_P) { + if (s->pict_type == AV_PICTURE_TYPE_P) { const uint8_t *vlc = ff_svq1_block_type_vlc[SVQ1_BLOCK_INTRA]; put_bits(&s->reorder_pb[5], vlc[1], vlc[0]); score[0] = vlc[1] * lambda; @@ -393,7 +393,7 @@ static int svq1_encode_plane(SVQ1EncContext *s, int plane, best = 0; - if (f->pict_type == AV_PICTURE_TYPE_P) { + if (s->pict_type == AV_PICTURE_TYPE_P) { const uint8_t *vlc = ff_svq1_block_type_vlc[SVQ1_BLOCK_INTER]; int mx, my, pred_x, pred_y, dxy; int16_t *motion_ptr; @@ -499,7 +499,6 @@ static av_cold int svq1_encode_end(AVCodecContext *avctx) av_frame_free(&s->current_picture); av_frame_free(&s->last_picture); - av_frame_free(&avctx->coded_frame); return 0; } @@ -513,10 +512,9 @@ static av_cold int svq1_encode_init(AVCodecContext *avctx) ff_me_cmp_init(&s->mecc, avctx); ff_mpegvideoencdsp_init(&s->m.mpvencdsp, avctx); - avctx->coded_frame = av_frame_alloc(); s->current_picture = av_frame_alloc(); s->last_picture = av_frame_alloc(); - if (!avctx->coded_frame || !s->current_picture || !s->last_picture) { + if (!s->current_picture || !s->last_picture) { svq1_encode_end(avctx); return AVERROR(ENOMEM); } @@ -550,6 +548,12 @@ static av_cold int svq1_encode_init(AVCodecContext *avctx) s->y_block_height * sizeof(int32_t)); s->ssd_int8_vs_int16 = ssd_int8_vs_int16_c; + if (!s->m.me.temp || !s->m.me.scratchpad || !s->m.me.map || + !s->m.me.score_map || !s->mb_type || !s->dummy) { + svq1_encode_end(avctx); + return AVERROR(ENOMEM); + } + if (ARCH_PPC) ff_svq1enc_init_ppc(s); if (ARCH_X86) @@ -564,8 +568,8 @@ static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { SVQ1EncContext *const s = avctx->priv_data; - AVFrame *const p = avctx->coded_frame; int i, ret; + uint8_t *sd; if (!pkt->data && (ret = av_new_packet(pkt, s->y_block_width * s->y_block_height * @@ -580,21 +584,44 @@ static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt, } if (!s->current_picture->data[0]) { - ff_get_buffer(avctx, s->current_picture, 0); - ff_get_buffer(avctx, s->last_picture, 0); + ret = ff_get_buffer(avctx, s->current_picture, 0); + if (ret < 0) + return ret; + } + if (!s->last_picture->data[0]) { + ret = ff_get_buffer(avctx, s->last_picture, 0); + if (ret < 0) + return ret; + } + if (!s->scratchbuf) { s->scratchbuf = av_malloc(s->current_picture->linesize[0] * 16 * 2); + if (!s->scratchbuf) + return AVERROR(ENOMEM); } FFSWAP(AVFrame*, s->current_picture, s->last_picture); init_put_bits(&s->pb, pkt->data, pkt->size); - p->pict_type = avctx->gop_size && avctx->frame_number % avctx->gop_size ? - AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I; - p->key_frame = p->pict_type == AV_PICTURE_TYPE_I; - p->quality = pict->quality; + if (avctx->gop_size && (avctx->frame_number % avctx->gop_size)) + s->pict_type = AV_PICTURE_TYPE_P; + else + s->pict_type = AV_PICTURE_TYPE_I; + s->quality = pict->quality; + +#if FF_API_CODED_FRAME +FF_DISABLE_DEPRECATION_WARNINGS + avctx->coded_frame->pict_type = s->pict_type; + avctx->coded_frame->key_frame = s->pict_type == AV_PICTURE_TYPE_I; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + + sd = av_packet_new_side_data(pkt, AV_PKT_DATA_QUALITY_FACTOR, sizeof(int)); + if (!sd) + return AVERROR(ENOMEM); + *(int *)sd = pict->quality; - svq1_write_header(s, p->pict_type); + svq1_write_header(s, s->pict_type); for (i = 0; i < 3; i++) if (svq1_encode_plane(s, i, pict->data[i], @@ -603,8 +630,15 @@ static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt, s->frame_width / (i ? 4 : 1), s->frame_height / (i ? 4 : 1), pict->linesize[i], - s->current_picture->linesize[i]) < 0) + s->current_picture->linesize[i]) < 0) { + int j; + for (j = 0; j < i; j++) { + av_freep(&s->motion_val8[j]); + av_freep(&s->motion_val16[j]); + } + av_freep(&s->scratchbuf); return -1; + } // avpriv_align_put_bits(&s->pb); while (put_bits_count(&s->pb) & 31) @@ -613,7 +647,7 @@ static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt, flush_put_bits(&s->pb); pkt->size = put_bits_count(&s->pb) / 8; - if (p->pict_type == AV_PICTURE_TYPE_I) + if (s->pict_type == AV_PICTURE_TYPE_I) pkt->flags |= AV_PKT_FLAG_KEY; *got_packet = 1;