1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * lossless JPEG encoder 3cabdff1aSopenharmony_ci * Copyright (c) 2000, 2001 Fabrice Bellard 4cabdff1aSopenharmony_ci * Copyright (c) 2003 Alex Beregszaszi 5cabdff1aSopenharmony_ci * Copyright (c) 2003-2004 Michael Niedermayer 6cabdff1aSopenharmony_ci * 7cabdff1aSopenharmony_ci * Support for external huffman table, various fixes (AVID workaround), 8cabdff1aSopenharmony_ci * aspecting, new decode_frame mechanism and apple mjpeg-b support 9cabdff1aSopenharmony_ci * by Alex Beregszaszi 10cabdff1aSopenharmony_ci * 11cabdff1aSopenharmony_ci * This file is part of FFmpeg. 12cabdff1aSopenharmony_ci * 13cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 14cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 15cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 16cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 17cabdff1aSopenharmony_ci * 18cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 19cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 20cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21cabdff1aSopenharmony_ci * Lesser General Public License for more details. 22cabdff1aSopenharmony_ci * 23cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 24cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 25cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 26cabdff1aSopenharmony_ci */ 27cabdff1aSopenharmony_ci 28cabdff1aSopenharmony_ci/** 29cabdff1aSopenharmony_ci * @file 30cabdff1aSopenharmony_ci * lossless JPEG encoder. 31cabdff1aSopenharmony_ci */ 32cabdff1aSopenharmony_ci 33cabdff1aSopenharmony_ci#include "libavutil/frame.h" 34cabdff1aSopenharmony_ci#include "libavutil/mem.h" 35cabdff1aSopenharmony_ci#include "libavutil/opt.h" 36cabdff1aSopenharmony_ci#include "libavutil/pixdesc.h" 37cabdff1aSopenharmony_ci 38cabdff1aSopenharmony_ci#include "avcodec.h" 39cabdff1aSopenharmony_ci#include "codec_internal.h" 40cabdff1aSopenharmony_ci#include "encode.h" 41cabdff1aSopenharmony_ci#include "idctdsp.h" 42cabdff1aSopenharmony_ci#include "jpegtables.h" 43cabdff1aSopenharmony_ci#include "mathops.h" 44cabdff1aSopenharmony_ci#include "mjpegenc_common.h" 45cabdff1aSopenharmony_ci#include "mjpeg.h" 46cabdff1aSopenharmony_ci 47cabdff1aSopenharmony_citypedef struct LJpegEncContext { 48cabdff1aSopenharmony_ci AVClass *class; 49cabdff1aSopenharmony_ci IDCTDSPContext idsp; 50cabdff1aSopenharmony_ci ScanTable scantable; 51cabdff1aSopenharmony_ci uint16_t matrix[64]; 52cabdff1aSopenharmony_ci 53cabdff1aSopenharmony_ci int vsample[4]; 54cabdff1aSopenharmony_ci int hsample[4]; 55cabdff1aSopenharmony_ci 56cabdff1aSopenharmony_ci uint16_t huff_code_dc_luminance[12]; 57cabdff1aSopenharmony_ci uint16_t huff_code_dc_chrominance[12]; 58cabdff1aSopenharmony_ci uint8_t huff_size_dc_luminance[12]; 59cabdff1aSopenharmony_ci uint8_t huff_size_dc_chrominance[12]; 60cabdff1aSopenharmony_ci 61cabdff1aSopenharmony_ci uint16_t (*scratch)[4]; 62cabdff1aSopenharmony_ci int pred; 63cabdff1aSopenharmony_ci} LJpegEncContext; 64cabdff1aSopenharmony_ci 65cabdff1aSopenharmony_cistatic int ljpeg_encode_bgr(AVCodecContext *avctx, PutBitContext *pb, 66cabdff1aSopenharmony_ci const AVFrame *frame) 67cabdff1aSopenharmony_ci{ 68cabdff1aSopenharmony_ci LJpegEncContext *s = avctx->priv_data; 69cabdff1aSopenharmony_ci const int width = frame->width; 70cabdff1aSopenharmony_ci const int height = frame->height; 71cabdff1aSopenharmony_ci const int linesize = frame->linesize[0]; 72cabdff1aSopenharmony_ci uint16_t (*buffer)[4] = s->scratch; 73cabdff1aSopenharmony_ci int left[4], top[4], topleft[4]; 74cabdff1aSopenharmony_ci int x, y, i; 75cabdff1aSopenharmony_ci 76cabdff1aSopenharmony_ci for (i = 0; i < 4; i++) 77cabdff1aSopenharmony_ci buffer[0][i] = 1 << (9 - 1); 78cabdff1aSopenharmony_ci 79cabdff1aSopenharmony_ci for (y = 0; y < height; y++) { 80cabdff1aSopenharmony_ci const int modified_predictor = y ? s->pred : 1; 81cabdff1aSopenharmony_ci uint8_t *ptr = frame->data[0] + (linesize * y); 82cabdff1aSopenharmony_ci 83cabdff1aSopenharmony_ci if (put_bytes_left(pb, 0) < width * 4 * 4) { 84cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n"); 85cabdff1aSopenharmony_ci return -1; 86cabdff1aSopenharmony_ci } 87cabdff1aSopenharmony_ci 88cabdff1aSopenharmony_ci for (i = 0; i < 4; i++) 89cabdff1aSopenharmony_ci top[i]= left[i]= topleft[i]= buffer[0][i]; 90cabdff1aSopenharmony_ci 91cabdff1aSopenharmony_ci for (x = 0; x < width; x++) { 92cabdff1aSopenharmony_ci if(avctx->pix_fmt == AV_PIX_FMT_BGR24){ 93cabdff1aSopenharmony_ci buffer[x][1] = ptr[3 * x + 0] - ptr[3 * x + 1] + 0x100; 94cabdff1aSopenharmony_ci buffer[x][2] = ptr[3 * x + 2] - ptr[3 * x + 1] + 0x100; 95cabdff1aSopenharmony_ci buffer[x][0] = (ptr[3 * x + 0] + 2 * ptr[3 * x + 1] + ptr[3 * x + 2]) >> 2; 96cabdff1aSopenharmony_ci }else{ 97cabdff1aSopenharmony_ci buffer[x][1] = ptr[4 * x + 0] - ptr[4 * x + 1] + 0x100; 98cabdff1aSopenharmony_ci buffer[x][2] = ptr[4 * x + 2] - ptr[4 * x + 1] + 0x100; 99cabdff1aSopenharmony_ci buffer[x][0] = (ptr[4 * x + 0] + 2 * ptr[4 * x + 1] + ptr[4 * x + 2]) >> 2; 100cabdff1aSopenharmony_ci if (avctx->pix_fmt == AV_PIX_FMT_BGRA) 101cabdff1aSopenharmony_ci buffer[x][3] = ptr[4 * x + 3]; 102cabdff1aSopenharmony_ci } 103cabdff1aSopenharmony_ci 104cabdff1aSopenharmony_ci for (i = 0; i < 3 + (avctx->pix_fmt == AV_PIX_FMT_BGRA); i++) { 105cabdff1aSopenharmony_ci int pred, diff; 106cabdff1aSopenharmony_ci 107cabdff1aSopenharmony_ci PREDICT(pred, topleft[i], top[i], left[i], modified_predictor); 108cabdff1aSopenharmony_ci 109cabdff1aSopenharmony_ci topleft[i] = top[i]; 110cabdff1aSopenharmony_ci top[i] = buffer[x+1][i]; 111cabdff1aSopenharmony_ci 112cabdff1aSopenharmony_ci left[i] = buffer[x][i]; 113cabdff1aSopenharmony_ci 114cabdff1aSopenharmony_ci diff = ((left[i] - pred + 0x100) & 0x1FF) - 0x100; 115cabdff1aSopenharmony_ci 116cabdff1aSopenharmony_ci if (i == 0 || i == 3) 117cabdff1aSopenharmony_ci ff_mjpeg_encode_dc(pb, diff, s->huff_size_dc_luminance, s->huff_code_dc_luminance); //FIXME ugly 118cabdff1aSopenharmony_ci else 119cabdff1aSopenharmony_ci ff_mjpeg_encode_dc(pb, diff, s->huff_size_dc_chrominance, s->huff_code_dc_chrominance); 120cabdff1aSopenharmony_ci } 121cabdff1aSopenharmony_ci } 122cabdff1aSopenharmony_ci } 123cabdff1aSopenharmony_ci 124cabdff1aSopenharmony_ci return 0; 125cabdff1aSopenharmony_ci} 126cabdff1aSopenharmony_ci 127cabdff1aSopenharmony_cistatic inline void ljpeg_encode_yuv_mb(LJpegEncContext *s, PutBitContext *pb, 128cabdff1aSopenharmony_ci const AVFrame *frame, int predictor, 129cabdff1aSopenharmony_ci int mb_x, int mb_y) 130cabdff1aSopenharmony_ci{ 131cabdff1aSopenharmony_ci int i; 132cabdff1aSopenharmony_ci 133cabdff1aSopenharmony_ci if (mb_x == 0 || mb_y == 0) { 134cabdff1aSopenharmony_ci for (i = 0; i < 3; i++) { 135cabdff1aSopenharmony_ci uint8_t *ptr; 136cabdff1aSopenharmony_ci int x, y, h, v, linesize; 137cabdff1aSopenharmony_ci h = s->hsample[i]; 138cabdff1aSopenharmony_ci v = s->vsample[i]; 139cabdff1aSopenharmony_ci linesize = frame->linesize[i]; 140cabdff1aSopenharmony_ci 141cabdff1aSopenharmony_ci for (y = 0; y < v; y++) { 142cabdff1aSopenharmony_ci for (x = 0; x < h; x++) { 143cabdff1aSopenharmony_ci int pred; 144cabdff1aSopenharmony_ci 145cabdff1aSopenharmony_ci ptr = frame->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap 146cabdff1aSopenharmony_ci if (y == 0 && mb_y == 0) { 147cabdff1aSopenharmony_ci if (x == 0 && mb_x == 0) 148cabdff1aSopenharmony_ci pred = 128; 149cabdff1aSopenharmony_ci else 150cabdff1aSopenharmony_ci pred = ptr[-1]; 151cabdff1aSopenharmony_ci } else { 152cabdff1aSopenharmony_ci if (x == 0 && mb_x == 0) { 153cabdff1aSopenharmony_ci pred = ptr[-linesize]; 154cabdff1aSopenharmony_ci } else { 155cabdff1aSopenharmony_ci PREDICT(pred, ptr[-linesize - 1], ptr[-linesize], 156cabdff1aSopenharmony_ci ptr[-1], predictor); 157cabdff1aSopenharmony_ci } 158cabdff1aSopenharmony_ci } 159cabdff1aSopenharmony_ci 160cabdff1aSopenharmony_ci if (i == 0) 161cabdff1aSopenharmony_ci ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_luminance, s->huff_code_dc_luminance); //FIXME ugly 162cabdff1aSopenharmony_ci else 163cabdff1aSopenharmony_ci ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_chrominance, s->huff_code_dc_chrominance); 164cabdff1aSopenharmony_ci } 165cabdff1aSopenharmony_ci } 166cabdff1aSopenharmony_ci } 167cabdff1aSopenharmony_ci } else { 168cabdff1aSopenharmony_ci for (i = 0; i < 3; i++) { 169cabdff1aSopenharmony_ci uint8_t *ptr; 170cabdff1aSopenharmony_ci int x, y, h, v, linesize; 171cabdff1aSopenharmony_ci h = s->hsample[i]; 172cabdff1aSopenharmony_ci v = s->vsample[i]; 173cabdff1aSopenharmony_ci linesize = frame->linesize[i]; 174cabdff1aSopenharmony_ci 175cabdff1aSopenharmony_ci for (y = 0; y < v; y++) { 176cabdff1aSopenharmony_ci for (x = 0; x < h; x++) { 177cabdff1aSopenharmony_ci int pred; 178cabdff1aSopenharmony_ci 179cabdff1aSopenharmony_ci ptr = frame->data[i] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap 180cabdff1aSopenharmony_ci PREDICT(pred, ptr[-linesize - 1], ptr[-linesize], ptr[-1], predictor); 181cabdff1aSopenharmony_ci 182cabdff1aSopenharmony_ci if (i == 0) 183cabdff1aSopenharmony_ci ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_luminance, s->huff_code_dc_luminance); //FIXME ugly 184cabdff1aSopenharmony_ci else 185cabdff1aSopenharmony_ci ff_mjpeg_encode_dc(pb, *ptr - pred, s->huff_size_dc_chrominance, s->huff_code_dc_chrominance); 186cabdff1aSopenharmony_ci } 187cabdff1aSopenharmony_ci } 188cabdff1aSopenharmony_ci } 189cabdff1aSopenharmony_ci } 190cabdff1aSopenharmony_ci} 191cabdff1aSopenharmony_ci 192cabdff1aSopenharmony_cistatic int ljpeg_encode_yuv(AVCodecContext *avctx, PutBitContext *pb, 193cabdff1aSopenharmony_ci const AVFrame *frame) 194cabdff1aSopenharmony_ci{ 195cabdff1aSopenharmony_ci LJpegEncContext *s = avctx->priv_data; 196cabdff1aSopenharmony_ci const int mb_width = (avctx->width + s->hsample[0] - 1) / s->hsample[0]; 197cabdff1aSopenharmony_ci const int mb_height = (avctx->height + s->vsample[0] - 1) / s->vsample[0]; 198cabdff1aSopenharmony_ci int mb_x, mb_y; 199cabdff1aSopenharmony_ci 200cabdff1aSopenharmony_ci for (mb_y = 0; mb_y < mb_height; mb_y++) { 201cabdff1aSopenharmony_ci if (put_bytes_left(pb, 0) < 202cabdff1aSopenharmony_ci mb_width * 4 * 3 * s->hsample[0] * s->vsample[0]) { 203cabdff1aSopenharmony_ci av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n"); 204cabdff1aSopenharmony_ci return -1; 205cabdff1aSopenharmony_ci } 206cabdff1aSopenharmony_ci 207cabdff1aSopenharmony_ci for (mb_x = 0; mb_x < mb_width; mb_x++) 208cabdff1aSopenharmony_ci ljpeg_encode_yuv_mb(s, pb, frame, s->pred, mb_x, mb_y); 209cabdff1aSopenharmony_ci } 210cabdff1aSopenharmony_ci 211cabdff1aSopenharmony_ci return 0; 212cabdff1aSopenharmony_ci} 213cabdff1aSopenharmony_ci 214cabdff1aSopenharmony_cistatic int ljpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt, 215cabdff1aSopenharmony_ci const AVFrame *pict, int *got_packet) 216cabdff1aSopenharmony_ci{ 217cabdff1aSopenharmony_ci LJpegEncContext *s = avctx->priv_data; 218cabdff1aSopenharmony_ci PutBitContext pb; 219cabdff1aSopenharmony_ci const int width = avctx->width; 220cabdff1aSopenharmony_ci const int height = avctx->height; 221cabdff1aSopenharmony_ci const int mb_width = (width + s->hsample[0] - 1) / s->hsample[0]; 222cabdff1aSopenharmony_ci const int mb_height = (height + s->vsample[0] - 1) / s->vsample[0]; 223cabdff1aSopenharmony_ci size_t max_pkt_size = AV_INPUT_BUFFER_MIN_SIZE; 224cabdff1aSopenharmony_ci int ret, header_bits; 225cabdff1aSopenharmony_ci 226cabdff1aSopenharmony_ci if( avctx->pix_fmt == AV_PIX_FMT_BGR0 227cabdff1aSopenharmony_ci || avctx->pix_fmt == AV_PIX_FMT_BGR24) 228cabdff1aSopenharmony_ci max_pkt_size += width * height * 3 * 4; 229cabdff1aSopenharmony_ci else if(avctx->pix_fmt == AV_PIX_FMT_BGRA) 230cabdff1aSopenharmony_ci max_pkt_size += width * height * 4 * 4; 231cabdff1aSopenharmony_ci else { 232cabdff1aSopenharmony_ci max_pkt_size += mb_width * mb_height * 3 * 4 233cabdff1aSopenharmony_ci * s->hsample[0] * s->vsample[0]; 234cabdff1aSopenharmony_ci } 235cabdff1aSopenharmony_ci 236cabdff1aSopenharmony_ci if ((ret = ff_mjpeg_add_icc_profile_size(avctx, pict, &max_pkt_size)) < 0) 237cabdff1aSopenharmony_ci return ret; 238cabdff1aSopenharmony_ci if ((ret = ff_alloc_packet(avctx, pkt, max_pkt_size)) < 0) 239cabdff1aSopenharmony_ci return ret; 240cabdff1aSopenharmony_ci 241cabdff1aSopenharmony_ci init_put_bits(&pb, pkt->data, pkt->size); 242cabdff1aSopenharmony_ci 243cabdff1aSopenharmony_ci ff_mjpeg_encode_picture_header(avctx, &pb, pict, NULL, &s->scantable, 244cabdff1aSopenharmony_ci s->pred, s->matrix, s->matrix, 0); 245cabdff1aSopenharmony_ci 246cabdff1aSopenharmony_ci header_bits = put_bits_count(&pb); 247cabdff1aSopenharmony_ci 248cabdff1aSopenharmony_ci if( avctx->pix_fmt == AV_PIX_FMT_BGR0 249cabdff1aSopenharmony_ci || avctx->pix_fmt == AV_PIX_FMT_BGRA 250cabdff1aSopenharmony_ci || avctx->pix_fmt == AV_PIX_FMT_BGR24) 251cabdff1aSopenharmony_ci ret = ljpeg_encode_bgr(avctx, &pb, pict); 252cabdff1aSopenharmony_ci else 253cabdff1aSopenharmony_ci ret = ljpeg_encode_yuv(avctx, &pb, pict); 254cabdff1aSopenharmony_ci if (ret < 0) 255cabdff1aSopenharmony_ci return ret; 256cabdff1aSopenharmony_ci 257cabdff1aSopenharmony_ci emms_c(); 258cabdff1aSopenharmony_ci 259cabdff1aSopenharmony_ci ff_mjpeg_escape_FF(&pb, header_bits >> 3); 260cabdff1aSopenharmony_ci ff_mjpeg_encode_picture_trailer(&pb, header_bits); 261cabdff1aSopenharmony_ci 262cabdff1aSopenharmony_ci flush_put_bits(&pb); 263cabdff1aSopenharmony_ci pkt->size = put_bits_ptr(&pb) - pb.buf; 264cabdff1aSopenharmony_ci *got_packet = 1; 265cabdff1aSopenharmony_ci 266cabdff1aSopenharmony_ci return 0; 267cabdff1aSopenharmony_ci} 268cabdff1aSopenharmony_ci 269cabdff1aSopenharmony_cistatic av_cold int ljpeg_encode_close(AVCodecContext *avctx) 270cabdff1aSopenharmony_ci{ 271cabdff1aSopenharmony_ci LJpegEncContext *s = avctx->priv_data; 272cabdff1aSopenharmony_ci 273cabdff1aSopenharmony_ci av_freep(&s->scratch); 274cabdff1aSopenharmony_ci 275cabdff1aSopenharmony_ci return 0; 276cabdff1aSopenharmony_ci} 277cabdff1aSopenharmony_ci 278cabdff1aSopenharmony_cistatic av_cold int ljpeg_encode_init(AVCodecContext *avctx) 279cabdff1aSopenharmony_ci{ 280cabdff1aSopenharmony_ci int ret = ff_mjpeg_encode_check_pix_fmt(avctx); 281cabdff1aSopenharmony_ci LJpegEncContext *s = avctx->priv_data; 282cabdff1aSopenharmony_ci 283cabdff1aSopenharmony_ci if (ret < 0) 284cabdff1aSopenharmony_ci return ret; 285cabdff1aSopenharmony_ci 286cabdff1aSopenharmony_ci s->scratch = av_malloc_array(avctx->width + 1, sizeof(*s->scratch)); 287cabdff1aSopenharmony_ci if (!s->scratch) 288cabdff1aSopenharmony_ci return AVERROR(ENOMEM); 289cabdff1aSopenharmony_ci 290cabdff1aSopenharmony_ci ff_idctdsp_init(&s->idsp, avctx); 291cabdff1aSopenharmony_ci ff_init_scantable(s->idsp.idct_permutation, &s->scantable, 292cabdff1aSopenharmony_ci ff_zigzag_direct); 293cabdff1aSopenharmony_ci 294cabdff1aSopenharmony_ci ff_mjpeg_init_hvsample(avctx, s->hsample, s->vsample); 295cabdff1aSopenharmony_ci 296cabdff1aSopenharmony_ci ff_mjpeg_build_huffman_codes(s->huff_size_dc_luminance, 297cabdff1aSopenharmony_ci s->huff_code_dc_luminance, 298cabdff1aSopenharmony_ci ff_mjpeg_bits_dc_luminance, 299cabdff1aSopenharmony_ci ff_mjpeg_val_dc); 300cabdff1aSopenharmony_ci ff_mjpeg_build_huffman_codes(s->huff_size_dc_chrominance, 301cabdff1aSopenharmony_ci s->huff_code_dc_chrominance, 302cabdff1aSopenharmony_ci ff_mjpeg_bits_dc_chrominance, 303cabdff1aSopenharmony_ci ff_mjpeg_val_dc); 304cabdff1aSopenharmony_ci 305cabdff1aSopenharmony_ci return 0; 306cabdff1aSopenharmony_ci} 307cabdff1aSopenharmony_ci 308cabdff1aSopenharmony_ci#define OFFSET(x) offsetof(LJpegEncContext, x) 309cabdff1aSopenharmony_ci#define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM 310cabdff1aSopenharmony_cistatic const AVOption options[] = { 311cabdff1aSopenharmony_ci{ "pred", "Prediction method", OFFSET(pred), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, 3, VE, "pred" }, 312cabdff1aSopenharmony_ci { "left", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "pred" }, 313cabdff1aSopenharmony_ci { "plane", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, INT_MIN, INT_MAX, VE, "pred" }, 314cabdff1aSopenharmony_ci { "median", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 3 }, INT_MIN, INT_MAX, VE, "pred" }, 315cabdff1aSopenharmony_ci 316cabdff1aSopenharmony_ci { NULL}, 317cabdff1aSopenharmony_ci}; 318cabdff1aSopenharmony_ci 319cabdff1aSopenharmony_cistatic const AVClass ljpeg_class = { 320cabdff1aSopenharmony_ci .class_name = "ljpeg", 321cabdff1aSopenharmony_ci .item_name = av_default_item_name, 322cabdff1aSopenharmony_ci .option = options, 323cabdff1aSopenharmony_ci .version = LIBAVUTIL_VERSION_INT, 324cabdff1aSopenharmony_ci}; 325cabdff1aSopenharmony_ci 326cabdff1aSopenharmony_ciconst FFCodec ff_ljpeg_encoder = { 327cabdff1aSopenharmony_ci .p.name = "ljpeg", 328cabdff1aSopenharmony_ci .p.long_name = NULL_IF_CONFIG_SMALL("Lossless JPEG"), 329cabdff1aSopenharmony_ci .p.type = AVMEDIA_TYPE_VIDEO, 330cabdff1aSopenharmony_ci .p.id = AV_CODEC_ID_LJPEG, 331cabdff1aSopenharmony_ci .priv_data_size = sizeof(LJpegEncContext), 332cabdff1aSopenharmony_ci .p.priv_class = &ljpeg_class, 333cabdff1aSopenharmony_ci .init = ljpeg_encode_init, 334cabdff1aSopenharmony_ci FF_CODEC_ENCODE_CB(ljpeg_encode_frame), 335cabdff1aSopenharmony_ci .close = ljpeg_encode_close, 336cabdff1aSopenharmony_ci .p.capabilities = AV_CODEC_CAP_FRAME_THREADS, 337cabdff1aSopenharmony_ci .p.pix_fmts = (const enum AVPixelFormat[]){ 338cabdff1aSopenharmony_ci AV_PIX_FMT_BGR24 , AV_PIX_FMT_BGRA , AV_PIX_FMT_BGR0, 339cabdff1aSopenharmony_ci AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUVJ422P, 340cabdff1aSopenharmony_ci AV_PIX_FMT_YUV420P , AV_PIX_FMT_YUV444P , AV_PIX_FMT_YUV422P, 341cabdff1aSopenharmony_ci AV_PIX_FMT_NONE}, 342cabdff1aSopenharmony_ci .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, 343cabdff1aSopenharmony_ci}; 344