summaryrefslogtreecommitdiff
path: root/libavcodec/rv34.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2011-08-13 02:16:44 +0200
committerMichael Niedermayer <michaelni@gmx.at>2011-08-13 02:56:08 +0200
commit0cb233cf46e057c4d4d9352470305de3f569a036 (patch)
treefcca8a6d95237f126cb466b708da2f6c1433428f /libavcodec/rv34.c
parent931187e117c299271df8c4caf1f8c656baf80a6b (diff)
parentb2c087871dafc7d030b2d48457ddff597dfd4925 (diff)
Merge commit 'b2c087871dafc7d030b2d48457ddff597dfd4925'
* commit 'b2c087871dafc7d030b2d48457ddff597dfd4925': Move x86util.asm from libavcodec/ to libavutil/. Move x86inc.asm to libavutil/. APIchanges: note error_recognition in lavf lavf: add support for error_recognition, use it in avidec, and bump minor API version avconv: change semantics of -map avconv: get rid of new* options. cmdutils: allow precisely specifying a stream for AVOptions. configure: add missing CFLAGS to fix building on the HURD libx264: Include hint for possible values for configuring libx264 cmdutils: allow ':'-separated modifiers in option names. avconv: make -map_metadata work consistently with the other options avconv: remove deprecated options. avconv: make -map_chapters accept only the input file index. Make a copy of ffmpeg under a new name -- avconv. ffmpeg: add a warning stating that the program is deprecated. Add weighted motion compensation for RV40 B-frames RV3/4: calculate B-frame motion weights once per frame Move RV3/4-specific DSP functions into their own context mjpeg: propagate decode errors from ff_mjpeg_decode_sos and ff_mjpeg_decode_dqt h264: notice memory allocation failure Conflicts: .gitignore Makefile cmdutils.c configure doc/ffplay.texi doc/ffprobe.texi doc/ffserver.texi libavcodec/libx264.c libavformat/avformat.h libavformat/avidec.c libavformat/version.h tests/lavf-regression.sh tests/lavfi-regression.sh Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/rv34.c')
-rw-r--r--libavcodec/rv34.c124
1 files changed, 92 insertions, 32 deletions
diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c
index f97e4accdf..193c807d25 100644
--- a/libavcodec/rv34.c
+++ b/libavcodec/rv34.c
@@ -568,12 +568,8 @@ static void rv34_pred_mv(RV34DecContext *r, int block_type, int subblock_no, int
*/
static int calc_add_mv(RV34DecContext *r, int dir, int val)
{
- int refdist = GET_PTS_DIFF(r->next_pts, r->last_pts);
- int dist = dir ? -GET_PTS_DIFF(r->next_pts, r->cur_pts) : GET_PTS_DIFF(r->cur_pts, r->last_pts);
- int mul;
+ int mul = dir ? -r->weight2 : r->weight1;
- if(!refdist) return 0;
- mul = (dist << 14) / refdist;
return (val * mul + 0x2000) >> 14;
}
@@ -721,7 +717,7 @@ static const int chroma_coeffs[3] = { 0, 3, 5 };
static inline void rv34_mc(RV34DecContext *r, const int block_type,
const int xoff, const int yoff, int mv_off,
const int width, const int height, int dir,
- const int thirdpel,
+ const int thirdpel, int weighted,
qpel_mc_func (*qpel_mc)[16],
h264_chroma_mc_func (*chroma_mc))
{
@@ -785,9 +781,15 @@ static inline void rv34_mc(RV34DecContext *r, const int block_type,
srcU = uvbuf;
srcV = uvbuf + 16;
}
- Y = s->dest[0] + xoff + yoff *s->linesize;
- U = s->dest[1] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
- V = s->dest[2] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
+ if(!weighted){
+ Y = s->dest[0] + xoff + yoff *s->linesize;
+ U = s->dest[1] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
+ V = s->dest[2] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
+ }else{
+ Y = r->tmp_b_block_y [dir] + xoff + yoff *s->linesize;
+ U = r->tmp_b_block_uv[dir*2] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
+ V = r->tmp_b_block_uv[dir*2+1] + (xoff>>1) + (yoff>>1)*s->uvlinesize;
+ }
if(block_type == RV34_MB_P_16x8){
qpel_mc[1][dxy](Y, srcY, s->linesize);
@@ -808,43 +810,70 @@ static void rv34_mc_1mv(RV34DecContext *r, const int block_type,
const int xoff, const int yoff, int mv_off,
const int width, const int height, int dir)
{
- rv34_mc(r, block_type, xoff, yoff, mv_off, width, height, dir, r->rv30,
- r->rv30 ? r->s.dsp.put_rv30_tpel_pixels_tab
- : r->s.dsp.put_rv40_qpel_pixels_tab,
- r->rv30 ? r->s.dsp.put_h264_chroma_pixels_tab
- : r->s.dsp.put_rv40_chroma_pixels_tab);
+ rv34_mc(r, block_type, xoff, yoff, mv_off, width, height, dir, r->rv30, 0,
+ r->rdsp.put_pixels_tab,
+ r->rdsp.put_chroma_pixels_tab);
+}
+
+static void rv4_weight(RV34DecContext *r)
+{
+ r->rdsp.rv40_weight_pixels_tab[0](r->s.dest[0],
+ r->tmp_b_block_y[0],
+ r->tmp_b_block_y[1],
+ r->weight1,
+ r->weight2,
+ r->s.linesize);
+ r->rdsp.rv40_weight_pixels_tab[1](r->s.dest[1],
+ r->tmp_b_block_uv[0],
+ r->tmp_b_block_uv[2],
+ r->weight1,
+ r->weight2,
+ r->s.uvlinesize);
+ r->rdsp.rv40_weight_pixels_tab[1](r->s.dest[2],
+ r->tmp_b_block_uv[1],
+ r->tmp_b_block_uv[3],
+ r->weight1,
+ r->weight2,
+ r->s.uvlinesize);
}
static void rv34_mc_2mv(RV34DecContext *r, const int block_type)
{
- rv34_mc(r, block_type, 0, 0, 0, 2, 2, 0, r->rv30,
- r->rv30 ? r->s.dsp.put_rv30_tpel_pixels_tab
- : r->s.dsp.put_rv40_qpel_pixels_tab,
- r->rv30 ? r->s.dsp.put_h264_chroma_pixels_tab
- : r->s.dsp.put_rv40_chroma_pixels_tab);
- rv34_mc(r, block_type, 0, 0, 0, 2, 2, 1, r->rv30,
- r->rv30 ? r->s.dsp.avg_rv30_tpel_pixels_tab
- : r->s.dsp.avg_rv40_qpel_pixels_tab,
- r->rv30 ? r->s.dsp.avg_h264_chroma_pixels_tab
- : r->s.dsp.avg_rv40_chroma_pixels_tab);
+ int weighted = !r->rv30 && block_type != RV34_MB_B_BIDIR && r->weight1 != 8192;
+
+ rv34_mc(r, block_type, 0, 0, 0, 2, 2, 0, r->rv30, weighted,
+ r->rdsp.put_pixels_tab,
+ r->rdsp.put_chroma_pixels_tab);
+ if(!weighted){
+ rv34_mc(r, block_type, 0, 0, 0, 2, 2, 1, r->rv30, 0,
+ r->rdsp.avg_pixels_tab,
+ r->rdsp.avg_chroma_pixels_tab);
+ }else{
+ rv34_mc(r, block_type, 0, 0, 0, 2, 2, 1, r->rv30, 1,
+ r->rdsp.put_pixels_tab,
+ r->rdsp.put_chroma_pixels_tab);
+ rv4_weight(r);
+ }
}
static void rv34_mc_2mv_skip(RV34DecContext *r)
{
int i, j;
+ int weighted = !r->rv30 && r->weight1 != 8192;
+
for(j = 0; j < 2; j++)
for(i = 0; i < 2; i++){
rv34_mc(r, RV34_MB_P_8x8, i*8, j*8, i+j*r->s.b8_stride, 1, 1, 0, r->rv30,
- r->rv30 ? r->s.dsp.put_rv30_tpel_pixels_tab
- : r->s.dsp.put_rv40_qpel_pixels_tab,
- r->rv30 ? r->s.dsp.put_h264_chroma_pixels_tab
- : r->s.dsp.put_rv40_chroma_pixels_tab);
+ weighted,
+ r->rdsp.put_pixels_tab,
+ r->rdsp.put_chroma_pixels_tab);
rv34_mc(r, RV34_MB_P_8x8, i*8, j*8, i+j*r->s.b8_stride, 1, 1, 1, r->rv30,
- r->rv30 ? r->s.dsp.avg_rv30_tpel_pixels_tab
- : r->s.dsp.avg_rv40_qpel_pixels_tab,
- r->rv30 ? r->s.dsp.avg_h264_chroma_pixels_tab
- : r->s.dsp.avg_rv40_chroma_pixels_tab);
+ weighted,
+ weighted ? r->rdsp.put_pixels_tab : r->rdsp.avg_pixels_tab,
+ weighted ? r->rdsp.put_chroma_pixels_tab : r->rdsp.avg_chroma_pixels_tab);
}
+ if(weighted)
+ rv4_weight(r);
}
/** number of motion vectors in each macroblock type */
@@ -1279,10 +1308,31 @@ static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int
if(MPV_frame_start(s, s->avctx) < 0)
return -1;
ff_er_frame_start(s);
+ if (!r->tmp_b_block_base || s->width != r->si.width || s->height != r->si.height) {
+ int i;
+
+ r->tmp_b_block_base = av_realloc(r->tmp_b_block_base, s->linesize * 48);
+ for (i = 0; i < 2; i++)
+ r->tmp_b_block_y[i] = r->tmp_b_block_base + i * 16 * s->linesize;
+ for (i = 0; i < 4; i++)
+ r->tmp_b_block_uv[i] = r->tmp_b_block_base + 32 * s->linesize
+ + (i >> 1) * 8 * s->uvlinesize + (i & 1) * 16;
+ }
r->cur_pts = r->si.pts;
if(s->pict_type != AV_PICTURE_TYPE_B){
r->last_pts = r->next_pts;
r->next_pts = r->cur_pts;
+ }else{
+ int refdist = GET_PTS_DIFF(r->next_pts, r->last_pts);
+ int dist0 = GET_PTS_DIFF(r->cur_pts, r->last_pts);
+ int dist1 = GET_PTS_DIFF(r->next_pts, r->cur_pts);
+
+ if(!refdist){
+ r->weight1 = r->weight2 = 8192;
+ }else{
+ r->weight1 = (dist0 << 14) / refdist;
+ r->weight2 = (dist1 << 14) / refdist;
+ }
}
s->mb_x = s->mb_y = 0;
}
@@ -1363,6 +1413,15 @@ av_cold int ff_rv34_decode_init(AVCodecContext *avctx)
ff_h264_pred_init(&r->h, CODEC_ID_RV40, 8);
+#if CONFIG_RV30_DECODER
+ if (avctx->codec_id == CODEC_ID_RV30)
+ ff_rv30dsp_init(&r->rdsp, &r->s.dsp);
+#endif
+#if CONFIG_RV40_DECODER
+ if (avctx->codec_id == CODEC_ID_RV40)
+ ff_rv40dsp_init(&r->rdsp, &r->s.dsp);
+#endif
+
r->intra_types_stride = 4*s->mb_stride + 4;
r->intra_types_hist = av_malloc(r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist));
r->intra_types = r->intra_types_hist + r->intra_types_stride * 4;
@@ -1494,6 +1553,7 @@ av_cold int ff_rv34_decode_end(AVCodecContext *avctx)
av_freep(&r->intra_types_hist);
r->intra_types = NULL;
+ av_freep(&r->tmp_b_block_base);
av_freep(&r->mb_type);
av_freep(&r->cbp_luma);
av_freep(&r->cbp_chroma);