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