00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00041 #include <stdio.h>
00042 #include <stdlib.h>
00043
00044 #include "avcodec.h"
00045 #include "lcl.h"
00046
00047 #include <zlib.h>
00048
00049
00050
00051
00052 typedef struct LclEncContext {
00053
00054 AVCodecContext *avctx;
00055 AVFrame pic;
00056
00057
00058 int imgtype;
00059
00060 int compression;
00061
00062 int flags;
00063 z_stream zstream;
00064 } LclEncContext;
00065
00066
00067
00068
00069
00070
00071 static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){
00072 LclEncContext *c = avctx->priv_data;
00073 AVFrame *pict = data;
00074 AVFrame * const p = &c->pic;
00075 int i;
00076 int zret;
00077
00078 *p = *pict;
00079 p->pict_type= AV_PICTURE_TYPE_I;
00080 p->key_frame= 1;
00081
00082 if(avctx->pix_fmt != PIX_FMT_BGR24){
00083 av_log(avctx, AV_LOG_ERROR, "Format not supported!\n");
00084 return -1;
00085 }
00086
00087 zret = deflateReset(&c->zstream);
00088 if (zret != Z_OK) {
00089 av_log(avctx, AV_LOG_ERROR, "Deflate reset error: %d\n", zret);
00090 return -1;
00091 }
00092 c->zstream.next_out = buf;
00093 c->zstream.avail_out = buf_size;
00094
00095 for(i = avctx->height - 1; i >= 0; i--) {
00096 c->zstream.next_in = p->data[0]+p->linesize[0]*i;
00097 c->zstream.avail_in = avctx->width*3;
00098 zret = deflate(&c->zstream, Z_NO_FLUSH);
00099 if (zret != Z_OK) {
00100 av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret);
00101 return -1;
00102 }
00103 }
00104 zret = deflate(&c->zstream, Z_FINISH);
00105 if (zret != Z_STREAM_END) {
00106 av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret);
00107 return -1;
00108 }
00109
00110 return c->zstream.total_out;
00111 }
00112
00113
00114
00115
00116
00117
00118 static av_cold int encode_init(AVCodecContext *avctx)
00119 {
00120 LclEncContext *c = avctx->priv_data;
00121 int zret;
00122
00123 c->avctx= avctx;
00124
00125 assert(avctx->width && avctx->height);
00126
00127 avctx->extradata= av_mallocz(8);
00128 avctx->coded_frame= &c->pic;
00129
00130
00131 c->compression = 6;
00132 c->flags = 0;
00133 c->imgtype = IMGTYPE_RGB24;
00134 avctx->bits_per_coded_sample= 24;
00135
00136 avctx->extradata[0]= 4;
00137 avctx->extradata[1]= 0;
00138 avctx->extradata[2]= 0;
00139 avctx->extradata[3]= 0;
00140 avctx->extradata[4]= c->imgtype;
00141 avctx->extradata[5]= c->compression;
00142 avctx->extradata[6]= c->flags;
00143 avctx->extradata[7]= CODEC_ZLIB;
00144 c->avctx->extradata_size= 8;
00145
00146 c->zstream.zalloc = Z_NULL;
00147 c->zstream.zfree = Z_NULL;
00148 c->zstream.opaque = Z_NULL;
00149 zret = deflateInit(&c->zstream, c->compression);
00150 if (zret != Z_OK) {
00151 av_log(avctx, AV_LOG_ERROR, "Deflate init error: %d\n", zret);
00152 return 1;
00153 }
00154
00155 return 0;
00156 }
00157
00158
00159
00160
00161
00162
00163 static av_cold int encode_end(AVCodecContext *avctx)
00164 {
00165 LclEncContext *c = avctx->priv_data;
00166
00167 av_freep(&avctx->extradata);
00168 deflateEnd(&c->zstream);
00169
00170 return 0;
00171 }
00172
00173 AVCodec ff_zlib_encoder = {
00174 .name = "zlib",
00175 .type = AVMEDIA_TYPE_VIDEO,
00176 .id = CODEC_ID_ZLIB,
00177 .priv_data_size = sizeof(LclEncContext),
00178 .init = encode_init,
00179 .encode = encode_frame,
00180 .close = encode_end,
00181 .pix_fmts = (const enum PixelFormat[]) { PIX_FMT_BGR24, PIX_FMT_NONE },
00182 .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"),
00183 };