📄 lcl.c
字号:
outptr[pixel_ptr++] = get_g(encoded[2], encoded[5], encoded[7]); outptr[pixel_ptr++] = get_r(encoded[2], encoded[7]); outptr[pixel_ptr++] = get_b(encoded[3], encoded[5]); outptr[pixel_ptr++] = get_g(encoded[3], encoded[5], encoded[7]); outptr[pixel_ptr++] = get_r(encoded[3], encoded[7]); encoded += 8; } } break; case IMGTYPE_RGB24: for (row = height - 1; row >= 0; row--) { pixel_ptr = row * c->pic.linesize[0]; for (col = 0; col < width; col++) { outptr[pixel_ptr++] = encoded[0]; outptr[pixel_ptr++] = encoded[1]; outptr[pixel_ptr++] = encoded[2]; encoded += 3; } } break; case IMGTYPE_YUV411: for (row = height - 1; row >= 0; row--) { pixel_ptr = row * c->pic.linesize[0]; for (col = 0; col < width/4; col++) { outptr[pixel_ptr++] = get_b(encoded[0], encoded[4]); outptr[pixel_ptr++] = get_g(encoded[0], encoded[4], encoded[5]); outptr[pixel_ptr++] = get_r(encoded[0], encoded[5]); outptr[pixel_ptr++] = get_b(encoded[1], encoded[4]); outptr[pixel_ptr++] = get_g(encoded[1], encoded[4], encoded[5]); outptr[pixel_ptr++] = get_r(encoded[1], encoded[5]); outptr[pixel_ptr++] = get_b(encoded[2], encoded[4]); outptr[pixel_ptr++] = get_g(encoded[2], encoded[4], encoded[5]); outptr[pixel_ptr++] = get_r(encoded[2], encoded[5]); outptr[pixel_ptr++] = get_b(encoded[3], encoded[4]); outptr[pixel_ptr++] = get_g(encoded[3], encoded[4], encoded[5]); outptr[pixel_ptr++] = get_r(encoded[3], encoded[5]); encoded += 6; } } break; case IMGTYPE_YUV211: for (row = height - 1; row >= 0; row--) { pixel_ptr = row * c->pic.linesize[0]; for (col = 0; col < width/2; col++) { outptr[pixel_ptr++] = get_b(encoded[0], encoded[2]); outptr[pixel_ptr++] = get_g(encoded[0], encoded[2], encoded[3]); outptr[pixel_ptr++] = get_r(encoded[0], encoded[3]); outptr[pixel_ptr++] = get_b(encoded[1], encoded[2]); outptr[pixel_ptr++] = get_g(encoded[1], encoded[2], encoded[3]); outptr[pixel_ptr++] = get_r(encoded[1], encoded[3]); encoded += 4; } } break; case IMGTYPE_YUV420: for (row = height / 2 - 1; row >= 0; row--) { pixel_ptr = 2 * row * c->pic.linesize[0]; for (col = 0; col < width/2; col++) { outptr[pixel_ptr] = get_b(encoded[0], encoded[4]); outptr[pixel_ptr+1] = get_g(encoded[0], encoded[4], encoded[5]); outptr[pixel_ptr+2] = get_r(encoded[0], encoded[5]); outptr[pixel_ptr+3] = get_b(encoded[1], encoded[4]); outptr[pixel_ptr+4] = get_g(encoded[1], encoded[4], encoded[5]); outptr[pixel_ptr+5] = get_r(encoded[1], encoded[5]); outptr[pixel_ptr-c->pic.linesize[0]] = get_b(encoded[2], encoded[4]); outptr[pixel_ptr-c->pic.linesize[0]+1] = get_g(encoded[2], encoded[4], encoded[5]); outptr[pixel_ptr-c->pic.linesize[0]+2] = get_r(encoded[2], encoded[5]); outptr[pixel_ptr-c->pic.linesize[0]+3] = get_b(encoded[3], encoded[4]); outptr[pixel_ptr-c->pic.linesize[0]+4] = get_g(encoded[3], encoded[4], encoded[5]); outptr[pixel_ptr-c->pic.linesize[0]+5] = get_r(encoded[3], encoded[5]); pixel_ptr += 6; encoded += 6; } } break; default: av_log(avctx, AV_LOG_ERROR, "BUG! Unknown imagetype in image decoder.\n"); return -1; } *data_size = sizeof(AVFrame); *(AVFrame*)data = c->pic; /* always report that the buffer was completely consumed */ return buf_size;}/* * * Encode a frame * */static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ LclContext *c = avctx->priv_data; AVFrame *pict = data; AVFrame * const p = &c->pic; int i; int zret; // Zlib return code#ifndef CONFIG_ZLIB av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled in.\n"); return -1;#else init_put_bits(&c->pb, buf, buf_size); *p = *pict; p->pict_type= FF_I_TYPE; p->key_frame= 1; if(avctx->pix_fmt != PIX_FMT_BGR24){ av_log(avctx, AV_LOG_ERROR, "Format not supported!\n"); return -1; } zret = deflateReset(&(c->zstream)); if (zret != Z_OK) { av_log(avctx, AV_LOG_ERROR, "Deflate reset error: %d\n", zret); return -1; } c->zstream.next_in = p->data[0]; c->zstream.avail_in = c->decomp_size; c->zstream.next_out = c->comp_buf; c->zstream.avail_out = c->max_comp_size; zret = deflate(&(c->zstream), Z_FINISH); if ((zret != Z_OK) && (zret != Z_STREAM_END)) { av_log(avctx, AV_LOG_ERROR, "Deflate error: %d\n", zret); return -1; } for (i = 0; i < c->zstream.total_out; i++) put_bits(&c->pb, 8, c->comp_buf[i]); flush_put_bits(&c->pb); return c->zstream.total_out;#endif}/* * * Init lcl decoder * */static int decode_init(AVCodecContext *avctx){ LclContext * const c = (LclContext *)avctx->priv_data; int basesize = avctx->width * avctx->height; int zret; // Zlib return code c->avctx = avctx; avctx->has_b_frames = 0; c->pic.data[0] = NULL;#ifdef CONFIG_ZLIB // Needed if zlib unused or init aborted before inflateInit memset(&(c->zstream), 0, sizeof(z_stream)); #endif if (avctx->extradata_size < 8) { av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n"); return 1; } /* Check codec type */ if (((avctx->codec_id == CODEC_ID_MSZH) && (*((char *)avctx->extradata + 7) != CODEC_MSZH)) || ((avctx->codec_id == CODEC_ID_ZLIB) && (*((char *)avctx->extradata + 7) != CODEC_ZLIB))) { av_log(avctx, AV_LOG_ERROR, "Codec id and codec type mismatch. This should not happen.\n"); } /* Detect image type */ switch (c->imgtype = *((char *)avctx->extradata + 4)) { case IMGTYPE_YUV111: c->decomp_size = basesize * 3; av_log(avctx, AV_LOG_INFO, "Image type is YUV 1:1:1.\n"); break; case IMGTYPE_YUV422: c->decomp_size = basesize * 2; av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:2.\n"); break; case IMGTYPE_RGB24: c->decomp_size = basesize * 3; av_log(avctx, AV_LOG_INFO, "Image type is RGB 24.\n"); break; case IMGTYPE_YUV411: c->decomp_size = basesize / 2 * 3; av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:1:1.\n"); break; case IMGTYPE_YUV211: c->decomp_size = basesize * 2; av_log(avctx, AV_LOG_INFO, "Image type is YUV 2:1:1.\n"); break; case IMGTYPE_YUV420: c->decomp_size = basesize / 2 * 3; av_log(avctx, AV_LOG_INFO, "Image type is YUV 4:2:0.\n"); break; default: av_log(avctx, AV_LOG_ERROR, "Unsupported image format %d.\n", c->imgtype); return 1; } /* Detect compression method */ c->compression = *((char *)avctx->extradata + 5); switch (avctx->codec_id) { case CODEC_ID_MSZH: switch (c->compression) { case COMP_MSZH: av_log(avctx, AV_LOG_INFO, "Compression enabled.\n"); break; case COMP_MSZH_NOCOMP: c->decomp_size = 0; av_log(avctx, AV_LOG_INFO, "No compression.\n"); break; default: av_log(avctx, AV_LOG_ERROR, "Unsupported compression format for MSZH (%d).\n", c->compression); return 1; } break; case CODEC_ID_ZLIB:#ifdef CONFIG_ZLIB switch (c->compression) { case COMP_ZLIB_HISPEED: av_log(avctx, AV_LOG_INFO, "High speed compression.\n"); break; case COMP_ZLIB_HICOMP: av_log(avctx, AV_LOG_INFO, "High compression.\n"); break; case COMP_ZLIB_NORMAL: av_log(avctx, AV_LOG_INFO, "Normal compression.\n"); break; default: if ((c->compression < Z_NO_COMPRESSION) || (c->compression > Z_BEST_COMPRESSION)) { av_log(avctx, AV_LOG_ERROR, "Unusupported compression level for ZLIB: (%d).\n", c->compression); return 1; } av_log(avctx, AV_LOG_INFO, "Compression level for ZLIB: (%d).\n", c->compression); }#else av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n"); return 1;#endif break; default: av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in compression switch.\n"); return 1; } /* Allocate decompression buffer */ /* 4*8 max overflow space for mszh decomp algorithm */ if (c->decomp_size) { if ((c->decomp_buf = av_malloc(c->decomp_size+4*8)) == NULL) { av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); return 1; } } /* Detect flags */ c->flags = *((char *)avctx->extradata + 6); if (c->flags & FLAG_MULTITHREAD) av_log(avctx, AV_LOG_INFO, "Multithread encoder flag set.\n"); if (c->flags & FLAG_NULLFRAME) av_log(avctx, AV_LOG_INFO, "Nullframe insertion flag set.\n"); if ((avctx->codec_id == CODEC_ID_ZLIB) && (c->flags & FLAG_PNGFILTER)) av_log(avctx, AV_LOG_INFO, "PNG filter flag set.\n"); if (c->flags & FLAGMASK_UNUSED) av_log(avctx, AV_LOG_ERROR, "Unknown flag set (%d).\n", c->flags); /* If needed init zlib */ if (avctx->codec_id == CODEC_ID_ZLIB) {#ifdef CONFIG_ZLIB c->zstream.zalloc = Z_NULL; c->zstream.zfree = Z_NULL; c->zstream.opaque = Z_NULL; zret = inflateInit(&(c->zstream)); if (zret != Z_OK) { av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret); return 1; }#else av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n"); return 1;#endif } avctx->pix_fmt = PIX_FMT_BGR24; return 0;}/* * * Init lcl encoder * */static int encode_init(AVCodecContext *avctx){ LclContext *c = avctx->priv_data; int zret; // Zlib return code#ifndef CONFIG_ZLIB av_log(avctx, AV_LOG_ERROR, "Zlib support not compiled.\n"); return 1;#else c->avctx= avctx; assert(avctx->width && avctx->height); avctx->extradata= av_mallocz(8); avctx->coded_frame= &c->pic; // Will be user settable someday c->compression = 6; c->flags = 0; switch(avctx->pix_fmt){ case PIX_FMT_BGR24: c->imgtype = IMGTYPE_RGB24; c->decomp_size = avctx->width * avctx->height * 3; avctx->bits_per_sample= 24; break; default: av_log(avctx, AV_LOG_ERROR, "Format %d not supported\n", avctx->pix_fmt); return -1; } ((uint8_t*)avctx->extradata)[0]= 4; ((uint8_t*)avctx->extradata)[1]= 0; ((uint8_t*)avctx->extradata)[2]= 0; ((uint8_t*)avctx->extradata)[3]= 0; ((uint8_t*)avctx->extradata)[4]= c->imgtype; ((uint8_t*)avctx->extradata)[5]= c->compression; ((uint8_t*)avctx->extradata)[6]= c->flags; ((uint8_t*)avctx->extradata)[7]= 0; c->avctx->extradata_size= 8; c->zstream.zalloc = Z_NULL; c->zstream.zfree = Z_NULL; c->zstream.opaque = Z_NULL; zret = deflateInit(&(c->zstream), c->compression); if (zret != Z_OK) { av_log(avctx, AV_LOG_ERROR, "Deflate init error: %d\n", zret); return 1; } /* Conservative upper bound taken from zlib v1.2.1 source */ c->max_comp_size = c->decomp_size + ((c->decomp_size + 7) >> 3) + ((c->decomp_size + 63) >> 6) + 11; if ((c->comp_buf = av_malloc(c->max_comp_size)) == NULL) { av_log(avctx, AV_LOG_ERROR, "Can't allocate compression buffer.\n"); return 1; } return 0;#endif}/* * * Uninit lcl decoder * */static int decode_end(AVCodecContext *avctx){ LclContext * const c = (LclContext *)avctx->priv_data; if (c->pic.data[0]) avctx->release_buffer(avctx, &c->pic);#ifdef CONFIG_ZLIB inflateEnd(&(c->zstream));#endif return 0;}/* * * Uninit lcl encoder * */static int encode_end(AVCodecContext *avctx){ LclContext *c = avctx->priv_data; av_freep(&avctx->extradata); av_freep(c->comp_buf);#ifdef CONFIG_ZLIB deflateEnd(&(c->zstream));#endif return 0;}AVCodec mszh_decoder = { "mszh", CODEC_TYPE_VIDEO, CODEC_ID_MSZH, sizeof(LclContext), decode_init, NULL, decode_end, decode_frame, CODEC_CAP_DR1,};AVCodec zlib_decoder = { "zlib", CODEC_TYPE_VIDEO, CODEC_ID_ZLIB, sizeof(LclContext), decode_init, NULL, decode_end, decode_frame, CODEC_CAP_DR1,};#ifdef CONFIG_ENCODERSAVCodec zlib_encoder = { "zlib", CODEC_TYPE_VIDEO, CODEC_ID_ZLIB, sizeof(LclContext), encode_init, encode_frame, encode_end,// .options = lcl_options,};#endif //CONFIG_ENCODERS
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -