rawdec: support AVRn 1:1 raw interlaced mode
Fixes Ticket971 Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
e35c0ee05c
commit
0de4918f32
@ -39,6 +39,7 @@ 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;
|
||||||
@ -130,6 +131,17 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,23 +185,41 @@ 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;
|
||||||
buf_size = context->length - AVPALETTE_SIZE;
|
if(avctx->pix_fmt == PIX_FMT_PAL8){
|
||||||
if (avctx->bits_per_coded_sample == 4){
|
buf_size = context->length - AVPALETTE_SIZE;
|
||||||
for(i=0; 2*i+1 < buf_size && i<avpkt->size; i++){
|
if (avctx->bits_per_coded_sample == 4){
|
||||||
dst[2*i+0]= buf[i]>>4;
|
for(i=0; 2*i+1 < buf_size && i<avpkt->size; i++){
|
||||||
dst[2*i+1]= buf[i]&15;
|
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;
|
||||||
}
|
}
|
||||||
linesize_align = 8;
|
} else if(context->interlace && avctx->pix_fmt == PIX_FMT_UYVY422) {
|
||||||
} else {
|
int x, y;
|
||||||
av_assert0(avctx->bits_per_coded_sample == 2);
|
int true_height = buf_size / (2*avctx->width);
|
||||||
for(i=0; 4*i+3 < buf_size && i<avpkt->size; i++){
|
int tff = !!context->tff;
|
||||||
dst[4*i+0]= buf[i]>>6;
|
av_assert0(avctx->height * avctx->width * 2 == context->length);
|
||||||
dst[4*i+1]= buf[i]>>4&3;
|
if (buf_size < context->length) {
|
||||||
dst[4*i+2]= buf[i]>>2&3;
|
av_log(avctx, AV_LOG_ERROR, "Invalid buffer size, packet size %d < context length %d\n", buf_size, context->length);
|
||||||
dst[4*i+3]= buf[i] &3;
|
return AVERROR(EINVAL);
|
||||||
}
|
}
|
||||||
linesize_align = 16;
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user