1/* 2 * Sunplus JPEG decoder (SP5X) 3 * Copyright (c) 2003 Alex Beregszaszi 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22/** 23 * @file 24 * Sunplus JPEG decoder (SP5X). 25 */ 26 27#include "config_components.h" 28 29#include "avcodec.h" 30#include "codec_internal.h" 31#include "mjpeg.h" 32#include "mjpegdec.h" 33#include "sp5x.h" 34 35int ff_sp5x_process_packet(AVCodecContext *avctx, AVPacket *avpkt) 36{ 37 const uint8_t *buf = avpkt->data; 38 int buf_size = avpkt->size; 39 AVBufferRef *buf_recoded; 40 uint8_t *recoded; 41 int i = 0, j = 0; 42 43 if (!avctx->width || !avctx->height) 44 return -1; 45 46 buf_recoded = av_buffer_allocz(buf_size + 1024); 47 if (!buf_recoded) 48 return -1; 49 recoded = buf_recoded->data; 50 51 /* SOI */ 52 recoded[j++] = 0xFF; 53 recoded[j++] = 0xD8; 54 55 memcpy(recoded+j, &sp5x_data_dqt[0], sizeof(sp5x_data_dqt)); 56 memcpy(recoded + j + 5, &sp5x_qscale_five_quant_table[0], 64); 57 memcpy(recoded + j + 70, &sp5x_qscale_five_quant_table[1], 64); 58 j += sizeof(sp5x_data_dqt); 59 60 memcpy(recoded+j, &sp5x_data_dht[0], sizeof(sp5x_data_dht)); 61 j += sizeof(sp5x_data_dht); 62 63 memcpy(recoded+j, &sp5x_data_sof[0], sizeof(sp5x_data_sof)); 64 AV_WB16(recoded+j+5, avctx->coded_height); 65 AV_WB16(recoded+j+7, avctx->coded_width); 66 j += sizeof(sp5x_data_sof); 67 68 memcpy(recoded+j, &sp5x_data_sos[0], sizeof(sp5x_data_sos)); 69 j += sizeof(sp5x_data_sos); 70 71 if(avctx->codec_id==AV_CODEC_ID_AMV) 72 for (i = 2; i < buf_size-2 && j < buf_size+1024-2; i++) 73 recoded[j++] = buf[i]; 74 else 75 for (i = 14; i < buf_size && j < buf_size+1024-3; i++) 76 { 77 recoded[j++] = buf[i]; 78 if (buf[i] == 0xff) 79 recoded[j++] = 0; 80 } 81 82 /* EOI */ 83 recoded[j++] = 0xFF; 84 recoded[j++] = 0xD9; 85 86 av_buffer_unref(&avpkt->buf); 87 avpkt->buf = buf_recoded; 88 avpkt->data = recoded; 89 avpkt->size = j; 90 91 return 0; 92} 93 94#if CONFIG_SP5X_DECODER 95const FFCodec ff_sp5x_decoder = { 96 .p.name = "sp5x", 97 .p.long_name = NULL_IF_CONFIG_SMALL("Sunplus JPEG (SP5X)"), 98 .p.type = AVMEDIA_TYPE_VIDEO, 99 .p.id = AV_CODEC_ID_SP5X, 100 .priv_data_size = sizeof(MJpegDecodeContext), 101 .init = ff_mjpeg_decode_init, 102 .close = ff_mjpeg_decode_end, 103 FF_CODEC_RECEIVE_FRAME_CB(ff_mjpeg_receive_frame), 104 .p.capabilities = AV_CODEC_CAP_DR1, 105 .p.max_lowres = 3, 106 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP | 107 FF_CODEC_CAP_SETS_PKT_DTS, 108}; 109#endif 110#if CONFIG_AMV_DECODER 111const FFCodec ff_amv_decoder = { 112 .p.name = "amv", 113 .p.long_name = NULL_IF_CONFIG_SMALL("AMV Video"), 114 .p.type = AVMEDIA_TYPE_VIDEO, 115 .p.id = AV_CODEC_ID_AMV, 116 .priv_data_size = sizeof(MJpegDecodeContext), 117 .init = ff_mjpeg_decode_init, 118 .close = ff_mjpeg_decode_end, 119 FF_CODEC_RECEIVE_FRAME_CB(ff_mjpeg_receive_frame), 120 .p.max_lowres = 3, 121 .p.capabilities = AV_CODEC_CAP_DR1, 122 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP | 123 FF_CODEC_CAP_SETS_PKT_DTS, 124}; 125#endif 126