The part of said function that is common to both encoder and decoder is negligible since c954cf1e1b766a0d1992d5be0a8be0055a8e1a6a and more than offset by the costs of "Am I an encoder?" checks. So move allocating the frames to the encoder and decoder directly. Also rename ff_snow_frame_start() to ff_snow_frames_prepare(), because a frame without a buffer has not been properly started.
Unified · Split
| @@ -22,7 +22,6 @@ · 21 unmodified lines | ||
| 22 | 22 | #include "libavutil/thread.h" |
| 23 | 23 | #include "avcodec.h" |
| 24 | 24 | #include "decode.h" |
| 25 | −#include "encode.h" | |
| 26 | 25 | #include "snow_dwt.h" |
| 27 | 26 | #include "snow.h" |
| 28 | 27 | #include "snowdata.h" |
| @@ -61,36 +60,6 @@ void ff_snow_inner_add_yblock(const uint8_t *obmc, const int obmc_stride, uint8_ · 32 unmodified lines | ||
| 61 | 60 | } |
| 62 | 61 | } |
| 63 | 62 | |
| 64 | −int ff_snow_get_buffer(SnowContext *s, AVFrame *frame) | |
| 65 | −{ | |
| 66 | − int ret, i; | |
| 67 | − int edges_needed = av_codec_is_encoder(s->avctx->codec); | |
| 68 | − | |
| 69 | − frame->width = s->avctx->width ; | |
| 70 | − frame->height = s->avctx->height; | |
| 71 | − if (edges_needed) { | |
| 72 | − frame->width += 2 * EDGE_WIDTH; | |
| 73 | − frame->height += 2 * EDGE_WIDTH; | |
| 74 | − | |
| 75 | − ret = ff_encode_alloc_frame(s->avctx, frame); | |
| 76 | − } else | |
| 77 | − ret = ff_get_buffer(s->avctx, frame, AV_GET_BUFFER_FLAG_REF); | |
| 78 | − if (ret < 0) | |
| 79 | − return ret; | |
| 80 | − if (edges_needed) { | |
| 81 | − for (i = 0; frame->data[i]; i++) { | |
| 82 | − int offset = (EDGE_WIDTH >> (i ? s->chroma_v_shift : 0)) * | |
| 83 | − frame->linesize[i] + | |
| 84 | − (EDGE_WIDTH >> (i ? s->chroma_h_shift : 0)); | |
| 85 | − frame->data[i] += offset; | |
| 86 | − } | |
| 87 | − frame->width = s->avctx->width; | |
| 88 | − frame->height = s->avctx->height; | |
| 89 | − } | |
| 90 | − | |
| 91 | − return 0; | |
| 92 | −} | |
| 93 | − | |
| 94 | 63 | void ff_snow_reset_contexts(SnowContext *s){ //FIXME better initial contexts |
| 95 | 64 | int plane_index, level, orientation; |
| 96 | 65 | |
| @@ -589,20 +558,21 @@ void ff_snow_release_buffer(AVCodecContext *avctx) · 492 unmodified lines | ||
| 589 | 558 | } |
| 590 | 559 | } |
| 591 | 560 | |
| 592 | −int ff_snow_frame_start(SnowContext *s){ | |
| 561 | +int ff_snow_frames_prepare(SnowContext *s) | |
| 562 | +{ | |
| 593 | 563 | AVFrame *tmp; |
| 594 | − int i, ret; | |
| 595 | 564 | |
| 596 | 565 | ff_snow_release_buffer(s->avctx); |
| 597 | 566 | |
| 598 | 567 | tmp= s->last_picture[s->max_ref_frames-1]; |
| 599 | − for(i=s->max_ref_frames-1; i>0; i--) | |
| 568 | + for (int i = s->max_ref_frames - 1; i > 0; i--) | |
| 600 | 569 | s->last_picture[i] = s->last_picture[i-1]; |
| 601 | 570 | s->last_picture[0] = s->current_picture; |
| 602 | 571 | s->current_picture = tmp; |
| 603 | 572 | |
| 604 | 573 | if(s->keyframe){ |
| 605 | 574 | s->ref_frames= 0; |
| 575 | + s->current_picture->flags |= AV_FRAME_FLAG_KEY; | |
| 606 | 576 | }else{ |
| 607 | 577 | int i; |
| 608 | 578 | for(i=0; i<s->max_ref_frames && s->last_picture[i]->data[0]; i++) |
| @@ -613,14 +583,8 @@ int ff_snow_frame_start(SnowContext *s){ · 4 unmodified lines | ||
| 613 | 583 | av_log(s->avctx,AV_LOG_ERROR, "No reference frames\n"); |
| 614 | 584 | return AVERROR_INVALIDDATA; |
| 615 | 585 | } |
| 616 | − } | |
| 617 | − if ((ret = ff_snow_get_buffer(s, s->current_picture)) < 0) | |
| 618 | − return ret; | |
| 619 | − | |
| 620 | − if (s->keyframe) | |
| 621 | − s->current_picture->flags |= AV_FRAME_FLAG_KEY; | |
| 622 | − else | |
| 623 | 586 | s->current_picture->flags &= ~AV_FRAME_FLAG_KEY; |
| 587 | + } | |
| 624 | 588 | |
| 625 | 589 | return 0; |
| 626 | 590 | } |
| @@ -245,11 +245,10 @@ void ff_snow_common_end(SnowContext *s); · 244 unmodified lines | ||
| 245 | 245 | void ff_snow_release_buffer(AVCodecContext *avctx); |
| 246 | 246 | void ff_snow_reset_contexts(SnowContext *s); |
| 247 | 247 | int ff_snow_alloc_blocks(SnowContext *s); |
| 248 | −int ff_snow_frame_start(SnowContext *s); | |
| 248 | +int ff_snow_frames_prepare(SnowContext *s); | |
| 249 | 249 | void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, ptrdiff_t stride, |
| 250 | 250 | int sx, int sy, int b_w, int b_h, const BlockNode *block, |
| 251 | 251 | int plane_index, int w, int h); |
| 252 | −int ff_snow_get_buffer(SnowContext *s, AVFrame *frame); | |
| 253 | 252 | /* common inline functions */ |
| 254 | 253 | //XXX doublecheck all of them should stay inlined |
| 255 | 254 | |
| @@ -24,6 +24,7 @@ · 23 unmodified lines | ||
| 24 | 24 | #include "libavutil/opt.h" |
| 25 | 25 | #include "avcodec.h" |
| 26 | 26 | #include "codec_internal.h" |
| 27 | +#include "decode.h" | |
| 27 | 28 | #include "snow_dwt.h" |
| 28 | 29 | #include "snow.h" |
| 29 | 30 | |
| @@ -475,7 +476,13 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *picture, · 445 unmodified lines | ||
| 475 | 476 | |
| 476 | 477 | ff_snow_alloc_blocks(s); |
| 477 | 478 | |
| 478 | − if((res = ff_snow_frame_start(s)) < 0) | |
| 479 | + if ((res = ff_snow_frames_prepare(s)) < 0) | |
| 480 | + return res; | |
| 481 | + | |
| 482 | + s->current_picture->width = s->avctx->width; | |
| 483 | + s->current_picture->height = s->avctx->height; | |
| 484 | + res = ff_get_buffer(s->avctx, s->current_picture, AV_GET_BUFFER_FLAG_REF); | |
| 485 | + if (res < 0) | |
| 479 | 486 | return res; |
| 480 | 487 | |
| 481 | 488 | s->current_picture->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; |
| @@ -39,6 +39,28 @@ · 38 unmodified lines | ||
| 39 | 39 | #include "mpegvideo.h" |
| 40 | 40 | #include "h263enc.h" |
| 41 | 41 | |
| 42 | +static int get_encode_buffer(SnowContext *s, AVFrame *frame) | |
| 43 | +{ | |
| 44 | + int ret; | |
| 45 | + | |
| 46 | + frame->width = s->avctx->width + 2 * EDGE_WIDTH; | |
| 47 | + frame->height = s->avctx->height + 2 * EDGE_WIDTH; | |
| 48 | + | |
| 49 | + ret = ff_encode_alloc_frame(s->avctx, frame); | |
| 50 | + if (ret < 0) | |
| 51 | + return ret; | |
| 52 | + for (int i = 0; frame->data[i]; i++) { | |
| 53 | + int offset = (EDGE_WIDTH >> (i ? s->chroma_v_shift : 0)) * | |
| 54 | + frame->linesize[i] + | |
| 55 | + (EDGE_WIDTH >> (i ? s->chroma_h_shift : 0)); | |
| 56 | + frame->data[i] += offset; | |
| 57 | + } | |
| 58 | + frame->width = s->avctx->width; | |
| 59 | + frame->height = s->avctx->height; | |
| 60 | + | |
| 61 | + return 0; | |
| 62 | +} | |
| 63 | + | |
| 42 | 64 | static av_cold int encode_init(AVCodecContext *avctx) |
| 43 | 65 | { |
| 44 | 66 | SnowContext *s = avctx->priv_data; |
| @@ -140,7 +162,7 @@ static av_cold int encode_init(AVCodecContext *avctx) · 95 unmodified lines | ||
| 140 | 162 | if (!s->input_picture) |
| 141 | 163 | return AVERROR(ENOMEM); |
| 142 | 164 | |
| 143 | − if ((ret = ff_snow_get_buffer(s, s->input_picture)) < 0) | |
| 165 | + if ((ret = get_encode_buffer(s, s->input_picture)) < 0) | |
| 144 | 166 | return ret; |
| 145 | 167 | |
| 146 | 168 | if(s->motion_est == FF_ME_ITER){ |
| @@ -1659,7 +1681,10 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, · 1512 unmodified lines | ||
| 1659 | 1681 | emms_c(); |
| 1660 | 1682 | } |
| 1661 | 1683 | |
| 1662 | − ff_snow_frame_start(s); | |
| 1684 | + ff_snow_frames_prepare(s); | |
| 1685 | + ret = get_encode_buffer(s, s->current_picture); | |
| 1686 | + if (ret < 0) | |
| 1687 | + return ret; | |
| 1663 | 1688 | |
| 1664 | 1689 | s->m.current_picture_ptr= &s->m.current_picture; |
| 1665 | 1690 | s->m.current_picture.f = s->current_picture; |