Subversion Repositories Kolibri OS

Rev

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.     AVCodecContext *mjpeg_avctx;
  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.         AVCodec *codec = avcodec_find_decoder(AV_CODEC_ID_MJPEG);
  50.         AVDictionary *thread_opt = NULL;
  51.         if (!codec) {
  52.             av_log(avctx, AV_LOG_ERROR, "MJPEG codec not found\n");
  53.             return AVERROR_DECODER_NOT_FOUND;
  54.         }
  55.  
  56.         a->mjpeg_avctx = avcodec_alloc_context3(codec);
  57.  
  58.         av_dict_set(&thread_opt, "threads", "1", 0); // Is this needed ?
  59.         a->mjpeg_avctx->refcounted_frames = 1;
  60.         a->mjpeg_avctx->flags = avctx->flags;
  61.         a->mjpeg_avctx->idct_algo = avctx->idct_algo;
  62.         a->mjpeg_avctx->lowres = avctx->lowres;
  63.         a->mjpeg_avctx->width = avctx->width;
  64.         a->mjpeg_avctx->height = avctx->height;
  65.  
  66.         if ((ret = ff_codec_open2_recursive(a->mjpeg_avctx, codec, &thread_opt)) < 0) {
  67.             av_log(avctx, AV_LOG_ERROR, "MJPEG codec failed to open\n");
  68.         }
  69.         av_dict_free(&thread_opt);
  70.  
  71.         return ret;
  72.     }
  73.  
  74.     if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0)
  75.         return ret;
  76.  
  77.     avctx->pix_fmt = AV_PIX_FMT_UYVY422;
  78.  
  79.     if(avctx->extradata_size >= 9 && avctx->extradata[4]+28 < avctx->extradata_size) {
  80.         int ndx = avctx->extradata[4] + 4;
  81.         a->interlace = !memcmp(avctx->extradata + ndx, "1:1(", 4);
  82.         if(a->interlace) {
  83.             a->tff = avctx->extradata[ndx + 24] == 1;
  84.         }
  85.     }
  86.  
  87.     return 0;
  88. }
  89.  
  90. static av_cold int end(AVCodecContext *avctx)
  91. {
  92.     AVRnContext *a = avctx->priv_data;
  93.  
  94.     avcodec_close(a->mjpeg_avctx);
  95.     av_freep(&a->mjpeg_avctx);
  96.  
  97.     return 0;
  98. }
  99.  
  100. static int decode_frame(AVCodecContext *avctx, void *data,
  101.                         int *got_frame, AVPacket *avpkt)
  102. {
  103.     AVRnContext *a = avctx->priv_data;
  104.     AVFrame *p = data;
  105.     const uint8_t *buf = avpkt->data;
  106.     int buf_size       = avpkt->size;
  107.     int y, ret, true_height;
  108.  
  109.     if(a->is_mjpeg) {
  110.         ret = avcodec_decode_video2(a->mjpeg_avctx, data, got_frame, avpkt);
  111.  
  112.         if (ret >= 0 && *got_frame && avctx->width <= p->width && avctx->height <= p->height) {
  113.             int shift = p->height - avctx->height;
  114.             int subsample_h, subsample_v;
  115.  
  116.             av_pix_fmt_get_chroma_sub_sample(p->format, &subsample_h, &subsample_v);
  117.  
  118.             p->data[0] += p->linesize[0] * shift;
  119.             if (p->data[2]) {
  120.                 p->data[1] += p->linesize[1] * (shift>>subsample_v);
  121.                 p->data[2] += p->linesize[2] * (shift>>subsample_v);
  122.             }
  123.  
  124.             p->width  = avctx->width;
  125.             p->height = avctx->height;
  126.         }
  127.         avctx->pix_fmt = a->mjpeg_avctx->pix_fmt;
  128.         return ret;
  129.     }
  130.  
  131.     true_height    = buf_size / (2*avctx->width);
  132.  
  133.     if(buf_size < 2*avctx->width * avctx->height) {
  134.         av_log(avctx, AV_LOG_ERROR, "packet too small\n");
  135.         return AVERROR_INVALIDDATA;
  136.     }
  137.  
  138.     if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
  139.         return ret;
  140.     p->pict_type= AV_PICTURE_TYPE_I;
  141.     p->key_frame= 1;
  142.  
  143.     if(a->interlace) {
  144.         buf += (true_height - avctx->height)*avctx->width;
  145.         for(y = 0; y < avctx->height-1; y+=2) {
  146.             memcpy(p->data[0] + (y+ a->tff)*p->linesize[0], buf                             , 2*avctx->width);
  147.             memcpy(p->data[0] + (y+!a->tff)*p->linesize[0], buf + avctx->width*true_height+4, 2*avctx->width);
  148.             buf += 2*avctx->width;
  149.         }
  150.     } else {
  151.         buf += (true_height - avctx->height)*avctx->width*2;
  152.         for(y = 0; y < avctx->height; y++) {
  153.             memcpy(p->data[0] + y*p->linesize[0], buf, 2*avctx->width);
  154.             buf += 2*avctx->width;
  155.         }
  156.     }
  157.  
  158.     *got_frame      = 1;
  159.     return buf_size;
  160. }
  161.  
  162. AVCodec ff_avrn_decoder = {
  163.     .name           = "avrn",
  164.     .long_name      = NULL_IF_CONFIG_SMALL("Avid AVI Codec"),
  165.     .type           = AVMEDIA_TYPE_VIDEO,
  166.     .id             = AV_CODEC_ID_AVRN,
  167.     .priv_data_size = sizeof(AVRnContext),
  168.     .init           = init,
  169.     .close          = end,
  170.     .decode         = decode_frame,
  171.     .capabilities   = AV_CODEC_CAP_DR1,
  172.     .max_lowres     = 3,
  173. };
  174.