Mercurial > libavcodec.hg
annotate rawdec.c @ 10061:09f2db2d7c90 libavcodec
Fix bug caused by difference in stride and picture width.
When a frame is allocated using libschroedinger routines, the frame data size
does not match the actual frame size if the width is not a multiple of 16. So
we cannot do a straightforward memcpy of the frame returned by libschroedinger
into the FFmpeg picture as the stride differs from the width.
Fix this bug by allocating for the libschroedinger frame with the dimensions
in AVCodecContext within libavcodec and passing the frame to libschroedinger.
patch by Anuradha Suraparaju, anuradha rd.bbc.co uk
| author | diego |
|---|---|
| date | Sat, 15 Aug 2009 11:59:53 +0000 |
| parents | 45d331133468 |
| children | 5198794511a4 |
| rev | line source |
|---|---|
| 5264 | 1 /* |
| 2 * Raw Video Decoder | |
|
8629
04423b2f6e0b
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
8023
diff
changeset
|
3 * Copyright (c) 2001 Fabrice Bellard |
| 5264 | 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 /** | |
|
8718
e9d9d946f213
Use full internal pathname in doxygen @file directives.
diego
parents:
8629
diff
changeset
|
23 * @file libavcodec/rawdec.c |
| 5264 | 24 * Raw Video Decoder |
| 25 */ | |
| 26 | |
| 27 #include "avcodec.h" | |
| 28 #include "raw.h" | |
| 9335 | 29 #include "libavutil/intreadwrite.h" |
| 5264 | 30 |
| 31 typedef struct RawVideoContext { | |
| 32 unsigned char * buffer; /* block of memory for holding one frame */ | |
| 33 int length; /* number of bytes in buffer */ | |
|
8993
80720c5427a0
Fix raw rgb/bgr vertical flip in avi based on info from http://www.fourcc.org/fccbihgt.php.
michael
parents:
8718
diff
changeset
|
34 int flip; |
| 5264 | 35 AVFrame pic; ///< AVCodecContext.coded_frame |
| 36 } RawVideoContext; | |
| 37 | |
| 38 static const PixelFormatTag pixelFormatBpsAVI[] = { | |
| 5419 | 39 { PIX_FMT_PAL8, 4 }, |
| 5264 | 40 { PIX_FMT_PAL8, 8 }, |
| 41 { PIX_FMT_RGB555, 15 }, | |
| 42 { PIX_FMT_RGB555, 16 }, | |
| 43 { PIX_FMT_BGR24, 24 }, | |
| 44 { PIX_FMT_RGB32, 32 }, | |
|
8023
76f6a08c9fe6
Fix some icc warnings by using enum PixelFormat instead of int where appropriate.
cehoyos
parents:
7823
diff
changeset
|
45 { PIX_FMT_NONE, 0 }, |
| 5264 | 46 }; |
| 47 | |
| 48 static const PixelFormatTag pixelFormatBpsMOV[] = { | |
| 6423 | 49 { PIX_FMT_PAL8, 4 }, |
| 5264 | 50 { PIX_FMT_PAL8, 8 }, |
| 9620 | 51 // FIXME swscale does not support 16 bit in .mov, sample 16bit.mov |
| 52 // http://developer.apple.com/documentation/QuickTime/QTFF/QTFFChap3/qtff3.html | |
| 5264 | 53 { PIX_FMT_BGR555, 16 }, |
| 54 { PIX_FMT_RGB24, 24 }, | |
| 55 { PIX_FMT_BGR32_1, 32 }, | |
|
8023
76f6a08c9fe6
Fix some icc warnings by using enum PixelFormat instead of int where appropriate.
cehoyos
parents:
7823
diff
changeset
|
56 { PIX_FMT_NONE, 0 }, |
| 5264 | 57 }; |
| 58 | |
|
8023
76f6a08c9fe6
Fix some icc warnings by using enum PixelFormat instead of int where appropriate.
cehoyos
parents:
7823
diff
changeset
|
59 static enum PixelFormat findPixelFormat(const PixelFormatTag *tags, unsigned int fourcc) |
| 5264 | 60 { |
| 61 while (tags->pix_fmt >= 0) { | |
| 62 if (tags->fourcc == fourcc) | |
| 63 return tags->pix_fmt; | |
| 64 tags++; | |
| 65 } | |
| 66 return PIX_FMT_YUV420P; | |
| 67 } | |
| 68 | |
|
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6424
diff
changeset
|
69 static av_cold int raw_init_decoder(AVCodecContext *avctx) |
| 5264 | 70 { |
| 71 RawVideoContext *context = avctx->priv_data; | |
| 72 | |
| 73 if (avctx->codec_tag == MKTAG('r','a','w',' ')) | |
|
7823
4525dcd81357
Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents:
7040
diff
changeset
|
74 avctx->pix_fmt = findPixelFormat(pixelFormatBpsMOV, avctx->bits_per_coded_sample); |
| 5264 | 75 else if (avctx->codec_tag) |
| 76 avctx->pix_fmt = findPixelFormat(ff_raw_pixelFormatTags, avctx->codec_tag); | |
|
7823
4525dcd81357
Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents:
7040
diff
changeset
|
77 else if (avctx->bits_per_coded_sample) |
|
4525dcd81357
Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents:
7040
diff
changeset
|
78 avctx->pix_fmt = findPixelFormat(pixelFormatBpsAVI, avctx->bits_per_coded_sample); |
| 5264 | 79 |
| 80 context->length = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height); | |
| 81 context->buffer = av_malloc(context->length); | |
| 82 context->pic.pict_type = FF_I_TYPE; | |
| 83 context->pic.key_frame = 1; | |
| 84 | |
| 85 avctx->coded_frame= &context->pic; | |
| 86 | |
| 87 if (!context->buffer) | |
| 88 return -1; | |
| 89 | |
|
9845
45d331133468
Add new FOURCC (0x0003) for raw DIB video, set flip flag accordingly.
darkshikari
parents:
9712
diff
changeset
|
90 if((avctx->extradata_size >= 9 && !memcmp(avctx->extradata + avctx->extradata_size - 9, "BottomUp", 9)) || |
|
45d331133468
Add new FOURCC (0x0003) for raw DIB video, set flip flag accordingly.
darkshikari
parents:
9712
diff
changeset
|
91 avctx->codec_tag == MKTAG( 3 , 0 , 0 , 0 )) |
|
8993
80720c5427a0
Fix raw rgb/bgr vertical flip in avi based on info from http://www.fourcc.org/fccbihgt.php.
michael
parents:
8718
diff
changeset
|
92 context->flip=1; |
|
80720c5427a0
Fix raw rgb/bgr vertical flip in avi based on info from http://www.fourcc.org/fccbihgt.php.
michael
parents:
8718
diff
changeset
|
93 |
| 5264 | 94 return 0; |
| 95 } | |
| 96 | |
| 97 static void flip(AVCodecContext *avctx, AVPicture * picture){ | |
| 8995 | 98 picture->data[0] += picture->linesize[0] * (avctx->height-1); |
| 99 picture->linesize[0] *= -1; | |
| 5264 | 100 } |
| 101 | |
| 102 static int raw_decode(AVCodecContext *avctx, | |
| 103 void *data, int *data_size, | |
|
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
9335
diff
changeset
|
104 AVPacket *avpkt) |
| 5264 | 105 { |
|
9355
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
9335
diff
changeset
|
106 const uint8_t *buf = avpkt->data; |
|
54bc8a2727b0
Implement avcodec_decode_video2(), _audio3() and _subtitle2() which takes an
rbultje
parents:
9335
diff
changeset
|
107 int buf_size = avpkt->size; |
| 5264 | 108 RawVideoContext *context = avctx->priv_data; |
| 109 | |
| 110 AVFrame * frame = (AVFrame *) data; | |
| 111 AVPicture * picture = (AVPicture *) data; | |
| 112 | |
| 113 frame->interlaced_frame = avctx->coded_frame->interlaced_frame; | |
| 114 frame->top_field_first = avctx->coded_frame->top_field_first; | |
| 115 | |
| 6423 | 116 //4bpp raw in avi and mov (yes this is ugly ...) |
|
7823
4525dcd81357
Bump Major version, this commit is almost just renaming bits_per_sample to
michael
parents:
7040
diff
changeset
|
117 if(avctx->bits_per_coded_sample == 4 && avctx->pix_fmt==PIX_FMT_PAL8 && |
| 6424 | 118 (!avctx->codec_tag || avctx->codec_tag == MKTAG('r','a','w',' '))){ |
| 5419 | 119 int i; |
| 120 for(i=256*2; i+1 < context->length>>1; i++){ | |
| 121 context->buffer[2*i+0]= buf[i-256*2]>>4; | |
| 122 context->buffer[2*i+1]= buf[i-256*2]&15; | |
| 123 } | |
| 124 buf= context->buffer + 256*4; | |
| 125 buf_size= context->length - 256*4; | |
| 126 } | |
| 127 | |
| 5264 | 128 if(buf_size < context->length - (avctx->pix_fmt==PIX_FMT_PAL8 ? 256*4 : 0)) |
| 129 return -1; | |
| 130 | |
| 131 avpicture_fill(picture, buf, avctx->pix_fmt, avctx->width, avctx->height); | |
| 132 if(avctx->pix_fmt==PIX_FMT_PAL8 && buf_size < context->length){ | |
| 133 frame->data[1]= context->buffer; | |
| 134 } | |
| 135 if (avctx->palctrl && avctx->palctrl->palette_changed) { | |
| 136 memcpy(frame->data[1], avctx->palctrl->palette, AVPALETTE_SIZE); | |
| 137 avctx->palctrl->palette_changed = 0; | |
| 138 } | |
| 139 | |
|
8993
80720c5427a0
Fix raw rgb/bgr vertical flip in avi based on info from http://www.fourcc.org/fccbihgt.php.
michael
parents:
8718
diff
changeset
|
140 if(context->flip) |
| 8995 | 141 flip(avctx, picture); |
| 5264 | 142 |
| 9712 | 143 if ( avctx->codec_tag == MKTAG('Y', 'V', '1', '2') |
| 144 || avctx->codec_tag == MKTAG('Y', 'V', 'U', '9')) | |
| 5264 | 145 { |
| 146 // swap fields | |
| 147 unsigned char *tmp = picture->data[1]; | |
| 148 picture->data[1] = picture->data[2]; | |
| 149 picture->data[2] = tmp; | |
| 150 } | |
| 151 | |
| 9335 | 152 if(avctx->codec_tag == AV_RL32("yuv2") && |
| 153 avctx->pix_fmt == PIX_FMT_YUYV422) { | |
| 154 int x, y; | |
| 155 uint8_t *line = picture->data[0]; | |
| 156 for(y = 0; y < avctx->height; y++) { | |
| 157 for(x = 0; x < avctx->width; x++) | |
| 158 line[2*x + 1] ^= 0x80; | |
| 159 line += picture->linesize[0]; | |
| 160 } | |
| 161 } | |
| 162 | |
| 5264 | 163 *data_size = sizeof(AVPicture); |
| 164 return buf_size; | |
| 165 } | |
| 166 | |
|
6517
48759bfbd073
Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents:
6424
diff
changeset
|
167 static av_cold int raw_close_decoder(AVCodecContext *avctx) |
| 5264 | 168 { |
| 169 RawVideoContext *context = avctx->priv_data; | |
| 170 | |
| 171 av_freep(&context->buffer); | |
| 172 return 0; | |
| 173 } | |
| 174 | |
| 175 AVCodec rawvideo_decoder = { | |
| 176 "rawvideo", | |
| 177 CODEC_TYPE_VIDEO, | |
| 178 CODEC_ID_RAWVIDEO, | |
| 179 sizeof(RawVideoContext), | |
| 180 raw_init_decoder, | |
| 181 NULL, | |
| 182 raw_close_decoder, | |
| 183 raw_decode, | |
|
7040
e943e1409077
Make AVCodec long_names definition conditional depending on CONFIG_SMALL.
stefano
parents:
6712
diff
changeset
|
184 .long_name = NULL_IF_CONFIG_SMALL("raw video"), |
| 5264 | 185 }; |
