You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

124 lines
3.7KB

  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. * @file
  23. * Sunplus JPEG decoder (SP5X).
  24. */
  25. #include "avcodec.h"
  26. #include "internal.h"
  27. #include "mjpeg.h"
  28. #include "mjpegdec.h"
  29. #include "sp5x.h"
  30. int ff_sp5x_process_packet(AVCodecContext *avctx, AVPacket *avpkt)
  31. {
  32. const uint8_t *buf = avpkt->data;
  33. int buf_size = avpkt->size;
  34. AVBufferRef *buf_recoded;
  35. uint8_t *recoded;
  36. int i = 0, j = 0;
  37. if (!avctx->width || !avctx->height)
  38. return -1;
  39. buf_recoded = av_buffer_allocz(buf_size + 1024);
  40. if (!buf_recoded)
  41. return -1;
  42. recoded = buf_recoded->data;
  43. /* SOI */
  44. recoded[j++] = 0xFF;
  45. recoded[j++] = 0xD8;
  46. memcpy(recoded+j, &sp5x_data_dqt[0], sizeof(sp5x_data_dqt));
  47. memcpy(recoded + j + 5, &sp5x_qscale_five_quant_table[0], 64);
  48. memcpy(recoded + j + 70, &sp5x_qscale_five_quant_table[1], 64);
  49. j += sizeof(sp5x_data_dqt);
  50. memcpy(recoded+j, &sp5x_data_dht[0], sizeof(sp5x_data_dht));
  51. j += sizeof(sp5x_data_dht);
  52. memcpy(recoded+j, &sp5x_data_sof[0], sizeof(sp5x_data_sof));
  53. AV_WB16(recoded+j+5, avctx->coded_height);
  54. AV_WB16(recoded+j+7, avctx->coded_width);
  55. j += sizeof(sp5x_data_sof);
  56. memcpy(recoded+j, &sp5x_data_sos[0], sizeof(sp5x_data_sos));
  57. j += sizeof(sp5x_data_sos);
  58. if(avctx->codec_id==AV_CODEC_ID_AMV)
  59. for (i = 2; i < buf_size-2 && j < buf_size+1024-2; i++)
  60. recoded[j++] = buf[i];
  61. else
  62. for (i = 14; i < buf_size && j < buf_size+1024-3; i++)
  63. {
  64. recoded[j++] = buf[i];
  65. if (buf[i] == 0xff)
  66. recoded[j++] = 0;
  67. }
  68. /* EOI */
  69. recoded[j++] = 0xFF;
  70. recoded[j++] = 0xD9;
  71. av_buffer_unref(&avpkt->buf);
  72. avpkt->buf = buf_recoded;
  73. avpkt->data = recoded;
  74. avpkt->size = j;
  75. return 0;
  76. }
  77. #if CONFIG_SP5X_DECODER
  78. AVCodec ff_sp5x_decoder = {
  79. .name = "sp5x",
  80. .long_name = NULL_IF_CONFIG_SMALL("Sunplus JPEG (SP5X)"),
  81. .type = AVMEDIA_TYPE_VIDEO,
  82. .id = AV_CODEC_ID_SP5X,
  83. .priv_data_size = sizeof(MJpegDecodeContext),
  84. .init = ff_mjpeg_decode_init,
  85. .close = ff_mjpeg_decode_end,
  86. .receive_frame = ff_mjpeg_receive_frame,
  87. .capabilities = AV_CODEC_CAP_DR1,
  88. .max_lowres = 3,
  89. .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP |
  90. FF_CODEC_CAP_SETS_PKT_DTS,
  91. };
  92. #endif
  93. #if CONFIG_AMV_DECODER
  94. AVCodec ff_amv_decoder = {
  95. .name = "amv",
  96. .long_name = NULL_IF_CONFIG_SMALL("AMV Video"),
  97. .type = AVMEDIA_TYPE_VIDEO,
  98. .id = AV_CODEC_ID_AMV,
  99. .priv_data_size = sizeof(MJpegDecodeContext),
  100. .init = ff_mjpeg_decode_init,
  101. .close = ff_mjpeg_decode_end,
  102. .receive_frame = ff_mjpeg_receive_frame,
  103. .max_lowres = 3,
  104. .capabilities = AV_CODEC_CAP_DR1,
  105. .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP |
  106. FF_CODEC_CAP_SETS_PKT_DTS,
  107. };
  108. #endif