Mercurial > libavcodec.hg
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, |