Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * AVRn decoder
  3.  * Copyright (c) 2012 Michael Niedermayer
  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. #include "avcodec.h"
  23. #include "internal.h"
  24. #include "mjpeg.h"
  25. #include "mjpegdec.h"
  26. #include "libavutil/imgutils.h"
  27.  
  28. typedef struct {
  29.     MJpegDecodeContext mjpeg_ctx;
  30.     int is_mjpeg;
  31.     int interlace; //FIXME use frame.interlaced_frame
  32.     int tff;
  33. } AVRnContext;
  34.  
  35. static av_cold int init(AVCodecContext *avctx)
  36. {
  37.     AVRnContext *a = avctx->priv_data;
  38.     int ret;
  39.  
  40.     // Support "Resolution 1:1" for Avid AVI Codec
  41.     a->is_mjpeg = avctx->extradata_size < 31 || memcmp(&avctx->extradata[28], "1:1", 3);
  42.  
  43.     if(!a->is_mjpeg && avctx->lowres) {
  44.         av_log(avctx, AV_LOG_ERROR, "lowres is not possible with rawvideo\n");
  45.         return AVERROR(EINVAL);
  46.     }
  47.  
  48.     if(a->is_mjpeg)
  49.         return ff_mjpeg_decode_init(avctx);
  50.  
  51.     if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0)
  52.         return ret;
  53.  
  54.     avctx->pix_fmt = AV_PIX_FMT_UYVY422;
  55.  
  56.     if(avctx->extradata_size >= 9 && avctx->extradata[4]+28 < avctx->extradata_size) {
  57.         int ndx = avctx->extradata[4] + 4;
  58.         a->interlace = !memcmp(avctx->extradata + ndx, "1:1(", 4);
  59.         if(a->interlace) {
  60.             a->tff = avctx->extradata[ndx + 24] == 1;
  61.         }
  62.     }
  63.  
  64.     return 0;
  65. }
  66.  
  67. static av_cold int end(AVCodecContext *avctx)
  68. {
  69.     AVRnContext *a = avctx->priv_data;
  70.  
  71.     if(a->is_mjpeg)
  72.         ff_mjpeg_decode_end(avctx);
  73.  
  74.     return 0;
  75. }
  76.  
  77. static int decode_frame(AVCodecContext *avctx, void *data,
  78.                         int *got_frame, AVPacket *avpkt)
  79. {
  80.     AVRnContext *a = avctx->priv_data;
  81.     AVFrame *p = data;
  82.     const uint8_t *buf = avpkt->data;
  83.     int buf_size       = avpkt->size;
  84.     int y, ret, true_height;
  85.  
  86.     if(a->is_mjpeg)
  87.         return ff_mjpeg_decode_frame(avctx, data, got_frame, avpkt);
  88.  
  89.     true_height    = buf_size / (2*avctx->width);
  90.  
  91.     if(buf_size < 2*avctx->width * avctx->height) {
  92.         av_log(avctx, AV_LOG_ERROR, "packet too small\n");
  93.         return AVERROR_INVALIDDATA;
  94.     }
  95.  
  96.     if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
  97.         return ret;
  98.     p->pict_type= AV_PICTURE_TYPE_I;
  99.     p->key_frame= 1;
  100.  
  101.     if(a->interlace) {
  102.         buf += (true_height - avctx->height)*avctx->width;
  103.         for(y = 0; y < avctx->height-1; y+=2) {
  104.             memcpy(p->data[0] + (y+ a->tff)*p->linesize[0], buf                             , 2*avctx->width);
  105.             memcpy(p->data[0] + (y+!a->tff)*p->linesize[0], buf + avctx->width*true_height+4, 2*avctx->width);
  106.             buf += 2*avctx->width;
  107.         }
  108.     } else {
  109.         buf += (true_height - avctx->height)*avctx->width*2;
  110.         for(y = 0; y < avctx->height; y++) {
  111.             memcpy(p->data[0] + y*p->linesize[0], buf, 2*avctx->width);
  112.             buf += 2*avctx->width;
  113.         }
  114.     }
  115.  
  116.     *got_frame      = 1;
  117.     return buf_size;
  118. }
  119.  
  120. AVCodec ff_avrn_decoder = {
  121.     .name           = "avrn",
  122.     .long_name      = NULL_IF_CONFIG_SMALL("Avid AVI Codec"),
  123.     .type           = AVMEDIA_TYPE_VIDEO,
  124.     .id             = AV_CODEC_ID_AVRN,
  125.     .priv_data_size = sizeof(AVRnContext),
  126.     .init           = init,
  127.     .close          = end,
  128.     .decode         = decode_frame,
  129.     .capabilities   = CODEC_CAP_DR1,
  130.     .max_lowres     = 3,
  131. };
  132.