comparison mpegvideo.c @ 553:18ad513d92fe libavcodec

direct rendering method 1 support
author michaelni
date Sun, 14 Jul 2002 18:37:35 +0000
parents 218eb765c987
children 3eb6fe38019a
comparison
equal deleted inserted replaced
552:26971b5a271d 553:18ad513d92fe
142 s->dct_unquantize = s->dct_unquantize_mpeg1; 142 s->dct_unquantize = s->dct_unquantize_mpeg1;
143 143
144 s->mb_width = (s->width + 15) / 16; 144 s->mb_width = (s->width + 15) / 16;
145 s->mb_height = (s->height + 15) / 16; 145 s->mb_height = (s->height + 15) / 16;
146 s->mb_num = s->mb_width * s->mb_height; 146 s->mb_num = s->mb_width * s->mb_height;
147 s->linesize = s->mb_width * 16 + 2 * EDGE_WIDTH; 147 if(!(s->flags&CODEC_FLAG_DR1)){
148 148 s->linesize = s->mb_width * 16 + 2 * EDGE_WIDTH;
149 for(i=0;i<3;i++) { 149
150 for(i=0;i<3;i++) {
150 int w, h, shift, pict_start; 151 int w, h, shift, pict_start;
151 152
152 w = s->linesize; 153 w = s->linesize;
153 h = s->mb_height * 16 + 2 * EDGE_WIDTH; 154 h = s->mb_height * 16 + 2 * EDGE_WIDTH;
154 shift = (i == 0) ? 0 : 1; 155 shift = (i == 0) ? 0 : 1;
171 CHECKED_ALLOCZ(pict, c_size) 172 CHECKED_ALLOCZ(pict, c_size)
172 s->aux_picture_base[i] = pict; 173 s->aux_picture_base[i] = pict;
173 s->aux_picture[i] = pict + pict_start; 174 s->aux_picture[i] = pict + pict_start;
174 if(i>0) memset(s->aux_picture_base[i], 128, c_size); 175 if(i>0) memset(s->aux_picture_base[i], 128, c_size);
175 } 176 }
176 } 177 }
178 }
179
180 CHECKED_ALLOCZ(s->edge_emu_buffer, (s->width+32)*2*17);
177 181
178 if (s->encoding) { 182 if (s->encoding) {
179 int j; 183 int j;
180 int mv_table_size= (s->mb_width+2)*(s->mb_height+2); 184 int mv_table_size= (s->mb_width+2)*(s->mb_height+2);
181 185
265 269
266 CHECKED_ALLOCZ(s->qscale_table , s->mb_num * sizeof(UINT8)) 270 CHECKED_ALLOCZ(s->qscale_table , s->mb_num * sizeof(UINT8))
267 } 271 }
268 /* default structure is frame */ 272 /* default structure is frame */
269 s->picture_structure = PICT_FRAME; 273 s->picture_structure = PICT_FRAME;
270 274
271 /* init macroblock skip table */ 275 /* init macroblock skip table */
272 CHECKED_ALLOCZ(s->mbskip_table, s->mb_num); 276 CHECKED_ALLOCZ(s->mbskip_table, s->mb_num);
273 277
274 s->block= s->blocks[0]; 278 s->block= s->blocks[0];
275 279
313 317
314 av_freep(&s->mbskip_table); 318 av_freep(&s->mbskip_table);
315 av_freep(&s->bitstream_buffer); 319 av_freep(&s->bitstream_buffer);
316 av_freep(&s->tex_pb_buffer); 320 av_freep(&s->tex_pb_buffer);
317 av_freep(&s->pb2_buffer); 321 av_freep(&s->pb2_buffer);
322 av_freep(&s->edge_emu_buffer);
323
318 for(i=0;i<3;i++) { 324 for(i=0;i<3;i++) {
319 int j; 325 int j;
320 av_freep(&s->last_picture_base[i]); 326 if(!(s->flags&CODEC_FLAG_DR1)){
321 av_freep(&s->next_picture_base[i]); 327 av_freep(&s->last_picture_base[i]);
322 av_freep(&s->aux_picture_base[i]); 328 av_freep(&s->next_picture_base[i]);
329 av_freep(&s->aux_picture_base[i]);
330 }
331 s->last_picture_base[i]=
332 s->next_picture_base[i]=
333 s->aux_picture_base [i] = NULL;
334 s->last_picture[i]=
335 s->next_picture[i]=
336 s->aux_picture [i] = NULL;
337
323 for(j=0; j<REORDER_BUFFER_SIZE; j++){ 338 for(j=0; j<REORDER_BUFFER_SIZE; j++){
324 av_freep(&s->picture_buffer[j][i]); 339 av_freep(&s->picture_buffer[j][i]);
325 } 340 }
326 } 341 }
327 s->context_initialized = 0; 342 s->context_initialized = 0;
593 memset(last_line + (i + 1) * wrap + width, last_line[width-1], w); /* top right */ 608 memset(last_line + (i + 1) * wrap + width, last_line[width-1], w); /* top right */
594 } 609 }
595 } 610 }
596 611
597 /* generic function for encode/decode called before a frame is coded/decoded */ 612 /* generic function for encode/decode called before a frame is coded/decoded */
598 void MPV_frame_start(MpegEncContext *s) 613 void MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)
599 { 614 {
600 int i; 615 int i;
601 UINT8 *tmp; 616 UINT8 *tmp;
602 617
603 s->mb_skiped = 0; 618 s->mb_skiped = 0;
604 s->decoding_error=0; 619 s->decoding_error=0;
605 620
621 if(avctx->flags&CODEC_FLAG_DR1){
622 int i;
623 avctx->get_buffer_callback(avctx, s->width, s->height, s->pict_type);
624
625 s->linesize= avctx->dr_stride;
626 }
627
606 if (s->pict_type == B_TYPE) { 628 if (s->pict_type == B_TYPE) {
607 for(i=0;i<3;i++) { 629 for(i=0;i<3;i++) {
630 if(avctx->flags&CODEC_FLAG_DR1)
631 s->aux_picture[i]= avctx->dr_buffer[i];
632
608 s->current_picture[i] = s->aux_picture[i]; 633 s->current_picture[i] = s->aux_picture[i];
609 } 634 }
610 } else { 635 } else {
611 for(i=0;i<3;i++) { 636 for(i=0;i<3;i++) {
612 /* swap next and last */ 637 /* swap next and last */
613 tmp = s->last_picture[i]; 638 if(avctx->flags&CODEC_FLAG_DR1)
639 tmp= avctx->dr_buffer[i];
640 else
641 tmp = s->last_picture[i];
642
614 s->last_picture[i] = s->next_picture[i]; 643 s->last_picture[i] = s->next_picture[i];
615 s->next_picture[i] = tmp; 644 s->next_picture[i] = tmp;
616 s->current_picture[i] = tmp; 645 s->current_picture[i] = tmp;
646
647 s->last_dr_opaque= s->next_dr_opaque;
648 s->next_dr_opaque= avctx->dr_opaque_frame;
649
650 if(s->has_b_frames && s->last_dr_opaque)
651 avctx->dr_opaque_frame= s->last_dr_opaque;
652 else
653 avctx->dr_opaque_frame= s->next_dr_opaque;
617 } 654 }
618 } 655 }
619 } 656 }
620 657
621 /* generic function for encode/decode called after a frame has been coded/decoded */ 658 /* generic function for encode/decode called after a frame has been coded/decoded */
622 void MPV_frame_end(MpegEncContext *s) 659 void MPV_frame_end(MpegEncContext *s)
623 { 660 {
624 // if((s->picture_number%100)==0 && s->encoding) printf("sads:%d //\n", sads); 661 // if((s->picture_number%100)==0 && s->encoding) printf("sads:%d //\n", sads);
625 662
626 /* draw edge for correct motion prediction if outside */ 663 /* draw edge for correct motion prediction if outside */
627 if (s->pict_type != B_TYPE && !s->intra_only) { 664 if (s->pict_type != B_TYPE && !s->intra_only && !(s->flags&CODEC_FLAG_EMU_EDGE)) {
628 if(s->avctx==NULL || s->avctx->codec->id!=CODEC_ID_MPEG4 || s->divx_version>=500){ 665 if(s->avctx==NULL || s->avctx->codec->id!=CODEC_ID_MPEG4 || s->divx_version>=500){
629 draw_edges(s->current_picture[0], s->linesize, s->mb_width*16, s->mb_height*16, EDGE_WIDTH); 666 draw_edges(s->current_picture[0], s->linesize, s->mb_width*16, s->mb_height*16, EDGE_WIDTH);
630 draw_edges(s->current_picture[1], s->linesize/2, s->mb_width*8, s->mb_height*8, EDGE_WIDTH/2); 667 draw_edges(s->current_picture[1], s->linesize/2, s->mb_width*8, s->mb_height*8, EDGE_WIDTH/2);
631 draw_edges(s->current_picture[2], s->linesize/2, s->mb_width*8, s->mb_height*8, EDGE_WIDTH/2); 668 draw_edges(s->current_picture[2], s->linesize/2, s->mb_width*8, s->mb_height*8, EDGE_WIDTH/2);
632 }else{ 669 }else{
774 s->qscale= s->coded_order[0].qscale; 811 s->qscale= s->coded_order[0].qscale;
775 s->force_type= s->coded_order[0].force_type; 812 s->force_type= s->coded_order[0].force_type;
776 s->picture_in_gop_number= s->coded_order[0].picture_in_gop_number; 813 s->picture_in_gop_number= s->coded_order[0].picture_in_gop_number;
777 s->picture_number= s->coded_order[0].picture_number; 814 s->picture_number= s->coded_order[0].picture_number;
778 815
779 MPV_frame_start(s); 816 MPV_frame_start(s, avctx);
780 817
781 encode_picture(s, s->picture_number); 818 encode_picture(s, s->picture_number);
782 avctx->key_frame = (s->pict_type == I_TYPE); 819 avctx->key_frame = (s->pict_type == I_TYPE);
783 avctx->pict_type = s->pict_type; 820 avctx->pict_type = s->pict_type;
784 avctx->real_pict_num = s->picture_number; 821 avctx->real_pict_num = s->picture_number;
877 gmc1(dest_cr + (dest_offset>>1), ptr, linesize>>1, h>>1, motion_x&15, motion_y&15, s->no_rounding); 914 gmc1(dest_cr + (dest_offset>>1), ptr, linesize>>1, h>>1, motion_x&15, motion_y&15, s->no_rounding);
878 915
879 return; 916 return;
880 } 917 }
881 918
919 static void emulated_edge_mc(UINT8 *buf, UINT8 *src, int linesize, int block_w, int block_h,
920 int src_x, int src_y, int w, int h){
921 int x, y;
922 int start_y, start_x, end_y, end_x;
923
924 if(src_y>= h){
925 src+= (h-1-src_y)*linesize;
926 src_y=h-1;
927 }
928 if(src_x>= w){
929 src+= (w-1-src_x);
930 src_x=w-1;
931 }
932
933 start_y= MAX(0, -src_y);
934 start_x= MAX(0, -src_x);
935 end_y= MIN(block_h, h-src_y);
936 end_x= MIN(block_w, w-src_x);
937
938 // copy existing part
939 for(y=start_y; y<end_y; y++){
940 for(x=start_x; x<end_x; x++){
941 buf[x + y*linesize]= src[x + y*linesize];
942 }
943 }
944
945 //top
946 for(y=0; y<start_y; y++){
947 for(x=start_x; x<end_x; x++){
948 buf[x + y*linesize]= buf[x + start_y*linesize];
949 }
950 }
951
952 //bottom
953 for(y=end_y; y<block_h; y++){
954 for(x=start_x; x<end_x; x++){
955 buf[x + y*linesize]= buf[x + (end_y-1)*linesize];
956 }
957 }
958
959 for(y=0; y<block_h; y++){
960 //left
961 for(x=0; x<start_x; x++){
962 buf[x + y*linesize]= buf[start_x + y*linesize];
963 }
964
965 //right
966 for(x=end_x; x<block_w; x++){
967 buf[x + y*linesize]= buf[end_x - 1 + y*linesize];
968 }
969 }
970 }
971
972
882 /* apply one mpeg motion vector to the three components */ 973 /* apply one mpeg motion vector to the three components */
883 static inline void mpeg_motion(MpegEncContext *s, 974 static inline void mpeg_motion(MpegEncContext *s,
884 UINT8 *dest_y, UINT8 *dest_cb, UINT8 *dest_cr, 975 UINT8 *dest_y, UINT8 *dest_cb, UINT8 *dest_cr,
885 int dest_offset, 976 int dest_offset,
886 UINT8 **ref_picture, int src_offset, 977 UINT8 **ref_picture, int src_offset,
887 int field_based, op_pixels_func *pix_op, 978 int field_based, op_pixels_func *pix_op,
888 int motion_x, int motion_y, int h) 979 int motion_x, int motion_y, int h)
889 { 980 {
890 UINT8 *ptr; 981 UINT8 *ptr;
891 int dxy, offset, mx, my, src_x, src_y, height, linesize; 982 int dxy, offset, mx, my, src_x, src_y, height, linesize;
983 int emu=0;
984
892 if(s->quarter_sample) 985 if(s->quarter_sample)
893 { 986 {
894 motion_x>>=1; 987 motion_x>>=1;
895 motion_y>>=1; 988 motion_y>>=1;
896 } 989 }
907 if (src_y == height) 1000 if (src_y == height)
908 dxy &= ~2; 1001 dxy &= ~2;
909 linesize = s->linesize << field_based; 1002 linesize = s->linesize << field_based;
910 ptr = ref_picture[0] + (src_y * linesize) + (src_x) + src_offset; 1003 ptr = ref_picture[0] + (src_y * linesize) + (src_x) + src_offset;
911 dest_y += dest_offset; 1004 dest_y += dest_offset;
1005
1006 if(s->flags&CODEC_FLAG_EMU_EDGE){
1007 if(src_x<0 || src_y<0 || src_x + (motion_x&1) + 16 > s->width
1008 || src_y + (motion_y&1) + h > height){
1009 emulated_edge_mc(s->edge_emu_buffer, ptr, linesize, 17, h+1, src_x, src_y, s->width, height);
1010 ptr= s->edge_emu_buffer;
1011 emu=1;
1012 }
1013 }
912 pix_op[dxy](dest_y, ptr, linesize, h); 1014 pix_op[dxy](dest_y, ptr, linesize, h);
913 pix_op[dxy](dest_y + 8, ptr + 8, linesize, h); 1015 pix_op[dxy](dest_y + 8, ptr + 8, linesize, h);
914 1016
915 if(s->flags&CODEC_FLAG_GRAY) return; 1017 if(s->flags&CODEC_FLAG_GRAY) return;
916 1018
939 if (src_y == (height >> 1)) 1041 if (src_y == (height >> 1))
940 dxy &= ~2; 1042 dxy &= ~2;
941 1043
942 offset = (src_y * (linesize >> 1)) + src_x + (src_offset >> 1); 1044 offset = (src_y * (linesize >> 1)) + src_x + (src_offset >> 1);
943 ptr = ref_picture[1] + offset; 1045 ptr = ref_picture[1] + offset;
1046 if(emu){
1047 emulated_edge_mc(s->edge_emu_buffer, ptr, linesize>>1, 9, (h>>1)+1, src_x, src_y, s->width>>1, height>>1);
1048 ptr= s->edge_emu_buffer;
1049 }
944 pix_op[dxy](dest_cb + (dest_offset >> 1), ptr, linesize >> 1, h >> 1); 1050 pix_op[dxy](dest_cb + (dest_offset >> 1), ptr, linesize >> 1, h >> 1);
1051
945 ptr = ref_picture[2] + offset; 1052 ptr = ref_picture[2] + offset;
1053 if(emu){
1054 emulated_edge_mc(s->edge_emu_buffer, ptr, linesize>>1, 9, (h>>1)+1, src_x, src_y, s->width>>1, height>>1);
1055 ptr= s->edge_emu_buffer;
1056 }
946 pix_op[dxy](dest_cr + (dest_offset >> 1), ptr, linesize >> 1, h >> 1); 1057 pix_op[dxy](dest_cr + (dest_offset >> 1), ptr, linesize >> 1, h >> 1);
947 } 1058 }
948 1059
949 static inline void qpel_motion(MpegEncContext *s, 1060 static inline void qpel_motion(MpegEncContext *s,
950 UINT8 *dest_y, UINT8 *dest_cb, UINT8 *dest_cr, 1061 UINT8 *dest_y, UINT8 *dest_cb, UINT8 *dest_cr,