diff options
Diffstat (limited to 'chromium/third_party/ffmpeg/libavcodec/rawdec.c')
-rw-r--r-- | chromium/third_party/ffmpeg/libavcodec/rawdec.c | 129 |
1 files changed, 73 insertions, 56 deletions
diff --git a/chromium/third_party/ffmpeg/libavcodec/rawdec.c b/chromium/third_party/ffmpeg/libavcodec/rawdec.c index 3f4a8fc86d7..a03b1be9fe6 100644 --- a/chromium/third_party/ffmpeg/libavcodec/rawdec.c +++ b/chromium/third_party/ffmpeg/libavcodec/rawdec.c @@ -25,6 +25,8 @@ */ #include "avcodec.h" +#include "dsputil.h" +#include "get_bits.h" #include "internal.h" #include "raw.h" #include "libavutil/avassert.h" @@ -41,7 +43,12 @@ typedef struct RawVideoContext { int flip; int is_2_4_bpp; // 2 or 4 bpp raw in avi/mov int is_yuv2; + int is_lt_16bpp; // 16bpp pixfmt and bits_per_coded_sample < 16 int tff; + + DSPContext dsp; + void *bitstream_buf; + unsigned int bitstream_buf_size; } RawVideoContext; static const AVOption options[]={ @@ -55,44 +62,6 @@ static const AVClass rawdec_class = { .version = LIBAVUTIL_VERSION_INT, }; -static const PixelFormatTag pix_fmt_bps_avi[] = { - { AV_PIX_FMT_MONOWHITE, 1 }, - { AV_PIX_FMT_PAL8, 2 }, - { AV_PIX_FMT_PAL8, 4 }, - { AV_PIX_FMT_PAL8, 8 }, - { AV_PIX_FMT_RGB444LE, 12 }, - { AV_PIX_FMT_RGB555LE, 15 }, - { AV_PIX_FMT_RGB555LE, 16 }, - { AV_PIX_FMT_BGR24, 24 }, - { AV_PIX_FMT_BGRA, 32 }, - { AV_PIX_FMT_NONE, 0 }, -}; - -static const PixelFormatTag pix_fmt_bps_mov[] = { - { AV_PIX_FMT_MONOWHITE, 1 }, - { AV_PIX_FMT_PAL8, 2 }, - { AV_PIX_FMT_PAL8, 4 }, - { AV_PIX_FMT_PAL8, 8 }, - // FIXME swscale does not support 16 bit in .mov, sample 16bit.mov - // http://developer.apple.com/documentation/QuickTime/QTFF/QTFFChap3/qtff3.html - { AV_PIX_FMT_RGB555BE, 16 }, - { AV_PIX_FMT_RGB24, 24 }, - { AV_PIX_FMT_ARGB, 32 }, - { AV_PIX_FMT_MONOWHITE,33 }, - { AV_PIX_FMT_NONE, 0 }, -}; - -enum AVPixelFormat avpriv_find_pix_fmt(const PixelFormatTag *tags, - unsigned int fourcc) -{ - while (tags->pix_fmt >= 0) { - if (tags->fourcc == fourcc) - return tags->pix_fmt; - tags++; - } - return AV_PIX_FMT_NONE; -} - #if LIBAVCODEC_VERSION_MAJOR < 55 enum AVPixelFormat ff_find_pix_fmt(const PixelFormatTag *tags, unsigned int fourcc) { @@ -105,17 +74,19 @@ static av_cold int raw_init_decoder(AVCodecContext *avctx) RawVideoContext *context = avctx->priv_data; const AVPixFmtDescriptor *desc; + ff_dsputil_init(&context->dsp, avctx); + if ( avctx->codec_tag == MKTAG('r','a','w',' ') || avctx->codec_tag == MKTAG('N','O','1','6')) - avctx->pix_fmt = avpriv_find_pix_fmt(pix_fmt_bps_mov, + avctx->pix_fmt = avpriv_find_pix_fmt(avpriv_pix_fmt_bps_mov, avctx->bits_per_coded_sample); else if (avctx->codec_tag == MKTAG('W', 'R', 'A', 'W')) - avctx->pix_fmt = avpriv_find_pix_fmt(pix_fmt_bps_avi, + avctx->pix_fmt = avpriv_find_pix_fmt(avpriv_pix_fmt_bps_avi, avctx->bits_per_coded_sample); - else if (avctx->codec_tag) + else if (avctx->codec_tag && (avctx->codec_tag & 0xFFFFFF) != MKTAG('B','I','T', 0)) avctx->pix_fmt = avpriv_find_pix_fmt(ff_raw_pix_fmt_tags, avctx->codec_tag); else if (avctx->pix_fmt == AV_PIX_FMT_NONE && avctx->bits_per_coded_sample) - avctx->pix_fmt = avpriv_find_pix_fmt(pix_fmt_bps_avi, + avctx->pix_fmt = avpriv_find_pix_fmt(avpriv_pix_fmt_bps_avi, avctx->bits_per_coded_sample); desc = av_pix_fmt_desc_get(avctx->pix_fmt); @@ -142,6 +113,7 @@ static av_cold int raw_init_decoder(AVCodecContext *avctx) FFALIGN(avctx->width, 16), avctx->height); } else { + context->is_lt_16bpp = av_get_bits_per_pixel(desc) == 16 && avctx->bits_per_coded_sample && avctx->bits_per_coded_sample < 16; context->frame_size = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height); } @@ -166,6 +138,34 @@ static void flip(AVCodecContext *avctx, AVPicture *picture) picture->linesize[0] *= -1; } +/* + * Scale sample to 16-bit resolution + */ +#define SCALE16(x, bits) (((x) << (16 - (bits))) | ((x) >> (2 * (bits) - 16))) + +/** + * Scale buffer to 16 bits per coded sample resolution + */ +#define MKSCALE16(name, r16, w16) \ +static void name(AVCodecContext *avctx, uint8_t * dst, const uint8_t *buf, int buf_size, int packed) \ +{ \ + int i; \ + if (!packed) { \ + for (i = 0; i + 1 < buf_size; i += 2) \ + w16(dst + i, SCALE16(r16(buf + i), avctx->bits_per_coded_sample)); \ + } else { \ + GetBitContext gb; \ + init_get_bits(&gb, buf, buf_size * 8); \ + for (i = 0; i < avctx->width * avctx->height; i++) { \ + int sample = get_bits(&gb, avctx->bits_per_coded_sample); \ + w16(dst + i*2, SCALE16(sample, avctx->bits_per_coded_sample)); \ + } \ + } \ +} + +MKSCALE16(scale16be, AV_RB16, AV_WB16) +MKSCALE16(scale16le, AV_RL16, AV_WL16) + static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { @@ -175,15 +175,18 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame, int buf_size = avpkt->size; int linesize_align = 4; int res, len; - int need_copy = !avpkt->buf || context->is_2_4_bpp || context->is_yuv2; + int need_copy = !avpkt->buf || context->is_2_4_bpp || context->is_yuv2 || context->is_lt_16bpp; AVFrame *frame = data; AVPicture *picture = data; frame->pict_type = AV_PICTURE_TYPE_I; frame->key_frame = 1; - frame->reordered_opaque = avctx->reordered_opaque; - frame->pkt_pts = avctx->internal->pkt->pts; + + res = ff_decode_frame_props(avctx, frame); + if (res < 0) + return res; + av_frame_set_pkt_pos (frame, avctx->internal->pkt->pos); av_frame_set_pkt_duration(frame, avctx->internal->pkt->duration); @@ -224,6 +227,30 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame, linesize_align = 16; } buf = dst; + } else if (context->is_lt_16bpp) { + uint8_t *dst = frame->buf[0]->data; + int packed = (avctx->codec_tag & 0xFFFFFF) == MKTAG('B','I','T', 0); + int swap = avctx->codec_tag >> 24; + + if (packed && swap) { + av_fast_padded_malloc(&context->bitstream_buf, &context->bitstream_buf_size, buf_size); + if (!context->bitstream_buf) + return AVERROR(ENOMEM); + if (swap == 16) + context->dsp.bswap16_buf(context->bitstream_buf, (const uint16_t*)buf, buf_size / 2); + else if (swap == 32) + context->dsp.bswap_buf(context->bitstream_buf, (const uint32_t*)buf, buf_size / 4); + else + return AVERROR_INVALIDDATA; + buf = context->bitstream_buf; + } + + if (desc->flags & AV_PIX_FMT_FLAG_BE) + scale16be(avctx, dst, buf, buf_size, packed); + else + scale16le(avctx, dst, buf, buf_size, packed); + + buf = dst; } else if (need_copy) { memcpy(frame->buf[0]->data, buf, buf_size); buf = frame->buf[0]->data; @@ -234,7 +261,7 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame, buf += buf_size - context->frame_size; len = context->frame_size - (avctx->pix_fmt==AV_PIX_FMT_PAL8 ? AVPALETTE_SIZE : 0); - if (buf_size < len) { + if (buf_size < len && (avctx->codec_tag & 0xFFFFFF) != MKTAG('B','I','T', 0)) { av_log(avctx, AV_LOG_ERROR, "Invalid buffer size, packet size %d < expected frame_size %d\n", buf_size, len); av_buffer_unref(&frame->buf[0]); return AVERROR(EINVAL); @@ -319,16 +346,6 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame, line += picture->linesize[0]; } } - if (avctx->codec_tag == AV_RL32("YVYU") && - avctx->pix_fmt == AV_PIX_FMT_YUYV422) { - int x, y; - uint8_t *line = picture->data[0]; - for(y = 0; y < avctx->height; y++) { - for(x = 0; x < avctx->width - 1; x += 2) - FFSWAP(uint8_t, line[2*x + 1], line[2*x + 3]); - line += picture->linesize[0]; - } - } if (avctx->field_order > AV_FIELD_PROGRESSIVE) { /* we have interlaced material flagged in container */ frame->interlaced_frame = 1; |