summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2012-08-20 02:19:37 +0200
committerMichael Niedermayer <michaelni@gmx.at>2012-08-20 02:46:09 +0200
commitba2cf854d03ac8f563af5f71dfba27f7bd857a06 (patch)
tree3972f45701fc12f25821195b429a01a51073a3db /libavcodec
parenta93c221ccd7a036de052e79659fe5b082f586279 (diff)
lavc: move AVRn to a seperate decoder.
The special cases in demuxers and decoders are a mess otherwise (and more would be needed to support it fully) Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/Makefile1
-rw-r--r--libavcodec/allcodecs.c1
-rw-r--r--libavcodec/avcodec.h1
-rw-r--r--libavcodec/avrndec.c129
-rw-r--r--libavcodec/codec_desc.c6
-rw-r--r--libavcodec/rawdec.c60
6 files changed, 153 insertions, 45 deletions
diff --git a/libavcodec/Makefile b/libavcodec/Makefile
index 576ec5f005..e4113da808 100644
--- a/libavcodec/Makefile
+++ b/libavcodec/Makefile
@@ -112,6 +112,7 @@ OBJS-$(CONFIG_ATRAC1_DECODER) += atrac1.o atrac.o
OBJS-$(CONFIG_ATRAC3_DECODER) += atrac3.o atrac.o
OBJS-$(CONFIG_AURA_DECODER) += cyuv.o
OBJS-$(CONFIG_AURA2_DECODER) += aura.o
+OBJS-$(CONFIG_AVRP_DECODER) += avrndec.o
OBJS-$(CONFIG_AVRP_DECODER) += r210dec.o
OBJS-$(CONFIG_AVRP_ENCODER) += r210enc.o
OBJS-$(CONFIG_AVS_DECODER) += avs.o
diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c
index 4a247c4a67..00f44a57a6 100644
--- a/libavcodec/allcodecs.c
+++ b/libavcodec/allcodecs.c
@@ -81,6 +81,7 @@ void avcodec_register_all(void)
REGISTER_DECODER (AURA, aura);
REGISTER_DECODER (AURA2, aura2);
REGISTER_ENCDEC (AVRP, avrp);
+ REGISTER_DECODER (AVRN, avrn);
REGISTER_DECODER (AVS, avs);
REGISTER_ENCDEC (AVUI, avui);
REGISTER_ENCDEC (AYUV, ayuv);
diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h
index 1115caf23d..c3cde347d3 100644
--- a/libavcodec/avcodec.h
+++ b/libavcodec/avcodec.h
@@ -276,6 +276,7 @@ enum AVCodecID {
AV_CODEC_ID_YUV4 = MKBETAG('Y','U','V','4'),
AV_CODEC_ID_SANM = MKBETAG('S','A','N','M'),
AV_CODEC_ID_PAF_VIDEO = MKBETAG('P','A','F','V'),
+ AV_CODEC_ID_AVRN = MKBETAG('A','V','R','n'),
/* various PCM "codecs" */
AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
diff --git a/libavcodec/avrndec.c b/libavcodec/avrndec.c
new file mode 100644
index 0000000000..b173c6dcf4
--- /dev/null
+++ b/libavcodec/avrndec.c
@@ -0,0 +1,129 @@
+/*
+ * AVRn decoder
+ * Copyright (c) 2012 Michael Niedermayer
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "avcodec.h"
+#include "mjpeg.h"
+#include "mjpegdec.h"
+
+typedef struct {
+ MJpegDecodeContext mjpeg_ctx;
+ AVFrame frame;
+ int is_mjpeg;
+ int interlace; //FIXME use frame.interlaced_frame
+ int tff;
+} AVRnContext;
+
+static av_cold int init(AVCodecContext *avctx)
+{
+ AVRnContext *a = avctx->priv_data;
+
+ // Support "Resolution 1:1" for Avid AVI Codec
+ a->is_mjpeg = avctx->extradata_size < 31 || memcmp(&avctx->extradata[28], "1:1", 3);
+
+ if(a->is_mjpeg)
+ return ff_mjpeg_decode_init(avctx);
+
+ if(avctx->width <= 0 || avctx->height <= 0)
+ return -1;
+
+ avcodec_get_frame_defaults(&a->frame);
+ avctx->pix_fmt = PIX_FMT_UYVY422;
+
+ if(avctx->extradata_size >= 9 && avctx->extradata[4]+28 < avctx->extradata_size) {
+ int ndx = avctx->extradata[4] + 4;
+ a->interlace = !memcmp(avctx->extradata + ndx, "1:1(", 4);
+ if(a->interlace) {
+ a->tff = avctx->extradata[ndx + 24] == 1;
+ }
+ }
+
+ return 0;
+}
+
+static av_cold void end(AVCodecContext *avctx)
+{
+ AVRnContext *a = avctx->priv_data;
+ AVFrame *p = &a->frame;
+
+ if(p->data[0])
+ avctx->release_buffer(avctx, p);
+
+ if(a->is_mjpeg)
+ ff_mjpeg_decode_end(avctx);
+}
+
+static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
+{
+ AVRnContext *a = avctx->priv_data;
+ AVFrame *p = &a->frame;
+ const uint8_t *buf = avpkt->data;
+ int buf_size = avpkt->size;
+ int y;
+
+ if(a->is_mjpeg)
+ return ff_mjpeg_decode_frame(avctx, data, data_size, avpkt);
+
+ if(p->data[0])
+ avctx->release_buffer(avctx, p);
+
+ if(buf_size < 2*avctx->width * avctx->height) {
+ av_log(avctx, AV_LOG_ERROR, "packet too small\n");
+ return AVERROR_INVALIDDATA;
+ }
+
+ if(avctx->get_buffer(avctx, p) < 0){
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return -1;
+ }
+ p->pict_type= AV_PICTURE_TYPE_I;
+ p->key_frame= 1;
+
+ if(a->interlace) {
+ int true_height = buf_size / (2*avctx->width);
+ buf += (true_height - avctx->height)*avctx->width;
+ for(y = 0; y < avctx->height-1; y+=2) {
+ memcpy(p->data[0] + (y+ a->tff)*p->linesize[0], buf , 2*avctx->width);
+ memcpy(p->data[0] + (y+!a->tff)*p->linesize[0], buf + avctx->width*true_height+4, 2*avctx->width);
+ buf += 2*avctx->width;
+ }
+ } else {
+ for(y = 0; y < avctx->height; y++) {
+ memcpy(p->data[0] + y*p->linesize[0], buf, 2*avctx->width);
+ buf += 2*avctx->width;
+ }
+ }
+
+ *(AVFrame*)data = a->frame;
+ *data_size = sizeof(AVFrame);
+ return buf_size;
+}
+
+AVCodec ff_avrn_decoder = {
+ .name = "AVRn",
+ .type = AVMEDIA_TYPE_VIDEO,
+ .id = AV_CODEC_ID_AVRN,
+ .priv_data_size = sizeof(AVRnContext),
+ .init = init,
+ .close = end,
+ .decode = decode_frame,
+ .long_name = NULL_IF_CONFIG_SMALL("AVRn"),
+};
+
diff --git a/libavcodec/codec_desc.c b/libavcodec/codec_desc.c
index 607eaab84a..68e07bbd41 100644
--- a/libavcodec/codec_desc.c
+++ b/libavcodec/codec_desc.c
@@ -1175,6 +1175,12 @@ static const AVCodecDescriptor codec_descriptors[] = {
.name = "paf_video",
.long_name = NULL_IF_CONFIG_SMALL("Amazing Studio Packed Animation File Video"),
},
+ {
+ .id = AV_CODEC_ID_AVRN,
+ .type = AVMEDIA_TYPE_VIDEO,
+ .name = "AVRn",
+ .long_name = NULL_IF_CONFIG_SMALL("AVRn"),
+ },
/* various PCM "codecs" */
{
diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c
index 9e2fbaafbe..9920e7875e 100644
--- a/libavcodec/rawdec.c
+++ b/libavcodec/rawdec.c
@@ -39,7 +39,6 @@ typedef struct RawVideoContext {
unsigned char * buffer; /* block of memory for holding one frame */
int length; /* number of bytes in buffer */
int flip;
- int interlace;
AVFrame pic; ///< AVCodecContext.coded_frame
int tff;
} RawVideoContext;
@@ -131,17 +130,6 @@ static av_cold int raw_init_decoder(AVCodecContext *avctx)
avctx->codec_tag == MKTAG(3, 0, 0, 0) || avctx->codec_tag == MKTAG('W','R','A','W'))
context->flip=1;
- if(avctx->extradata_size >= 9 && avctx->extradata[4]+28 < avctx->extradata_size && !context->buffer && avctx->pix_fmt == PIX_FMT_UYVY422) {
- int ndx = avctx->extradata[4] + 4;
- context->interlace = !memcmp(avctx->extradata + ndx, "1:1(", 4);
- if(context->interlace) {
- context->buffer = av_malloc(context->length);
- if (!context->buffer)
- return AVERROR(ENOMEM);
- context->tff = avctx->extradata[ndx + 24] == 1;
- }
- }
-
return 0;
}
@@ -185,41 +173,23 @@ static int raw_decode(AVCodecContext *avctx,
if (context->buffer) {
int i;
uint8_t *dst = context->buffer;
- if(avctx->pix_fmt == PIX_FMT_PAL8){
- buf_size = context->length - AVPALETTE_SIZE;
- if (avctx->bits_per_coded_sample == 4){
- for(i=0; 2*i+1 < buf_size && i<avpkt->size; i++){
- dst[2*i+0]= buf[i]>>4;
- dst[2*i+1]= buf[i]&15;
- }
- linesize_align = 8;
- } else {
- av_assert0(avctx->bits_per_coded_sample == 2);
- for(i=0; 4*i+3 < buf_size && i<avpkt->size; i++){
- dst[4*i+0]= buf[i]>>6;
- dst[4*i+1]= buf[i]>>4&3;
- dst[4*i+2]= buf[i]>>2&3;
- dst[4*i+3]= buf[i] &3;
- }
- linesize_align = 16;
+ buf_size = context->length - AVPALETTE_SIZE;
+ if (avctx->bits_per_coded_sample == 4){
+ for(i=0; 2*i+1 < buf_size && i<avpkt->size; i++){
+ dst[2*i+0]= buf[i]>>4;
+ dst[2*i+1]= buf[i]&15;
}
- } else if(context->interlace && avctx->pix_fmt == PIX_FMT_UYVY422) {
- int x, y;
- int true_height = buf_size / (2*avctx->width);
- int tff = !!context->tff;
- av_assert0(avctx->height * avctx->width * 2 == context->length);
- if (buf_size < context->length) {
- av_log(avctx, AV_LOG_ERROR, "Invalid buffer size, packet size %d < context length %d\n", buf_size, context->length);
- return AVERROR(EINVAL);
+ linesize_align = 8;
+ } else {
+ av_assert0(avctx->bits_per_coded_sample == 2);
+ for(i=0; 4*i+3 < buf_size && i<avpkt->size; i++){
+ dst[4*i+0]= buf[i]>>6;
+ dst[4*i+1]= buf[i]>>4&3;
+ dst[4*i+2]= buf[i]>>2&3;
+ dst[4*i+3]= buf[i] &3;
}
- buf += (true_height - avctx->height)*avctx->width;
- for(y = 0; y < avctx->height-1; y+=2) {
- memcpy(dst + (y+ tff)*2*avctx->width, buf , 2*avctx->width);
- memcpy(dst + (y+!tff)*2*avctx->width, buf + avctx->width*true_height+4, 2*avctx->width);
- buf += 2*avctx->width;
- }
- }else
- av_assert0(0);
+ linesize_align = 16;
+ }
buf= dst;
}