Libav
|
00001 /* 00002 * LCL (LossLess Codec Library) Codec 00003 * Copyright (c) 2002-2004 Roberto Togni 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * FFmpeg is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 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 * Decoder context 00051 */ 00052 typedef struct LclEncContext { 00053 00054 AVCodecContext *avctx; 00055 AVFrame pic; 00056 00057 // Image type 00058 int imgtype; 00059 // Compression type 00060 int compression; 00061 // Flags 00062 int flags; 00063 z_stream zstream; 00064 } LclEncContext; 00065 00066 /* 00067 * 00068 * Encode a frame 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; // Zlib return code 00077 00078 *p = *pict; 00079 p->pict_type= FF_I_TYPE; 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 * Init lcl encoder 00116 * 00117 */ 00118 static av_cold int encode_init(AVCodecContext *avctx) 00119 { 00120 LclEncContext *c = avctx->priv_data; 00121 int zret; // Zlib return code 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 // Will be user settable someday 00131 c->compression = 6; 00132 c->flags = 0; 00133 00134 switch(avctx->pix_fmt){ 00135 case PIX_FMT_BGR24: 00136 c->imgtype = IMGTYPE_RGB24; 00137 avctx->bits_per_coded_sample= 24; 00138 break; 00139 default: 00140 av_log(avctx, AV_LOG_ERROR, "Input pixel format %s not supported\n", avcodec_get_pix_fmt_name(avctx->pix_fmt)); 00141 return -1; 00142 } 00143 00144 avctx->extradata[0]= 4; 00145 avctx->extradata[1]= 0; 00146 avctx->extradata[2]= 0; 00147 avctx->extradata[3]= 0; 00148 avctx->extradata[4]= c->imgtype; 00149 avctx->extradata[5]= c->compression; 00150 avctx->extradata[6]= c->flags; 00151 avctx->extradata[7]= CODEC_ZLIB; 00152 c->avctx->extradata_size= 8; 00153 00154 c->zstream.zalloc = Z_NULL; 00155 c->zstream.zfree = Z_NULL; 00156 c->zstream.opaque = Z_NULL; 00157 zret = deflateInit(&c->zstream, c->compression); 00158 if (zret != Z_OK) { 00159 av_log(avctx, AV_LOG_ERROR, "Deflate init error: %d\n", zret); 00160 return 1; 00161 } 00162 00163 return 0; 00164 } 00165 00166 /* 00167 * 00168 * Uninit lcl encoder 00169 * 00170 */ 00171 static av_cold int encode_end(AVCodecContext *avctx) 00172 { 00173 LclEncContext *c = avctx->priv_data; 00174 00175 av_freep(&avctx->extradata); 00176 deflateEnd(&c->zstream); 00177 00178 return 0; 00179 } 00180 00181 AVCodec zlib_encoder = { 00182 "zlib", 00183 AVMEDIA_TYPE_VIDEO, 00184 CODEC_ID_ZLIB, 00185 sizeof(LclEncContext), 00186 encode_init, 00187 encode_frame, 00188 encode_end, 00189 .long_name = NULL_IF_CONFIG_SMALL("LCL (LossLess Codec Library) ZLIB"), 00190 };