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. if (frame_size > packet_size)
  62. return AVERROR_INVALIDDATA;
  63. if (avctx->width % 2)
  64. return AVERROR_PATCHWELCOME;
  65. ret = init_get_bits(&bc, avpkt->data, avctx->width * avctx->height * 20);
  66. if (ret)
  67. return ret;
  68. for (i = 0; i < avctx->height; i++) {
  69. y = (uint16_t*)(frame->data[0] + i * frame->linesize[0]);
  70. u = (uint16_t*)(frame->data[1] + i * frame->linesize[1]);
  71. v = (uint16_t*)(frame->data[2] + i * frame->linesize[2]);
  72. for (j = 0; j < avctx->width; j += 2) {
  73. *u++ = get_bits(&bc, 10);
  74. *y++ = get_bits(&bc, 10);
  75. *v++ = get_bits(&bc, 10);
  76. *y++ = get_bits(&bc, 10);
  77. }
  78. }
  79. return 0;
  80. }
  81. static av_cold int bitpacked_init_decoder(AVCodecContext *avctx)
  82. {
  83. struct BitpackedContext *bc = avctx->priv_data;
  84. if (!avctx->codec_tag || !avctx->width || !avctx->height)
  85. return AVERROR_INVALIDDATA;
  86. if (avctx->codec_tag == MKTAG('U', 'Y', 'V', 'Y')) {
  87. if (avctx->bits_per_coded_sample == 16 &&
  88. avctx->pix_fmt == AV_PIX_FMT_UYVY422)
  89. bc->decode = bitpacked_decode_uyvy422;
  90. else if (avctx->bits_per_coded_sample == 20 &&
  91. avctx->pix_fmt == AV_PIX_FMT_YUV422P10)
  92. bc->decode = bitpacked_decode_yuv422p10;
  93. else
  94. return AVERROR_INVALIDDATA;
  95. } else {
  96. return AVERROR_INVALIDDATA;
  97. }
  98. return 0;
  99. }
  100. static int bitpacked_decode(AVCodecContext *avctx, void *data, int *got_frame,
  101. AVPacket *avpkt)
  102. {
  103. struct BitpackedContext *bc = avctx->priv_data;
  104. int buf_size = avpkt->size;
  105. AVFrame *frame = data;
  106. int res;
  107. frame->pict_type = AV_PICTURE_TYPE_I;
  108. frame->key_frame = 1;
  109. res = bc->decode(avctx, frame, avpkt);
  110. if (res)
  111. return res;
  112. *got_frame = 1;
  113. return buf_size;
  114. }
  115. AVCodec ff_bitpacked_decoder = {
  116. .name = "bitpacked",
  117. .long_name = NULL_IF_CONFIG_SMALL("Bitpacked"),
  118. .type = AVMEDIA_TYPE_VIDEO,
  119. .id = AV_CODEC_ID_BITPACKED,
  120. .priv_data_size = sizeof(struct BitpackedContext),
  121. .init = bitpacked_init_decoder,
  122. .decode = bitpacked_decode,
  123. .capabilities = AV_CODEC_CAP_EXPERIMENTAL,
  124. .codec_tags = (const uint32_t []){
  125. MKTAG('U', 'Y', 'V', 'Y'),
  126. FF_CODEC_TAGS_END,
  127. },
  128. };