summaryrefslogtreecommitdiff
path: root/libavcodec/snow.c
diff options
context:
space:
mode:
Diffstat (limited to 'libavcodec/snow.c')
-rw-r--r--libavcodec/snow.c80
1 files changed, 46 insertions, 34 deletions
diff --git a/libavcodec/snow.c b/libavcodec/snow.c
index b9dab45c5f..3adf723f70 100644
--- a/libavcodec/snow.c
+++ b/libavcodec/snow.c
@@ -1,20 +1,20 @@
/*
* Copyright (C) 2004 Michael Niedermayer <michaelni@gmx.at>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -32,9 +32,6 @@
#include "mathops.h"
#include "h263.h"
-#undef NDEBUG
-#include <assert.h>
-
void ff_snow_inner_add_yblock(const uint8_t *obmc, const int obmc_stride, uint8_t * * block, int b_w, int b_h,
int src_x, int src_y, int src_stride, slice_buffer * sb, int add, uint8_t * dst8){
@@ -148,7 +145,7 @@ static void mc_block(Plane *p, uint8_t *dst, const uint8_t *src, int stride, int
int16_t *tmpI= tmpIt;
uint8_t *tmp2= tmp2t[0];
const uint8_t *hpel[11];
- assert(dx<16 && dy<16);
+ av_assert2(dx<16 && dy<16);
r= brane[dx + 16*dy]&15;
l= brane[dx + 16*dy]>>4;
@@ -338,7 +335,7 @@ void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, int stride,
}
}else{
uint8_t *src= s->last_picture[block->ref].data[plane_index];
- const int scale= plane_index ? s->mv_scale : 2*s->mv_scale;
+ const int scale= plane_index ? (2*s->mv_scale)>>s->chroma_h_shift : 2*s->mv_scale;
int mx= block->mx*scale;
int my= block->my*scale;
const int dx= mx&15;
@@ -347,15 +344,18 @@ void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, int stride,
sx += (mx>>4) - (HTAPS_MAX/2-1);
sy += (my>>4) - (HTAPS_MAX/2-1);
src += sx + sy*stride;
- if( (unsigned)sx >= w - b_w - (HTAPS_MAX-2)
- || (unsigned)sy >= h - b_h - (HTAPS_MAX-2)){
- s->dsp.emulated_edge_mc(tmp + MB_SIZE, src, stride, b_w+HTAPS_MAX-1, b_h+HTAPS_MAX-1, sx, sy, w, h);
+ if( (unsigned)sx >= FFMAX(w - b_w - (HTAPS_MAX-2), 0)
+ || (unsigned)sy >= FFMAX(h - b_h - (HTAPS_MAX-2), 0)){
+ s->vdsp.emulated_edge_mc(tmp + MB_SIZE, src, stride, b_w+HTAPS_MAX-1, b_h+HTAPS_MAX-1, sx, sy, w, h);
src= tmp + MB_SIZE;
}
+
+ av_assert2(s->chroma_h_shift == s->chroma_v_shift); // only one mv_scale
+
// assert(b_w == b_h || 2*b_w == b_h || b_w == 2*b_h);
// assert(!(b_w&(b_w-1)));
- assert(b_w>1 && b_h>1);
- assert((tab_index>=0 && tab_index<4) || b_w==32);
+ av_assert2(b_w>1 && b_h>1);
+ av_assert2((tab_index>=0 && tab_index<4) || b_w==32);
if((dx&3) || (dy&3) || !(b_w == b_h || 2*b_w == b_h || b_w == 2*b_h) || (b_w&(b_w-1)) || !s->plane[plane_index].fast_mc )
mc_block(&s->plane[plane_index], dst, src, stride, b_w, b_h, dx, dy);
else if(b_w==32){
@@ -370,7 +370,7 @@ void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, int stride,
s->dsp.put_h264_qpel_pixels_tab[tab_index+1][dy+(dx>>2)](dst ,src + 3 + 3*stride,stride);
s->dsp.put_h264_qpel_pixels_tab[tab_index+1][dy+(dx>>2)](dst+b_h,src + 3 + b_h + 3*stride,stride);
}else{
- assert(2*b_w==b_h);
+ av_assert2(2*b_w==b_h);
s->dsp.put_h264_qpel_pixels_tab[tab_index ][dy+(dx>>2)](dst ,src + 3 + 3*stride ,stride);
s->dsp.put_h264_qpel_pixels_tab[tab_index ][dy+(dx>>2)](dst+b_w*stride,src + 3 + 3*stride+b_w*stride,stride);
}
@@ -379,7 +379,7 @@ void ff_snow_pred_block(SnowContext *s, uint8_t *dst, uint8_t *tmp, int stride,
#define mca(dx,dy,b_w)\
static void mc_block_hpel ## dx ## dy ## b_w(uint8_t *dst, const uint8_t *src, int stride, int h){\
- assert(h==b_w);\
+ av_assert2(h==b_w);\
mc_block(NULL, dst, src-(HTAPS_MAX/2-1)-(HTAPS_MAX/2-1)*stride, stride, b_w, b_w, dx, dy);\
}
@@ -395,13 +395,13 @@ mca( 8, 8,8)
av_cold int ff_snow_common_init(AVCodecContext *avctx){
SnowContext *s = avctx->priv_data;
int width, height;
- int i, j, ret;
- int emu_buf_size;
+ int i, j;
s->avctx= avctx;
s->max_ref_frames=1; //just make sure its not an invalid value in case of no initial keyframe
ff_dsputil_init(&s->dsp, avctx);
+ ff_videodsp_init(&s->vdsp, 8);
ff_dwt_init(&s->dwt);
#define mcf(dx,dy)\
@@ -459,14 +459,6 @@ av_cold int ff_snow_common_init(AVCodecContext *avctx){
for(j=0; j<MAX_REF_FRAMES; j++)
ff_scale_mv_ref[i][j] = 256*(i+1)/(j+1);
- if ((ret = ff_get_buffer(s->avctx, &s->mconly_picture)) < 0) {
- av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
- return ret;
- }
- FF_ALLOC_OR_GOTO(avctx, s->scratchbuf, s->mconly_picture.linesize[0]*7*MB_SIZE, fail);
- emu_buf_size = s->mconly_picture.linesize[0] * (2 * MB_SIZE + HTAPS_MAX - 1);
- FF_ALLOC_OR_GOTO(avctx, s->emu_edge_buffer, emu_buf_size, fail);
-
return 0;
fail:
return AVERROR(ENOMEM);
@@ -475,6 +467,22 @@ fail:
int ff_snow_common_init_after_header(AVCodecContext *avctx) {
SnowContext *s = avctx->priv_data;
int plane_index, level, orientation;
+ int ret, emu_buf_size;
+
+ if(!s->scratchbuf) {
+ if ((ret = ff_get_buffer(s->avctx, &s->mconly_picture)) < 0) {
+ av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ FF_ALLOCZ_OR_GOTO(avctx, s->scratchbuf, FFMAX(s->mconly_picture.linesize[0], 2*avctx->width+256)*7*MB_SIZE, fail);
+ emu_buf_size = FFMAX(s->mconly_picture.linesize[0], 2*avctx->width+256) * (2 * MB_SIZE + HTAPS_MAX - 1);
+ FF_ALLOC_OR_GOTO(avctx, s->emu_edge_buffer, emu_buf_size, fail);
+ }
+
+ if(s->mconly_picture.format != avctx->pix_fmt) {
+ av_log(avctx, AV_LOG_ERROR, "pixel format changed\n");
+ return AVERROR_INVALIDDATA;
+ }
for(plane_index=0; plane_index<3; plane_index++){
int w= s->avctx->width;
@@ -523,6 +531,8 @@ int ff_snow_common_init_after_header(AVCodecContext *avctx) {
}
return 0;
+fail:
+ return AVERROR(ENOMEM);
}
#define USE_HALFPEL_PLANE 0
@@ -532,8 +542,8 @@ static void halfpel_interpol(SnowContext *s, uint8_t *halfpel[4][4], AVFrame *fr
for(p=0; p<3; p++){
int is_chroma= !!p;
- int w= s->avctx->width >>is_chroma;
- int h= s->avctx->height >>is_chroma;
+ int w= is_chroma ? s->avctx->width >>s->chroma_h_shift : s->avctx->width;
+ int h= is_chroma ? s->avctx->height>>s->chroma_v_shift : s->avctx->height;
int ls= frame->linesize[p];
uint8_t *src= frame->data[p];
@@ -592,11 +602,11 @@ int ff_snow_frame_start(SnowContext *s){
s->current_picture.linesize[0], w , h ,
EDGE_WIDTH , EDGE_WIDTH , EDGE_TOP | EDGE_BOTTOM);
s->dsp.draw_edges(s->current_picture.data[1],
- s->current_picture.linesize[1], w>>1, h>>1,
- EDGE_WIDTH/2, EDGE_WIDTH/2, EDGE_TOP | EDGE_BOTTOM);
+ s->current_picture.linesize[1], w>>s->chroma_h_shift, h>>s->chroma_v_shift,
+ EDGE_WIDTH>>s->chroma_h_shift, EDGE_WIDTH>>s->chroma_v_shift, EDGE_TOP | EDGE_BOTTOM);
s->dsp.draw_edges(s->current_picture.data[2],
- s->current_picture.linesize[2], w>>1, h>>1,
- EDGE_WIDTH/2, EDGE_WIDTH/2, EDGE_TOP | EDGE_BOTTOM);
+ s->current_picture.linesize[2], w>>s->chroma_h_shift, h>>s->chroma_v_shift,
+ EDGE_WIDTH>>s->chroma_h_shift, EDGE_WIDTH>>s->chroma_v_shift, EDGE_TOP | EDGE_BOTTOM);
}
ff_snow_release_buffer(s->avctx);
@@ -623,7 +633,7 @@ int ff_snow_frame_start(SnowContext *s){
}
}
- s->current_picture.reference= 1;
+ s->current_picture.reference= 3;
if(ff_get_buffer(s->avctx, &s->current_picture) < 0){
av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
return -1;
@@ -657,8 +667,10 @@ av_cold void ff_snow_common_end(SnowContext *s)
for(i=0; i<MAX_REF_FRAMES; i++){
av_freep(&s->ref_mvs[i]);
av_freep(&s->ref_scores[i]);
- if(s->last_picture[i].data[0])
+ if(s->last_picture[i].data[0]) {
+ av_assert0(s->last_picture[i].data[0] != s->current_picture.data[0]);
s->avctx->release_buffer(s->avctx, &s->last_picture[i]);
+ }
}
for(plane_index=0; plane_index<3; plane_index++){