mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
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>
This commit is contained in:
parent
a93c221ccd
commit
ba2cf854d0
@ -112,6 +112,7 @@ OBJS-$(CONFIG_ATRAC1_DECODER) += atrac1.o atrac.o
|
|||||||
OBJS-$(CONFIG_ATRAC3_DECODER) += atrac3.o atrac.o
|
OBJS-$(CONFIG_ATRAC3_DECODER) += atrac3.o atrac.o
|
||||||
OBJS-$(CONFIG_AURA_DECODER) += cyuv.o
|
OBJS-$(CONFIG_AURA_DECODER) += cyuv.o
|
||||||
OBJS-$(CONFIG_AURA2_DECODER) += aura.o
|
OBJS-$(CONFIG_AURA2_DECODER) += aura.o
|
||||||
|
OBJS-$(CONFIG_AVRP_DECODER) += avrndec.o
|
||||||
OBJS-$(CONFIG_AVRP_DECODER) += r210dec.o
|
OBJS-$(CONFIG_AVRP_DECODER) += r210dec.o
|
||||||
OBJS-$(CONFIG_AVRP_ENCODER) += r210enc.o
|
OBJS-$(CONFIG_AVRP_ENCODER) += r210enc.o
|
||||||
OBJS-$(CONFIG_AVS_DECODER) += avs.o
|
OBJS-$(CONFIG_AVS_DECODER) += avs.o
|
||||||
|
@ -81,6 +81,7 @@ void avcodec_register_all(void)
|
|||||||
REGISTER_DECODER (AURA, aura);
|
REGISTER_DECODER (AURA, aura);
|
||||||
REGISTER_DECODER (AURA2, aura2);
|
REGISTER_DECODER (AURA2, aura2);
|
||||||
REGISTER_ENCDEC (AVRP, avrp);
|
REGISTER_ENCDEC (AVRP, avrp);
|
||||||
|
REGISTER_DECODER (AVRN, avrn);
|
||||||
REGISTER_DECODER (AVS, avs);
|
REGISTER_DECODER (AVS, avs);
|
||||||
REGISTER_ENCDEC (AVUI, avui);
|
REGISTER_ENCDEC (AVUI, avui);
|
||||||
REGISTER_ENCDEC (AYUV, ayuv);
|
REGISTER_ENCDEC (AYUV, ayuv);
|
||||||
|
@ -276,6 +276,7 @@ enum AVCodecID {
|
|||||||
AV_CODEC_ID_YUV4 = MKBETAG('Y','U','V','4'),
|
AV_CODEC_ID_YUV4 = MKBETAG('Y','U','V','4'),
|
||||||
AV_CODEC_ID_SANM = MKBETAG('S','A','N','M'),
|
AV_CODEC_ID_SANM = MKBETAG('S','A','N','M'),
|
||||||
AV_CODEC_ID_PAF_VIDEO = MKBETAG('P','A','F','V'),
|
AV_CODEC_ID_PAF_VIDEO = MKBETAG('P','A','F','V'),
|
||||||
|
AV_CODEC_ID_AVRN = MKBETAG('A','V','R','n'),
|
||||||
|
|
||||||
/* various PCM "codecs" */
|
/* various PCM "codecs" */
|
||||||
AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
|
AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
|
||||||
|
129
libavcodec/avrndec.c
Normal file
129
libavcodec/avrndec.c
Normal file
@ -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"),
|
||||||
|
};
|
||||||
|
|
@ -1175,6 +1175,12 @@ static const AVCodecDescriptor codec_descriptors[] = {
|
|||||||
.name = "paf_video",
|
.name = "paf_video",
|
||||||
.long_name = NULL_IF_CONFIG_SMALL("Amazing Studio Packed Animation File 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" */
|
/* various PCM "codecs" */
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,6 @@ typedef struct RawVideoContext {
|
|||||||
unsigned char * buffer; /* block of memory for holding one frame */
|
unsigned char * buffer; /* block of memory for holding one frame */
|
||||||
int length; /* number of bytes in buffer */
|
int length; /* number of bytes in buffer */
|
||||||
int flip;
|
int flip;
|
||||||
int interlace;
|
|
||||||
AVFrame pic; ///< AVCodecContext.coded_frame
|
AVFrame pic; ///< AVCodecContext.coded_frame
|
||||||
int tff;
|
int tff;
|
||||||
} RawVideoContext;
|
} 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'))
|
avctx->codec_tag == MKTAG(3, 0, 0, 0) || avctx->codec_tag == MKTAG('W','R','A','W'))
|
||||||
context->flip=1;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,7 +173,6 @@ static int raw_decode(AVCodecContext *avctx,
|
|||||||
if (context->buffer) {
|
if (context->buffer) {
|
||||||
int i;
|
int i;
|
||||||
uint8_t *dst = context->buffer;
|
uint8_t *dst = context->buffer;
|
||||||
if(avctx->pix_fmt == PIX_FMT_PAL8){
|
|
||||||
buf_size = context->length - AVPALETTE_SIZE;
|
buf_size = context->length - AVPALETTE_SIZE;
|
||||||
if (avctx->bits_per_coded_sample == 4){
|
if (avctx->bits_per_coded_sample == 4){
|
||||||
for(i=0; 2*i+1 < buf_size && i<avpkt->size; i++){
|
for(i=0; 2*i+1 < buf_size && i<avpkt->size; i++){
|
||||||
@ -203,23 +190,6 @@ static int raw_decode(AVCodecContext *avctx,
|
|||||||
}
|
}
|
||||||
linesize_align = 16;
|
linesize_align = 16;
|
||||||
}
|
}
|
||||||
} 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);
|
|
||||||
}
|
|
||||||
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);
|
|
||||||
buf= dst;
|
buf= dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -635,11 +635,6 @@ static int avi_read_header(AVFormatContext *s)
|
|||||||
st->codec->codec_tag = tag1;
|
st->codec->codec_tag = tag1;
|
||||||
st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1);
|
st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1);
|
||||||
st->need_parsing = AVSTREAM_PARSE_HEADERS; // This is needed to get the pict type which is necessary for generating correct pts.
|
st->need_parsing = AVSTREAM_PARSE_HEADERS; // This is needed to get the pict type which is necessary for generating correct pts.
|
||||||
// Support "Resolution 1:1" for Avid AVI Codec
|
|
||||||
if(tag1 == MKTAG('A', 'V', 'R', 'n') &&
|
|
||||||
st->codec->extradata_size >= 31 &&
|
|
||||||
!memcmp(&st->codec->extradata[28], "1:1", 3))
|
|
||||||
st->codec->codec_id = AV_CODEC_ID_RAWVIDEO;
|
|
||||||
|
|
||||||
if(st->codec->codec_tag==0 && st->codec->height > 0 && st->codec->extradata_size < 1U<<30){
|
if(st->codec->codec_tag==0 && st->codec->height > 0 && st->codec->extradata_size < 1U<<30){
|
||||||
st->codec->extradata_size+= 9;
|
st->codec->extradata_size+= 9;
|
||||||
|
@ -154,7 +154,7 @@ const AVCodecTag ff_codec_bmp_tags[] = {
|
|||||||
{ AV_CODEC_ID_MJPEG, MKTAG('M', 'J', 'L', 'S') }, /* JPEG-LS custom FOURCC for avi - decoder */
|
{ AV_CODEC_ID_MJPEG, MKTAG('M', 'J', 'L', 'S') }, /* JPEG-LS custom FOURCC for avi - decoder */
|
||||||
{ AV_CODEC_ID_MJPEG, MKTAG('j', 'p', 'e', 'g') },
|
{ AV_CODEC_ID_MJPEG, MKTAG('j', 'p', 'e', 'g') },
|
||||||
{ AV_CODEC_ID_MJPEG, MKTAG('I', 'J', 'P', 'G') },
|
{ AV_CODEC_ID_MJPEG, MKTAG('I', 'J', 'P', 'G') },
|
||||||
{ AV_CODEC_ID_MJPEG, MKTAG('A', 'V', 'R', 'n') },
|
{ AV_CODEC_ID_AVRN, MKTAG('A', 'V', 'R', 'n') },
|
||||||
{ AV_CODEC_ID_MJPEG, MKTAG('A', 'C', 'D', 'V') },
|
{ AV_CODEC_ID_MJPEG, MKTAG('A', 'C', 'D', 'V') },
|
||||||
{ AV_CODEC_ID_MJPEG, MKTAG('Q', 'I', 'V', 'G') },
|
{ AV_CODEC_ID_MJPEG, MKTAG('Q', 'I', 'V', 'G') },
|
||||||
{ AV_CODEC_ID_MJPEG, MKTAG('S', 'L', 'M', 'J') }, /* SL M-JPEG */
|
{ AV_CODEC_ID_MJPEG, MKTAG('S', 'L', 'M', 'J') }, /* SL M-JPEG */
|
||||||
|
Loading…
Reference in New Issue
Block a user