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.

154 lines
4.4KB

  1. /*
  2. * Unpack bit-packed streams to formats supported by FFmpeg
  3. * Copyright (c) 2017 Savoir-faire Linux, Inc
  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. /* Development sponsored by CBC/Radio-Canada */
  22. /**
  23. * @file
  24. * Bitpacked
  25. */
  26. #include "avcodec.h"
  27. #include "internal.h"
  28. #include "get_bits.h"
  29. #include "libavutil/imgutils.h"
  30. struct BitpackedContext {
  31. int (*decode)(AVCodecContext *avctx, AVFrame *frame,
  32. AVPacket *pkt);
  33. };
  34. /* For this format, it's a simple passthrough */
  35. static int bitpacked_decode_uyvy422(AVCodecContext *avctx, AVFrame *frame,
  36. AVPacket *avpkt)
  37. {
  38. int ret;
  39. /* there is no need to copy as the data already match
  40. * a known pixel format */
  41. frame->buf[0] = av_buffer_ref(avpkt->buf);
  42. ret = av_image_fill_arrays(frame->data, frame->linesize, avpkt->data,
  43. avctx->pix_fmt, avctx->width, avctx->height, 1);
  44. if (ret < 0) {
  45. av_buffer_unref(&frame->buf[0]);
  46. return ret;
  47. }
  48. return 0;
  49. }
  50. static int bitpacked_decode_yuv422p10(AVCodecContext *avctx, AVFrame *frame,
  51. AVPacket *avpkt)
  52. {
  53. uint64_t frame_size = (uint64_t)avctx->width * (uint64_t)avctx->height * 20;
  54. uint64_t packet_size = (uint64_t)avpkt->size * 8;
  55. GetBitContext bc;
  56. uint16_t *y, *u, *v;
  57. int ret, i, j;
  58. ret = ff_get_buffer(avctx, frame, 0);
  59. if (ret < 0)
  60. return ret;
  61. y = (uint16_t*)frame->data[0];
  62. u = (uint16_t*)frame->data[1];
  63. v = (uint16_t*)frame->data[2];
  64. if (frame_size > packet_size)
  65. return AVERROR_INVALIDDATA;
  66. if (avctx->width % 2)
  67. return AVERROR_PATCHWELCOME;
  68. ret = init_get_bits(&bc, avpkt->data, avctx->width * avctx->height * 20);
  69. if (ret)
  70. return ret;
  71. for (i = 0; i < avctx->height; i++) {
  72. y = (uint16_t*)(frame->data[0] + i * frame->linesize[0]);
  73. u = (uint16_t*)(frame->data[1] + i * frame->linesize[1]);
  74. v = (uint16_t*)(frame->data[2] + i * frame->linesize[2]);
  75. for (j = 0; j < avctx->width; j += 2) {
  76. *u++ = get_bits(&bc, 10);
  77. *y++ = get_bits(&bc, 10);
  78. *v++ = get_bits(&bc, 10);
  79. *y++ = get_bits(&bc, 10);
  80. }
  81. }
  82. return 0;
  83. }
  84. static av_cold int bitpacked_init_decoder(AVCodecContext *avctx)
  85. {
  86. struct BitpackedContext *bc = avctx->priv_data;
  87. if (!avctx->codec_tag || !avctx->width || !avctx->height)
  88. return AVERROR_INVALIDDATA;
  89. if (avctx->codec_tag == MKTAG('U', 'Y', 'V', 'Y')) {
  90. if (avctx->bits_per_coded_sample == 16 &&
  91. avctx->pix_fmt == AV_PIX_FMT_UYVY422)
  92. bc->decode = bitpacked_decode_uyvy422;
  93. else if (avctx->bits_per_coded_sample == 20 &&
  94. avctx->pix_fmt == AV_PIX_FMT_YUV422P10)
  95. bc->decode = bitpacked_decode_yuv422p10;
  96. else
  97. return AVERROR_INVALIDDATA;
  98. } else {
  99. return AVERROR_INVALIDDATA;
  100. }
  101. return 0;
  102. }
  103. static int bitpacked_decode(AVCodecContext *avctx, void *data, int *got_frame,
  104. AVPacket *avpkt)
  105. {
  106. struct BitpackedContext *bc = avctx->priv_data;
  107. int buf_size = avpkt->size;
  108. AVFrame *frame = data;
  109. int res;
  110. frame->pict_type = AV_PICTURE_TYPE_I;
  111. frame->key_frame = 1;
  112. res = bc->decode(avctx, frame, avpkt);
  113. if (res)
  114. return res;
  115. *got_frame = 1;
  116. return buf_size;
  117. }
  118. AVCodec ff_bitpacked_decoder = {
  119. .name = "bitpacked",
  120. .long_name = NULL_IF_CONFIG_SMALL("Bitpacked"),
  121. .type = AVMEDIA_TYPE_VIDEO,
  122. .id = AV_CODEC_ID_BITPACKED,
  123. .priv_data_size = sizeof(struct BitpackedContext),
  124. .init = bitpacked_init_decoder,
  125. .decode = bitpacked_decode,
  126. .capabilities = AV_CODEC_CAP_EXPERIMENTAL,
  127. };