public void release_buffer(AVFrame pic) { int i; InternalBuffer buf, last; ////assert(pic->type==FF_BUFFER_TYPE_INTERNAL); ////assert(s->internal_buffer_count); buf = null; /* avoids warning */ for (i = 0; i < this.internal_buffer_count; i++) { //just 3-5 checks so is not worth to optimize buf = this.internal_buffer[i]; if (buf.@base[0] == pic.data_base[0] && buf.data_offset[0] == pic.data_offset[0]) break; } ////assert(i < s->internal_buffer_count); this.internal_buffer_count--; last = this.internal_buffer[this.internal_buffer_count]; //FFSWAP(InternalBuffer, *buf, *last); InternalBuffer tmp = new InternalBuffer(); buf.copyInto(tmp); last.copyInto(buf); tmp.copyInto(last); for (i = 0; i < 4; i++) { pic.data_base[i] = null; pic.data_offset[i] = 0; // pic->base[i]=NULL; } //printf("R%X\n", pic->opaque); //if(s->debug&FF_DEBUG_BUFFERS) // av_log(s, AV_LOG_DEBUG, "default_release_buffer called on pic %p, %d buffers used\n", pic, s->internal_buffer_count); }
public int get_buffer(AVFrame pic) { int i; int w = this.width; int h = this.height; InternalBuffer buf; //int[] picture_number; if (pic.data_base[0] != null) { // DebugTool.printDebugString(" ----- get_buffer error case 0\n"); //av_log(s, AV_LOG_ERROR, "pic.data[0]!=NULL in avcodec_default_get_buffer\n"); return -1; } if (this.internal_buffer_count >= INTERNAL_BUFFER_SIZE) { //av_log(s, AV_LOG_ERROR, "internal_buffer_count overflow (missing release_buffer?)\n"); // DebugTool.printDebugString(" ----- get_buffer error case 1\n"); return -1; } if (av_image_check_size(w, h, 0, this) != 0) { // DebugTool.printDebugString(" ----- get_buffer error case 2\n"); return -1; } if (this.internal_buffer == null) { //this.internal_buffer= av_mallocz((INTERNAL_BUFFER_SIZE+1)*sizeof(InternalBuffer)); internal_buffer = new InternalBuffer[INTERNAL_BUFFER_SIZE + 1]; for (i = 0; i < INTERNAL_BUFFER_SIZE + 1; i++) internal_buffer[i] = new InternalBuffer(); } buf = internal_buffer[this.internal_buffer_count]; //picture_number= &(((InternalBuffer*)this.internal_buffer)[INTERNAL_BUFFER_SIZE]).last_pic_num; //FIXME ugly hack //(*picture_number)++; this.internal_buffer[INTERNAL_BUFFER_SIZE].last_pic_num++; if (buf.@base[0] != null && (buf.width != w || buf.height != h || buf.pix_fmt != this.pix_fmt)) { for (i = 0; i < 4; i++) { //av_freep(&buf.base[i]); buf.@base[i] = null; buf.data_offset[i] = 0; } } if (buf.@base[0] != null) { pic.age = this.internal_buffer[INTERNAL_BUFFER_SIZE].last_pic_num - buf.last_pic_num; buf.last_pic_num = this.internal_buffer[INTERNAL_BUFFER_SIZE].last_pic_num; } else { int h_chroma_shift, v_chroma_shift; int[] size = new int[4]; int tmpsize; int unaligned; AVPicture picture = new AVPicture(); int[] stride_align = new int[4]; //avcodec_get_chroma_sub_sample(this.pix_fmt, &h_chroma_shift, &v_chroma_shift); h_chroma_shift = ImageUtils.av_pix_fmt_descriptors[pix_fmt].log2_chroma_w; v_chroma_shift = ImageUtils.av_pix_fmt_descriptors[pix_fmt].log2_chroma_h; int[] param = new int[] { w, h }; avcodec_align_dimensions2(param, stride_align); w = param[0]; h = param[1]; pic.imageWidthWOEdge = w; pic.imageHeightWOEdge = h; if (0 == (this.flags & CODEC_FLAG_EMU_EDGE)) { w += EDGE_WIDTH * 2; h += EDGE_WIDTH * 2; } pic.imageWidth = w; pic.imageHeight = h; do { // NOTE: do not align linesizes individually, this breaks e.g. assumptions // that linesize[0] == 2*linesize[1] in the MPEG-encoder for 4:2:2 av_image_fill_linesizes(picture.linesize, this.pix_fmt, w); // increase alignment of w for next try (rhs gives the lowest bit set in w) w += w & ~(w - 1); unaligned = 0; for (i = 0; i < 4; i++) { unaligned |= (picture.linesize[i] % stride_align[i]); } } while (unaligned != 0); tmpsize = av_image_fill_pointers(picture.data_base, picture.data_offset, this.pix_fmt, h, null, picture.linesize); if (tmpsize < 0) { // DebugTool.printDebugString(" ----- get_buffer error case 3\n"); return -1; } for (i = 0; i < 3 && picture.data_offset[i + 1] != 0; i++) size[i] = picture.data_offset[i + 1] - picture.data_offset[i]; size[i] = tmpsize - (picture.data_offset[i] - picture.data_offset[0]); buf.last_pic_num = -256 * 256 * 256 * 64; //memset(buf.base, 0, sizeof(buf.base)); //memset(buf.data, 0, sizeof(buf.data)); for (int k = 0; k < [email protected]; k++) buf.@base[k] = null; //Arrays.fill(buf.base[k], 0); for (int k = 0; k < buf.data_offset.Length; k++) buf.data_offset[k] = 0; // Arrays.fill(buf.data[k], 0); for (i = 0; i < 4 && size[i] != 0; i++) { int h_shift = i == 0 ? 0 : h_chroma_shift; int v_shift = i == 0 ? 0 : v_chroma_shift; buf.linesize[i] = picture.linesize[i]; //buf.base[i]= av_malloc(size[i]+16); //FIXME 16 buf.@base[i] = new byte[size[i] + 16]; if (buf.@base[i] == null) return -1; //memset(buf.base[i], 128, size[i]); Arrays.Fill(buf.@base[i], 0, size[i], (byte)128); // no edge if EDGE EMU or not planar YUV if ((this.flags & CODEC_FLAG_EMU_EDGE) != 0 || 0 == size[2]) buf.data_offset[i] = 0; else buf.data_offset[i] = ((((buf.linesize[i] * EDGE_WIDTH >> v_shift) + (EDGE_WIDTH >> h_shift)) + (stride_align[i]) - 1) & ~((stride_align[i]) - 1)); //+ FFALIGN((buf.linesize[i]*EDGE_WIDTH>>v_shift) + (EDGE_WIDTH>>h_shift), stride_align[i]); } if (size[1] != 0 && 0 == size[2]) ff_set_systematic_pal2(buf.@base[1], buf.data_offset[1], this.pix_fmt); buf.width = this.width; buf.height = this.height; buf.pix_fmt = this.pix_fmt; pic.age = 256 * 256 * 256 * 64; } pic.type = FF_BUFFER_TYPE_INTERNAL; for (i = 0; i < 4; i++) { pic.@base[i] = buf.@base[i]; pic.data_base[i] = buf.@base[i]; pic.data_offset[i] = buf.data_offset[i]; pic.linesize[i] = buf.linesize[i]; } this.internal_buffer_count++; // DebugTool.printDebugString("****Internal_Buffer_Count = "+this.internal_buffer_count); if (this.pkt != null) pic.pkt_pts = this.pkt.pts; else pic.pkt_pts = Constants.AV_NOPTS_VALUE; pic.reordered_opaque = this.reordered_opaque; /* if(this.debug&FF_DEBUG_BUFFERS) av_log(s, AV_LOG_DEBUG, "default_get_buffer called on pic %p, %d buffers used\n", pic, this.internal_buffer_count); */ // DebugTool.printDebugString(" ----- get_buffer OK.\n"); return 0; }