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