6
6
* 4MV & hq & B-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at>
8
* This file is part of FFmpeg.
8
* This file is part of Libav.
10
* FFmpeg is free software; you can redistribute it and/or
10
* Libav is free software; you can redistribute it and/or
11
11
* modify it under the terms of the GNU Lesser General Public
12
12
* License as published by the Free Software Foundation; either
13
13
* version 2.1 of the License, or (at your option) any later version.
15
* FFmpeg is distributed in the hope that it will be useful,
15
* Libav is distributed in the hope that it will be useful,
16
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18
18
* Lesser General Public License for more details.
20
20
* You should have received a copy of the GNU Lesser General Public
21
* License along with FFmpeg; if not, write to the Free Software
21
* License along with Libav; if not, write to the Free Software
22
22
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
40
40
#include <limits.h>
42
42
int dct_quantize_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow);
43
int dct_quantize_trellis_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow);
44
void denoise_dct_c(MpegEncContext *s, DCTELEM *block);
47
45
* allocates a Picture
85
83
if(s->flags&CODEC_FLAG_EMU_EDGE){
86
84
if( (unsigned)src_x >= s->h_edge_pos - 17
87
85
|| (unsigned)src_y >= s->v_edge_pos - 17){
88
ff_emulated_edge_mc(s->edge_emu_buffer, ptr, linesize, 17, 17, src_x, src_y, s->h_edge_pos, s->v_edge_pos);
86
s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, linesize, 17, 17, src_x, src_y, s->h_edge_pos, s->v_edge_pos);
89
87
ptr= s->edge_emu_buffer;
124
122
if(s->flags&CODEC_FLAG_EMU_EDGE){
125
123
if( (unsigned)src_x >= (s->h_edge_pos>>1) - 9
126
124
|| (unsigned)src_y >= (s->v_edge_pos>>1) - 9){
127
ff_emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
125
s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
128
126
ptr= s->edge_emu_buffer;
134
132
ptr = ref_picture[2] + offset;
136
ff_emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
134
s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, uvlinesize, 9, 9, src_x, src_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
137
135
ptr= s->edge_emu_buffer;
139
137
s->dsp.gmc1(dest_cr, ptr, uvlinesize, 8, motion_x&15, motion_y&15, 128 - s->no_rounding);
225
223
if(s->unrestricted_mv && (s->flags&CODEC_FLAG_EMU_EDGE)){
226
224
if( (unsigned)src_x > h_edge_pos - (motion_x&1) - w
227
225
|| (unsigned)src_y > v_edge_pos - (motion_y&1) - h){
228
ff_emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, w+1, (h+1)<<field_based,
226
s->dsp.emulated_edge_mc(s->edge_emu_buffer, src, s->linesize, w+1, (h+1)<<field_based,
229
227
src_x, src_y<<field_based, h_edge_pos, s->v_edge_pos);
230
228
src= s->edge_emu_buffer;
317
315
"MPEG motion vector out of boundary (%d %d)\n", src_x, src_y);
320
ff_emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize,
318
s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize,
321
319
17, 17+field_based,
322
320
src_x, src_y<<field_based,
323
321
s->h_edge_pos, s->v_edge_pos);
324
322
ptr_y = s->edge_emu_buffer;
325
323
if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
326
324
uint8_t *uvbuf= s->edge_emu_buffer+18*s->linesize;
327
ff_emulated_edge_mc(uvbuf ,
325
s->dsp.emulated_edge_mc(uvbuf ,
328
326
ptr_cb, s->uvlinesize,
329
327
9, 9+field_based,
330
328
uvsrc_x, uvsrc_y<<field_based,
331
329
s->h_edge_pos>>1, s->v_edge_pos>>1);
332
ff_emulated_edge_mc(uvbuf+16,
330
s->dsp.emulated_edge_mc(uvbuf+16,
333
331
ptr_cr, s->uvlinesize,
334
332
9, 9+field_based,
335
333
uvsrc_x, uvsrc_y<<field_based,
515
513
if( (unsigned)src_x > s->h_edge_pos - (motion_x&3) - 16
516
514
|| (unsigned)src_y > v_edge_pos - (motion_y&3) - h ){
517
ff_emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize,
515
s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr_y, s->linesize,
518
516
17, 17+field_based, src_x, src_y<<field_based,
519
517
s->h_edge_pos, s->v_edge_pos);
520
518
ptr_y= s->edge_emu_buffer;
521
519
if(!CONFIG_GRAY || !(s->flags&CODEC_FLAG_GRAY)){
522
520
uint8_t *uvbuf= s->edge_emu_buffer + 18*s->linesize;
523
ff_emulated_edge_mc(uvbuf, ptr_cb, s->uvlinesize,
521
s->dsp.emulated_edge_mc(uvbuf, ptr_cb, s->uvlinesize,
524
522
9, 9 + field_based,
525
523
uvsrc_x, uvsrc_y<<field_based,
526
524
s->h_edge_pos>>1, s->v_edge_pos>>1);
527
ff_emulated_edge_mc(uvbuf + 16, ptr_cr, s->uvlinesize,
525
s->dsp.emulated_edge_mc(uvbuf + 16, ptr_cr, s->uvlinesize,
528
526
9, 9 + field_based,
529
527
uvsrc_x, uvsrc_y<<field_based,
530
528
s->h_edge_pos>>1, s->v_edge_pos>>1);
581
579
src_x = s->mb_x * 8 + mx;
582
580
src_y = s->mb_y * 8 + my;
583
src_x = av_clip(src_x, -8, s->width/2);
584
if (src_x == s->width/2)
581
src_x = av_clip(src_x, -8, (s->width >> 1));
582
if (src_x == (s->width >> 1))
586
src_y = av_clip(src_y, -8, s->height/2);
587
if (src_y == s->height/2)
584
src_y = av_clip(src_y, -8, (s->height >> 1));
585
if (src_y == (s->height >> 1))
590
588
offset = (src_y * (s->uvlinesize)) + src_x;
592
590
if(s->flags&CODEC_FLAG_EMU_EDGE){
593
591
if( (unsigned)src_x > (s->h_edge_pos>>1) - (dxy &1) - 8
594
592
|| (unsigned)src_y > (s->v_edge_pos>>1) - (dxy>>1) - 8){
595
ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize,
593
s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize,
596
594
9, 9, src_x, src_y,
597
595
s->h_edge_pos>>1, s->v_edge_pos>>1);
598
596
ptr= s->edge_emu_buffer;
604
602
ptr = ref_picture[2] + offset;
606
ff_emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize,
604
s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize,
607
605
9, 9, src_x, src_y,
608
606
s->h_edge_pos>>1, s->v_edge_pos>>1);
609
607
ptr= s->edge_emu_buffer;
631
629
* @param dest_cr chroma cr/v destination pointer
632
630
* @param dir direction (0->forward, 1->backward)
633
631
* @param ref_picture array[3] of pointers to the 3 planes of the reference picture
634
* @param pic_op halfpel motion compensation function (average or put normally)
635
* @param pic_op qpel motion compensation function (average or put normally)
632
* @param pix_op halfpel motion compensation function (average or put normally)
633
* @param qpix_op qpel motion compensation function (average or put normally)
636
634
* the motion vectors are taken from s->mv and the MV type from s->mv_type
638
636
static av_always_inline void MPV_motion_internal(MpegEncContext *s,
672
670
if(mb_x==0 || IS_INTRA(s->current_picture.mb_type[xy-1])){
673
*(int32_t*)mv_cache[1][0]= *(int32_t*)mv_cache[1][1];
674
*(int32_t*)mv_cache[2][0]= *(int32_t*)mv_cache[2][1];
671
AV_COPY32(mv_cache[1][0], mv_cache[1][1]);
672
AV_COPY32(mv_cache[2][0], mv_cache[2][1]);
676
*(int32_t*)mv_cache[1][0]= *(int32_t*)s->current_picture.motion_val[0][mot_xy-1];
677
*(int32_t*)mv_cache[2][0]= *(int32_t*)s->current_picture.motion_val[0][mot_xy-1+mot_stride];
674
AV_COPY32(mv_cache[1][0], s->current_picture.motion_val[0][mot_xy-1]);
675
AV_COPY32(mv_cache[2][0], s->current_picture.motion_val[0][mot_xy-1+mot_stride]);
680
678
if(mb_x+1>=s->mb_width || IS_INTRA(s->current_picture.mb_type[xy+1])){
681
*(int32_t*)mv_cache[1][3]= *(int32_t*)mv_cache[1][2];
682
*(int32_t*)mv_cache[2][3]= *(int32_t*)mv_cache[2][2];
679
AV_COPY32(mv_cache[1][3], mv_cache[1][2]);
680
AV_COPY32(mv_cache[2][3], mv_cache[2][2]);
684
*(int32_t*)mv_cache[1][3]= *(int32_t*)s->current_picture.motion_val[0][mot_xy+2];
685
*(int32_t*)mv_cache[2][3]= *(int32_t*)s->current_picture.motion_val[0][mot_xy+2+mot_stride];
682
AV_COPY32(mv_cache[1][3], s->current_picture.motion_val[0][mot_xy+2]);
683
AV_COPY32(mv_cache[2][3], s->current_picture.motion_val[0][mot_xy+2+mot_stride]);
764
762
if(s->flags&CODEC_FLAG_EMU_EDGE){
765
763
if( (unsigned)src_x > s->h_edge_pos - (motion_x&3) - 8
766
764
|| (unsigned)src_y > s->v_edge_pos - (motion_y&3) - 8 ){
767
ff_emulated_edge_mc(s->edge_emu_buffer, ptr,
765
s->dsp.emulated_edge_mc(s->edge_emu_buffer, ptr,
768
766
s->linesize, 9, 9,
770
768
s->h_edge_pos, s->v_edge_pos);