mirror of
https://github.com/simon987/sist2.git
synced 2025-12-11 14:38:54 +00:00
Use WEBP to encode thumbnails
This commit is contained in:
19
third-party/libscan/libscan/ebook/ebook.c
vendored
19
third-party/libscan/libscan/ebook/ebook.c
vendored
@@ -153,22 +153,23 @@ int render_cover(scan_ebook_ctx_t *ctx, fz_context *fzctx, document_t *doc, fz_d
|
||||
|
||||
sws_freeContext(sws_ctx);
|
||||
|
||||
// YUV420p -> JPEG
|
||||
AVCodecContext *jpeg_encoder = alloc_jpeg_encoder(pixmap->w, pixmap->h, ctx->tn_qscale);
|
||||
avcodec_send_frame(jpeg_encoder, scaled_frame);
|
||||
// YUV420p -> JPEG/WEBP
|
||||
AVCodecContext *thumbnail_encoder = alloc_webp_encoder(pixmap->w, pixmap->h, ctx->tn_qscale);
|
||||
avcodec_send_frame(thumbnail_encoder, scaled_frame);
|
||||
avcodec_send_frame(thumbnail_encoder, NULL); // Send EOF
|
||||
|
||||
AVPacket jpeg_packet;
|
||||
av_init_packet(&jpeg_packet);
|
||||
avcodec_receive_packet(jpeg_encoder, &jpeg_packet);
|
||||
AVPacket thumbnail_packet;
|
||||
av_init_packet(&thumbnail_packet);
|
||||
avcodec_receive_packet(thumbnail_encoder, &thumbnail_packet);
|
||||
|
||||
APPEND_LONG_META(doc, MetaThumbnail, 1);
|
||||
ctx->store(doc->doc_id, 0, (char *) jpeg_packet.data, jpeg_packet.size);
|
||||
ctx->store(doc->doc_id, 0, (char *) thumbnail_packet.data, thumbnail_packet.size);
|
||||
|
||||
free(samples);
|
||||
av_packet_unref(&jpeg_packet);
|
||||
av_packet_unref(&thumbnail_packet);
|
||||
av_free(*scaled_frame->data);
|
||||
av_frame_free(&scaled_frame);
|
||||
avcodec_free_context(&jpeg_encoder);
|
||||
avcodec_free_context(&thumbnail_encoder);
|
||||
|
||||
fz_drop_pixmap(fzctx, pixmap);
|
||||
fz_drop_page(fzctx, cover);
|
||||
|
||||
31
third-party/libscan/libscan/media/media.c
vendored
31
third-party/libscan/libscan/media/media.c
vendored
@@ -68,7 +68,7 @@ void *scale_frame(const AVCodecContext *decoder, const AVFrame *frame, int size)
|
||||
|
||||
struct SwsContext *sws_ctx = sws_getContext(
|
||||
decoder->width, decoder->height, decoder->pix_fmt,
|
||||
dstW, dstH, AV_PIX_FMT_YUVJ420P,
|
||||
dstW, dstH, AV_PIX_FMT_YUV420P,
|
||||
SIST_SWS_ALGO, 0, 0, 0
|
||||
);
|
||||
|
||||
@@ -436,7 +436,8 @@ int decode_frame_and_save_thumbnail(scan_media_ctx_t *ctx, AVFormatContext *pFor
|
||||
}
|
||||
|
||||
if (seek_ok == FALSE && thumbnail_index != 0) {
|
||||
CTX_LOG_WARNING(doc->filepath, "(media.c) Could not seek media file. Can't generate additional thumbnails.");
|
||||
CTX_LOG_WARNING(doc->filepath,
|
||||
"(media.c) Could not seek media file. Can't generate additional thumbnails.");
|
||||
return SAVE_THUMBNAIL_FAILED;
|
||||
}
|
||||
}
|
||||
@@ -470,18 +471,19 @@ int decode_frame_and_save_thumbnail(scan_media_ctx_t *ctx, AVFormatContext *pFor
|
||||
|
||||
ctx->store(doc->doc_id, 0, frame_and_packet->packet->data, frame_and_packet->packet->size);
|
||||
} else {
|
||||
// Encode frame to jpeg
|
||||
AVCodecContext *jpeg_encoder = alloc_jpeg_encoder(scaled_frame->width, scaled_frame->height,
|
||||
ctx->tn_qscale);
|
||||
avcodec_send_frame(jpeg_encoder, scaled_frame);
|
||||
// Encode frame
|
||||
AVCodecContext *thumbnail_encoder = alloc_webp_encoder(scaled_frame->width, scaled_frame->height,
|
||||
ctx->tn_qscale);
|
||||
avcodec_send_frame(thumbnail_encoder, scaled_frame);
|
||||
avcodec_send_frame(thumbnail_encoder, NULL); // send EOF
|
||||
|
||||
AVPacket jpeg_packet;
|
||||
av_init_packet(&jpeg_packet);
|
||||
avcodec_receive_packet(jpeg_encoder, &jpeg_packet);
|
||||
AVPacket thumbnail_packet;
|
||||
av_init_packet(&thumbnail_packet);
|
||||
avcodec_receive_packet(thumbnail_encoder, &thumbnail_packet);
|
||||
|
||||
// Save thumbnail
|
||||
if (thumbnail_index == 0) {
|
||||
ctx->store(doc->doc_id, 0, jpeg_packet.data, jpeg_packet.size);
|
||||
ctx->store(doc->doc_id, 0, thumbnail_packet.data, thumbnail_packet.size);
|
||||
return_value = SAVE_THUMBNAIL_OK;
|
||||
|
||||
} else if (thumbnail_index > 1) {
|
||||
@@ -489,15 +491,15 @@ int decode_frame_and_save_thumbnail(scan_media_ctx_t *ctx, AVFormatContext *pFor
|
||||
// I figure out a better fix.
|
||||
thumbnail_index -= 1;
|
||||
|
||||
ctx->store(doc->doc_id, thumbnail_index, jpeg_packet.data, jpeg_packet.size);
|
||||
ctx->store(doc->doc_id, thumbnail_index, thumbnail_packet.data, thumbnail_packet.size);
|
||||
|
||||
return_value = SAVE_THUMBNAIL_OK;
|
||||
} else {
|
||||
return_value = SAVE_THUMBNAIL_SKIPPED;
|
||||
}
|
||||
|
||||
avcodec_free_context(&jpeg_encoder);
|
||||
av_packet_unref(&jpeg_packet);
|
||||
avcodec_free_context(&thumbnail_encoder);
|
||||
av_packet_unref(&thumbnail_packet);
|
||||
av_free(*scaled_frame->data);
|
||||
av_frame_free(&scaled_frame);
|
||||
}
|
||||
@@ -854,9 +856,10 @@ int store_image_thumbnail(scan_media_ctx_t *ctx, void *buf, size_t buf_len, docu
|
||||
ctx->store(doc->doc_id, 0, frame_and_packet->packet->data, frame_and_packet->packet->size);
|
||||
} else {
|
||||
// Encode frame to jpeg
|
||||
AVCodecContext *jpeg_encoder = alloc_jpeg_encoder(scaled_frame->width, scaled_frame->height,
|
||||
AVCodecContext *jpeg_encoder = alloc_webp_encoder(scaled_frame->width, scaled_frame->height,
|
||||
ctx->tn_qscale);
|
||||
avcodec_send_frame(jpeg_encoder, scaled_frame);
|
||||
avcodec_send_frame(jpeg_encoder, NULL); // Send EOF
|
||||
|
||||
AVPacket jpeg_packet;
|
||||
av_init_packet(&jpeg_packet);
|
||||
|
||||
22
third-party/libscan/libscan/media/media.h
vendored
22
third-party/libscan/libscan/media/media.h
vendored
@@ -48,6 +48,28 @@ static AVCodecContext *alloc_jpeg_encoder(int w, int h, int qscale) {
|
||||
return jpeg;
|
||||
}
|
||||
|
||||
static AVCodecContext *alloc_webp_encoder(int w, int h, int qscale) {
|
||||
|
||||
const AVCodec *webp_codec = avcodec_find_encoder(AV_CODEC_ID_WEBP);
|
||||
AVCodecContext *webp = avcodec_alloc_context3(webp_codec);
|
||||
webp->width = w;
|
||||
webp->height = h;
|
||||
webp->time_base.den = 1000000;
|
||||
webp->time_base.num = 1;
|
||||
webp->compression_level = 6;
|
||||
webp->global_quality = FF_QP2LAMBDA * qscale;
|
||||
|
||||
webp->pix_fmt = AV_PIX_FMT_YUV420P;
|
||||
webp->color_range = AVCOL_RANGE_JPEG;
|
||||
int ret = avcodec_open2(webp, webp_codec, NULL);
|
||||
|
||||
if (ret != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return webp;
|
||||
}
|
||||
|
||||
|
||||
void parse_media(scan_media_ctx_t *ctx, vfile_t *f, document_t *doc, const char *mime_str);
|
||||
|
||||
|
||||
19
third-party/libscan/libscan/raw/raw.c
vendored
19
third-party/libscan/libscan/raw/raw.c
vendored
@@ -52,7 +52,7 @@ int store_thumbnail_rgb24(scan_raw_ctx_t *ctx, libraw_processed_image_t *img, do
|
||||
|
||||
struct SwsContext *sws_ctx = sws_getContext(
|
||||
img->width, img->height, AV_PIX_FMT_RGB24,
|
||||
dstW, dstH, AV_PIX_FMT_YUVJ420P,
|
||||
dstW, dstH, AV_PIX_FMT_YUV420P,
|
||||
SIST_SWS_ALGO, 0, 0, 0
|
||||
);
|
||||
|
||||
@@ -76,20 +76,21 @@ int store_thumbnail_rgb24(scan_raw_ctx_t *ctx, libraw_processed_image_t *img, do
|
||||
|
||||
sws_freeContext(sws_ctx);
|
||||
|
||||
AVCodecContext *jpeg_encoder = alloc_jpeg_encoder(scaled_frame->width, scaled_frame->height, 1.0f);
|
||||
avcodec_send_frame(jpeg_encoder, scaled_frame);
|
||||
AVCodecContext *thumbnail_encoder = alloc_webp_encoder(scaled_frame->width, scaled_frame->height, ctx->tn_qscale);
|
||||
avcodec_send_frame(thumbnail_encoder, scaled_frame);
|
||||
avcodec_send_frame(thumbnail_encoder, NULL); // Send EOF
|
||||
|
||||
AVPacket jpeg_packet;
|
||||
av_init_packet(&jpeg_packet);
|
||||
avcodec_receive_packet(jpeg_encoder, &jpeg_packet);
|
||||
AVPacket thumbnail_packet;
|
||||
av_init_packet(&thumbnail_packet);
|
||||
avcodec_receive_packet(thumbnail_encoder, &thumbnail_packet);
|
||||
|
||||
APPEND_LONG_META(doc, MetaThumbnail, 1);
|
||||
ctx->store((char *) doc->doc_id, sizeof(doc->doc_id), (char *) jpeg_packet.data, jpeg_packet.size);
|
||||
ctx->store((char *) doc->doc_id, sizeof(doc->doc_id), (char *) thumbnail_packet.data, thumbnail_packet.size);
|
||||
|
||||
av_packet_unref(&jpeg_packet);
|
||||
av_packet_unref(&thumbnail_packet);
|
||||
av_free(*scaled_frame->data);
|
||||
av_frame_free(&scaled_frame);
|
||||
avcodec_free_context(&jpeg_encoder);
|
||||
avcodec_free_context(&thumbnail_encoder);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user