Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Raw Video Decoder
  3.  * Copyright (c) 2001 Fabrice Bellard
  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.  * Raw Video Decoder
  25.  */
  26.  
  27. #include "avcodec.h"
  28. #include "raw.h"
  29. #include "libavutil/avassert.h"
  30. #include "libavutil/buffer.h"
  31. #include "libavutil/common.h"
  32. #include "libavutil/intreadwrite.h"
  33. #include "libavutil/imgutils.h"
  34. #include "libavutil/opt.h"
  35.  
  36. typedef struct RawVideoContext {
  37.     AVClass *av_class;
  38.     AVBufferRef *palette;
  39.     int frame_size;  /* size of the frame in bytes */
  40.     int flip;
  41.     int is_2_4_bpp; // 2 or 4 bpp raw in avi/mov
  42.     int is_yuv2;
  43.     int tff;
  44. } RawVideoContext;
  45.  
  46. static const AVOption options[]={
  47. {"top", "top field first", offsetof(RawVideoContext, tff), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, AV_OPT_FLAG_DECODING_PARAM|AV_OPT_FLAG_VIDEO_PARAM},
  48. {NULL}
  49. };
  50.  
  51. static const AVClass rawdec_class = {
  52.     .class_name = "rawdec",
  53.     .option     = options,
  54.     .version    = LIBAVUTIL_VERSION_INT,
  55. };
  56.  
  57. static const PixelFormatTag pix_fmt_bps_avi[] = {
  58.     { AV_PIX_FMT_MONOWHITE, 1 },
  59.     { AV_PIX_FMT_PAL8,    2 },
  60.     { AV_PIX_FMT_PAL8,    4 },
  61.     { AV_PIX_FMT_PAL8,    8 },
  62.     { AV_PIX_FMT_RGB444LE, 12 },
  63.     { AV_PIX_FMT_RGB555LE, 15 },
  64.     { AV_PIX_FMT_RGB555LE, 16 },
  65.     { AV_PIX_FMT_BGR24,  24 },
  66.     { AV_PIX_FMT_BGRA,   32 },
  67.     { AV_PIX_FMT_NONE,    0 },
  68. };
  69.  
  70. static const PixelFormatTag pix_fmt_bps_mov[] = {
  71.     { AV_PIX_FMT_MONOWHITE, 1 },
  72.     { AV_PIX_FMT_PAL8,      2 },
  73.     { AV_PIX_FMT_PAL8,      4 },
  74.     { AV_PIX_FMT_PAL8,      8 },
  75.     // FIXME swscale does not support 16 bit in .mov, sample 16bit.mov
  76.     // http://developer.apple.com/documentation/QuickTime/QTFF/QTFFChap3/qtff3.html
  77.     { AV_PIX_FMT_RGB555BE, 16 },
  78.     { AV_PIX_FMT_RGB24,    24 },
  79.     { AV_PIX_FMT_ARGB,     32 },
  80.     { AV_PIX_FMT_MONOWHITE,33 },
  81.     { AV_PIX_FMT_NONE,      0 },
  82. };
  83.  
  84. enum AVPixelFormat avpriv_find_pix_fmt(const PixelFormatTag *tags,
  85.                                        unsigned int fourcc)
  86. {
  87.     while (tags->pix_fmt >= 0) {
  88.         if (tags->fourcc == fourcc)
  89.             return tags->pix_fmt;
  90.         tags++;
  91.     }
  92.     return AV_PIX_FMT_NONE;
  93. }
  94.  
  95. #if LIBAVCODEC_VERSION_MAJOR < 55
  96. enum AVPixelFormat ff_find_pix_fmt(const PixelFormatTag *tags, unsigned int fourcc)
  97. {
  98.     return avpriv_find_pix_fmt(tags, fourcc);
  99. }
  100. #endif
  101.  
  102. static av_cold int raw_init_decoder(AVCodecContext *avctx)
  103. {
  104.     RawVideoContext *context = avctx->priv_data;
  105.     const AVPixFmtDescriptor *desc;
  106.  
  107.     if (   avctx->codec_tag == MKTAG('r','a','w',' ')
  108.         || avctx->codec_tag == MKTAG('N','O','1','6'))
  109.         avctx->pix_fmt = avpriv_find_pix_fmt(pix_fmt_bps_mov,
  110.                                       avctx->bits_per_coded_sample);
  111.     else if (avctx->codec_tag == MKTAG('W', 'R', 'A', 'W'))
  112.         avctx->pix_fmt = avpriv_find_pix_fmt(pix_fmt_bps_avi,
  113.                                       avctx->bits_per_coded_sample);
  114.     else if (avctx->codec_tag)
  115.         avctx->pix_fmt = avpriv_find_pix_fmt(ff_raw_pix_fmt_tags, avctx->codec_tag);
  116.     else if (avctx->pix_fmt == AV_PIX_FMT_NONE && avctx->bits_per_coded_sample)
  117.         avctx->pix_fmt = avpriv_find_pix_fmt(pix_fmt_bps_avi,
  118.                                       avctx->bits_per_coded_sample);
  119.  
  120.     desc = av_pix_fmt_desc_get(avctx->pix_fmt);
  121.     if (!desc) {
  122.         av_log(avctx, AV_LOG_ERROR, "Invalid pixel format.\n");
  123.         return AVERROR(EINVAL);
  124.     }
  125.  
  126.     if (desc->flags & (AV_PIX_FMT_FLAG_PAL | AV_PIX_FMT_FLAG_PSEUDOPAL)) {
  127.         context->palette = av_buffer_alloc(AVPALETTE_SIZE);
  128.         if (!context->palette)
  129.             return AVERROR(ENOMEM);
  130.         if (desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)
  131.             avpriv_set_systematic_pal2((uint32_t*)context->palette->data, avctx->pix_fmt);
  132.         else
  133.             memset(context->palette->data, 0, AVPALETTE_SIZE);
  134.     }
  135.  
  136.     if ((avctx->bits_per_coded_sample == 4 || avctx->bits_per_coded_sample == 2) &&
  137.         avctx->pix_fmt == AV_PIX_FMT_PAL8 &&
  138.        (!avctx->codec_tag || avctx->codec_tag == MKTAG('r','a','w',' '))) {
  139.         context->is_2_4_bpp = 1;
  140.         context->frame_size = avpicture_get_size(avctx->pix_fmt,
  141.                                                  FFALIGN(avctx->width, 16),
  142.                                                  avctx->height);
  143.     } else {
  144.         context->frame_size = avpicture_get_size(avctx->pix_fmt, avctx->width,
  145.                                                  avctx->height);
  146.     }
  147.  
  148.     if ((avctx->extradata_size >= 9 &&
  149.          !memcmp(avctx->extradata + avctx->extradata_size - 9, "BottomUp", 9)) ||
  150.         avctx->codec_tag == MKTAG('c','y','u','v') ||
  151.         avctx->codec_tag == MKTAG(3, 0, 0, 0) ||
  152.         avctx->codec_tag == MKTAG('W','R','A','W'))
  153.         context->flip = 1;
  154.  
  155.     if (avctx->codec_tag == AV_RL32("yuv2") &&
  156.         avctx->pix_fmt   == AV_PIX_FMT_YUYV422)
  157.         context->is_yuv2 = 1;
  158.  
  159.     return 0;
  160. }
  161.  
  162. static void flip(AVCodecContext *avctx, AVPicture *picture)
  163. {
  164.     picture->data[0]     += picture->linesize[0] * (avctx->height - 1);
  165.     picture->linesize[0] *= -1;
  166. }
  167.  
  168. static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame,
  169.                       AVPacket *avpkt)
  170. {
  171.     const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
  172.     RawVideoContext *context       = avctx->priv_data;
  173.     const uint8_t *buf             = avpkt->data;
  174.     int buf_size                   = avpkt->size;
  175.     int linesize_align             = 4;
  176.     int res, len;
  177.     int need_copy                  = !avpkt->buf || context->is_2_4_bpp || context->is_yuv2;
  178.  
  179.     AVFrame   *frame   = data;
  180.     AVPicture *picture = data;
  181.  
  182.     frame->pict_type        = AV_PICTURE_TYPE_I;
  183.     frame->key_frame        = 1;
  184.     frame->reordered_opaque = avctx->reordered_opaque;
  185.     frame->pkt_pts          = avctx->pkt->pts;
  186.     av_frame_set_pkt_pos     (frame, avctx->pkt->pos);
  187.     av_frame_set_pkt_duration(frame, avctx->pkt->duration);
  188.  
  189.     if (context->tff >= 0) {
  190.         frame->interlaced_frame = 1;
  191.         frame->top_field_first  = context->tff;
  192.     }
  193.  
  194.     if ((res = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0)
  195.         return res;
  196.  
  197.     if (need_copy)
  198.         frame->buf[0] = av_buffer_alloc(FFMAX(context->frame_size, buf_size));
  199.     else
  200.         frame->buf[0] = av_buffer_ref(avpkt->buf);
  201.     if (!frame->buf[0])
  202.         return AVERROR(ENOMEM);
  203.  
  204.     //2bpp and 4bpp raw in avi and mov (yes this is ugly ...)
  205.     if (context->is_2_4_bpp) {
  206.         int i;
  207.         uint8_t *dst = frame->buf[0]->data;
  208.         buf_size = context->frame_size - AVPALETTE_SIZE;
  209.         if (avctx->bits_per_coded_sample == 4) {
  210.             for (i = 0; 2 * i + 1 < buf_size && i<avpkt->size; i++) {
  211.                 dst[2 * i + 0] = buf[i] >> 4;
  212.                 dst[2 * i + 1] = buf[i] & 15;
  213.             }
  214.             linesize_align = 8;
  215.         } else {
  216.             av_assert0(avctx->bits_per_coded_sample == 2);
  217.             for (i = 0; 4 * i + 3 < buf_size && i<avpkt->size; i++) {
  218.                 dst[4 * i + 0] = buf[i] >> 6;
  219.                 dst[4 * i + 1] = buf[i] >> 4 & 3;
  220.                 dst[4 * i + 2] = buf[i] >> 2 & 3;
  221.                 dst[4 * i + 3] = buf[i]      & 3;
  222.             }
  223.             linesize_align = 16;
  224.         }
  225.         buf = dst;
  226.     } else if (need_copy) {
  227.         memcpy(frame->buf[0]->data, buf, buf_size);
  228.         buf = frame->buf[0]->data;
  229.     }
  230.  
  231.     if (avctx->codec_tag == MKTAG('A', 'V', '1', 'x') ||
  232.         avctx->codec_tag == MKTAG('A', 'V', 'u', 'p'))
  233.         buf += buf_size - context->frame_size;
  234.  
  235.     len = context->frame_size - (avctx->pix_fmt==AV_PIX_FMT_PAL8 ? AVPALETTE_SIZE : 0);
  236.     if (buf_size < len) {
  237.         av_log(avctx, AV_LOG_ERROR, "Invalid buffer size, packet size %d < expected frame_size %d\n", buf_size, len);
  238.         av_buffer_unref(&frame->buf[0]);
  239.         return AVERROR(EINVAL);
  240.     }
  241.  
  242.     if ((res = avpicture_fill(picture, buf, avctx->pix_fmt,
  243.                               avctx->width, avctx->height)) < 0) {
  244.         av_buffer_unref(&frame->buf[0]);
  245.         return res;
  246.     }
  247.  
  248.     if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
  249.         const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE,
  250.                                                      NULL);
  251.  
  252.         if (pal) {
  253.             av_buffer_unref(&context->palette);
  254.             context->palette = av_buffer_alloc(AVPALETTE_SIZE);
  255.             if (!context->palette) {
  256.                 av_buffer_unref(&frame->buf[0]);
  257.                 return AVERROR(ENOMEM);
  258.             }
  259.             memcpy(context->palette->data, pal, AVPALETTE_SIZE);
  260.             frame->palette_has_changed = 1;
  261.         }
  262.     }
  263.  
  264.     if ((avctx->pix_fmt==AV_PIX_FMT_BGR24    ||
  265.         avctx->pix_fmt==AV_PIX_FMT_GRAY8    ||
  266.         avctx->pix_fmt==AV_PIX_FMT_RGB555LE ||
  267.         avctx->pix_fmt==AV_PIX_FMT_RGB555BE ||
  268.         avctx->pix_fmt==AV_PIX_FMT_RGB565LE ||
  269.         avctx->pix_fmt==AV_PIX_FMT_MONOWHITE ||
  270.         avctx->pix_fmt==AV_PIX_FMT_PAL8) &&
  271.         FFALIGN(frame->linesize[0], linesize_align) * avctx->height <= buf_size)
  272.         frame->linesize[0] = FFALIGN(frame->linesize[0], linesize_align);
  273.  
  274.     if (avctx->pix_fmt == AV_PIX_FMT_NV12 && avctx->codec_tag == MKTAG('N', 'V', '1', '2') &&
  275.         FFALIGN(frame->linesize[0], linesize_align) * avctx->height +
  276.         FFALIGN(frame->linesize[1], linesize_align) * ((avctx->height + 1) / 2) <= buf_size) {
  277.         int la0 = FFALIGN(frame->linesize[0], linesize_align);
  278.         frame->data[1] += (la0 - frame->linesize[0]) * avctx->height;
  279.         frame->linesize[0] = la0;
  280.         frame->linesize[1] = FFALIGN(frame->linesize[1], linesize_align);
  281.     }
  282.  
  283.     if ((avctx->pix_fmt == AV_PIX_FMT_PAL8 && buf_size < context->frame_size) ||
  284.         (desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)) {
  285.         frame->buf[1]  = av_buffer_ref(context->palette);
  286.         if (!frame->buf[1]) {
  287.             av_buffer_unref(&frame->buf[0]);
  288.             return AVERROR(ENOMEM);
  289.         }
  290.         frame->data[1] = frame->buf[1]->data;
  291.     }
  292.  
  293.     if (avctx->pix_fmt == AV_PIX_FMT_BGR24 &&
  294.         ((frame->linesize[0] + 3) & ~3) * avctx->height <= buf_size)
  295.         frame->linesize[0] = (frame->linesize[0] + 3) & ~3;
  296.  
  297.     if (context->flip)
  298.         flip(avctx, picture);
  299.  
  300.     if (avctx->codec_tag == MKTAG('Y', 'V', '1', '2') ||
  301.         avctx->codec_tag == MKTAG('Y', 'V', '1', '6') ||
  302.         avctx->codec_tag == MKTAG('Y', 'V', '2', '4') ||
  303.         avctx->codec_tag == MKTAG('Y', 'V', 'U', '9'))
  304.         FFSWAP(uint8_t *, picture->data[1], picture->data[2]);
  305.  
  306.     if (avctx->codec_tag == AV_RL32("I420") && (avctx->width+1)*(avctx->height+1) * 3/2 == buf_size) {
  307.         picture->data[1] = picture->data[1] +  (avctx->width+1)*(avctx->height+1) -avctx->width*avctx->height;
  308.         picture->data[2] = picture->data[2] + ((avctx->width+1)*(avctx->height+1) -avctx->width*avctx->height)*5/4;
  309.     }
  310.  
  311.     if (avctx->codec_tag == AV_RL32("yuv2") &&
  312.         avctx->pix_fmt   == AV_PIX_FMT_YUYV422) {
  313.         int x, y;
  314.         uint8_t *line = picture->data[0];
  315.         for (y = 0; y < avctx->height; y++) {
  316.             for (x = 0; x < avctx->width; x++)
  317.                 line[2 * x + 1] ^= 0x80;
  318.             line += picture->linesize[0];
  319.         }
  320.     }
  321.     if (avctx->codec_tag == AV_RL32("YVYU") &&
  322.         avctx->pix_fmt   == AV_PIX_FMT_YUYV422) {
  323.         int x, y;
  324.         uint8_t *line = picture->data[0];
  325.         for(y = 0; y < avctx->height; y++) {
  326.             for(x = 0; x < avctx->width - 1; x += 2)
  327.                 FFSWAP(uint8_t, line[2*x + 1], line[2*x + 3]);
  328.             line += picture->linesize[0];
  329.         }
  330.     }
  331.  
  332.     if (avctx->field_order > AV_FIELD_PROGRESSIVE) { /* we have interlaced material flagged in container */
  333.         frame->interlaced_frame = 1;
  334.         if (avctx->field_order == AV_FIELD_TT || avctx->field_order == AV_FIELD_TB)
  335.             frame->top_field_first = 1;
  336.     }
  337.  
  338.     *got_frame = 1;
  339.     return buf_size;
  340. }
  341.  
  342. static av_cold int raw_close_decoder(AVCodecContext *avctx)
  343. {
  344.     RawVideoContext *context = avctx->priv_data;
  345.  
  346.     av_buffer_unref(&context->palette);
  347.     return 0;
  348. }
  349.  
  350. AVCodec ff_rawvideo_decoder = {
  351.     .name           = "rawvideo",
  352.     .long_name      = NULL_IF_CONFIG_SMALL("raw video"),
  353.     .type           = AVMEDIA_TYPE_VIDEO,
  354.     .id             = AV_CODEC_ID_RAWVIDEO,
  355.     .priv_data_size = sizeof(RawVideoContext),
  356.     .init           = raw_init_decoder,
  357.     .close          = raw_close_decoder,
  358.     .decode         = raw_decode,
  359.     .priv_class     = &rawdec_class,
  360. };
  361.