static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ struct rtframeheader* ench = (struct rtframeheader*)vf->priv->buffer; uint8_t* data = vf->priv->buffer + FRAMEHEADERSIZE; uint8_t* zdata = vf->priv->zbuffer + FRAMEHEADERSIZE; int len = 0, zlen = 0,r; memset(vf->priv->buffer,0,FRAMEHEADERSIZE); // Reset the header if(vf->priv->lzo) memset(vf->priv->zbuffer,0,FRAMEHEADERSIZE); // This has to be don here otherwise tv with sound doesn't work if(!vf->priv->tbl_wrote) { RTjpeg_init_compress((long int*)data,mpi->width,mpi->height,vf->priv->q); RTjpeg_init_mcompress(); ench->frametype = 'D'; // compressor data ench->comptype = 'R'; // compressor data for RTjpeg ench->packetlength = 128*sizeof(long int); le2me_rtframeheader(ench); mux_v->buffer=vf->priv->buffer; muxer_write_chunk(mux_v,FRAMEHEADERSIZE + 128*sizeof(long int), 0x10, MP_NOPTS_VALUE, MP_NOPTS_VALUE); vf->priv->tbl_wrote = 1; memset(ench,0,FRAMEHEADERSIZE); // Reset the header } // Raw picture if(vf->priv->raw) { len = mpi->width*mpi->height*3/2; // Try lzo ??? if(vf->priv->lzo) { r = lzo1x_1_compress(mpi->planes[0],mpi->width*mpi->height*3/2, zdata,&zlen,vf->priv->zmem); if(r != LZO_E_OK) { mp_msg(MSGT_VFILTER,MSGL_ERR,"LZO compress error\n"); zlen = 0; } } if(zlen <= 0 || zlen > len) { memcpy(data,mpi->planes[0],len); ench->comptype = '0'; } else { // Use lzo only if it's littler ench = (struct rtframeheader*)vf->priv->zbuffer; ench->comptype = '3'; len = zlen; } } else { // RTjpeg compression len = RTjpeg_mcompressYUV420(data,mpi->planes[0],vf->priv->l, vf->priv->c); if(len <= 0) { mp_msg(MSGT_VFILTER,MSGL_ERR,"RTjpeg_mcompressYUV420 error (%d)\n",len); return 0; } if(vf->priv->lzo) { r = lzo1x_1_compress(data,len,zdata,&zlen,vf->priv->zmem); if(r != LZO_E_OK) { mp_msg(MSGT_VFILTER,MSGL_ERR,"LZO compress error\n"); zlen = 0; } } if(zlen <= 0 || zlen > len) ench->comptype = '1'; else { ench = (struct rtframeheader*)vf->priv->zbuffer; ench->comptype = '2'; len = zlen; } } ench->frametype = 'V'; // video frame ench->packetlength = len; le2me_rtframeheader(ench); mux_v->buffer=(void*)ench; muxer_write_chunk(mux_v, len + FRAMEHEADERSIZE, 0x10, pts, pts); return 1; }
NuppelWriter::NuppelWriter(int width, int height, outputCallback_t outputCallback, void *callbackExtra, float frameRate, float rtjQuality, bool rtjpeg, bool lzo, bool rgb, int keyframeFreq) { rtfileheader nuvh; rtframeheader frameh; static unsigned long int tbls[128]; int Q; this->outputCallback = outputCallback; this->callbackExtra = callbackExtra; this->width = width; this->height = height; this->frameRate = frameRate; this->keyframeFreq = keyframeFreq; this->lzo = lzo; this->rgb = rgb; this->rtjpeg = rtjpeg; frameofgop = 0; frameNumber = 0; /* Initialize a nuppelvideo header */ memset(&nuvh, 0, sizeof(nuvh)); strcpy(nuvh.finfo,"NuppelVideo"); strcpy(nuvh.version,"0.05"); nuvh.width = width; nuvh.height = height; nuvh.pimode = 'P'; nuvh.aspect = 1.0; nuvh.fps = frameRate; nuvh.videoblocks = -1; /* unknown */ bufferSize = width * height * 3; /* Allocate several temporary buffers */ compressBuffer = new unsigned char [width*height+(width*height)/2]; yuvBuffer = new unsigned char [width*height+(width*height)/2]; memset (yuvBuffer, 0, width*height+(width*height)/2); rgbBuffer = 0;//new uint8 [width * height * 3]; lzoTmp = new unsigned char [LZO1X_MEM_COMPRESS]; InitLookupTable(); /* Write the header */ outputCallback(&nuvh, sizeof(nuvh), callbackExtra); /* According to the RTJpeg docs, 255 is the full scale for Q, * being equivalent to a JPEG with 70% quality. */ Q = (int) (rtjQuality*255); /* Initialize the compression tables */ RTjpeg_init_compress(tbls,width,height, Q); RTjpeg_init_mcompress(); /* Write the compression configuration frame */ memset(&frameh, 0, sizeof(frameh)); frameh.frametype = 'D'; frameh.comptype = 'R'; frameh.packetlength = sizeof(tbls); outputCallback(&frameh, sizeof(frameh), callbackExtra); outputCallback(&tbls, sizeof(tbls), callbackExtra); }
static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ uint8_t *header = vf->priv->buffer; uint8_t* data = vf->priv->buffer + FRAMEHEADERSIZE; uint8_t* zdata = vf->priv->zbuffer + FRAMEHEADERSIZE; int len = 0, r; size_t zlen = 0; memset(header, 0, FRAMEHEADERSIZE); // Reset the header if(vf->priv->lzo) memset(vf->priv->zbuffer,0,FRAMEHEADERSIZE); // This has to be don here otherwise tv with sound doesn't work if(!vf->priv->tbl_wrote) { RTjpeg_init_compress((uint32_t *)data,mpi->width,mpi->height,vf->priv->q); RTjpeg_init_mcompress(); header[0] = 'D'; // frametype: compressor data header[1] = 'R'; // comptype: compressor data for RTjpeg AV_WL32(header + 8, COMPDATASIZE); // packetlength mux_v->buffer=vf->priv->buffer; muxer_write_chunk(mux_v,FRAMEHEADERSIZE + COMPDATASIZE, 0x10, MP_NOPTS_VALUE, MP_NOPTS_VALUE); vf->priv->tbl_wrote = 1; memset(header, 0, FRAMEHEADERSIZE); // Reset the header } // Raw picture if(vf->priv->raw) { len = mpi->width*mpi->height*3/2; // Try lzo ??? if(vf->priv->lzo) { r = lzo1x_1_compress(mpi->planes[0],len, zdata,&zlen,vf->priv->zmem); if(r != LZO_E_OK) { mp_msg(MSGT_VFILTER,MSGL_ERR,"LZO compress error\n"); zlen = 0; } } if(zlen <= 0 || zlen > len) { memcpy(data,mpi->planes[0],len); header[1] = '0'; // comptype: uncompressed } else { // Use lzo only if it's littler header = vf->priv->zbuffer; header[1] = '3'; //comptype: lzo len = zlen; } } else { // RTjpeg compression len = RTjpeg_mcompressYUV420(data,mpi->planes[0],vf->priv->l, vf->priv->c); if(len <= 0) { mp_msg(MSGT_VFILTER,MSGL_ERR,"RTjpeg_mcompressYUV420 error (%d)\n",len); return 0; } if(vf->priv->lzo) { r = lzo1x_1_compress(data,len,zdata,&zlen,vf->priv->zmem); if(r != LZO_E_OK) { mp_msg(MSGT_VFILTER,MSGL_ERR,"LZO compress error\n"); zlen = 0; } } if(zlen <= 0 || zlen > len) header[1] = '1'; // comptype: RTjpeg else { header = vf->priv->zbuffer; header[1] = '2'; // comptype: RTjpeg + LZO len = zlen; } } header[0] = 'V'; // frametype: video frame AV_WL32(header + 8, len); // packetlength mux_v->buffer = header; muxer_write_chunk(mux_v, len + FRAMEHEADERSIZE, 0x10, pts, pts); return 1; }