Libav
rawdec.c
Go to the documentation of this file.
1 /*
2  * Raw Video Decoder
3  * Copyright (c) 2001 Fabrice Bellard
4  *
5  * This file is part of Libav.
6  *
7  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
27 #include "avcodec.h"
28 #include "internal.h"
29 #include "raw.h"
30 #include "libavutil/buffer.h"
31 #include "libavutil/common.h"
32 #include "libavutil/intreadwrite.h"
33 #include "libavutil/imgutils.h"
34 
35 typedef struct RawVideoContext {
37  int frame_size; /* size of the frame in bytes */
38  int flip;
39  int is_2_4_bpp; // 2 or 4 bpp raw in avi/mov
40  int is_yuv2;
42 
43 static const PixelFormatTag pix_fmt_bps_avi[] = {
44  { AV_PIX_FMT_PAL8, 4 },
45  { AV_PIX_FMT_PAL8, 8 },
46  { AV_PIX_FMT_RGB444, 12 },
47  { AV_PIX_FMT_RGB555, 15 },
48  { AV_PIX_FMT_RGB555, 16 },
49  { AV_PIX_FMT_BGR24, 24 },
50  { AV_PIX_FMT_RGB32, 32 },
51  { AV_PIX_FMT_NONE, 0 },
52 };
53 
54 static const PixelFormatTag pix_fmt_bps_mov[] = {
55  { AV_PIX_FMT_MONOWHITE, 1 },
56  { AV_PIX_FMT_PAL8, 2 },
57  { AV_PIX_FMT_PAL8, 4 },
58  { AV_PIX_FMT_PAL8, 8 },
59  // FIXME swscale does not support 16 bit in .mov, sample 16bit.mov
60  // http://developer.apple.com/documentation/QuickTime/QTFF/QTFFChap3/qtff3.html
61  { AV_PIX_FMT_RGB555BE, 16 },
62  { AV_PIX_FMT_RGB24, 24 },
63  { AV_PIX_FMT_ARGB, 32 },
64  { AV_PIX_FMT_MONOWHITE,33 },
65  { AV_PIX_FMT_NONE, 0 },
66 };
67 
68 static enum AVPixelFormat find_pix_fmt(const PixelFormatTag *tags,
69  unsigned int fourcc)
70 {
71  while (tags->pix_fmt >= 0) {
72  if (tags->fourcc == fourcc)
73  return tags->pix_fmt;
74  tags++;
75  }
76  return AV_PIX_FMT_YUV420P;
77 }
78 
80 {
81  RawVideoContext *context = avctx->priv_data;
82  const AVPixFmtDescriptor *desc;
83 
84  if (avctx->codec_tag == MKTAG('r', 'a', 'w', ' '))
85  avctx->pix_fmt = find_pix_fmt(pix_fmt_bps_mov,
86  avctx->bits_per_coded_sample);
87  else if (avctx->codec_tag == MKTAG('W', 'R', 'A', 'W'))
88  avctx->pix_fmt = find_pix_fmt(pix_fmt_bps_avi,
89  avctx->bits_per_coded_sample);
90  else if (avctx->codec_tag)
92  else if (avctx->pix_fmt == AV_PIX_FMT_NONE && avctx->bits_per_coded_sample)
93  avctx->pix_fmt = find_pix_fmt(pix_fmt_bps_avi,
94  avctx->bits_per_coded_sample);
95 
96  desc = av_pix_fmt_desc_get(avctx->pix_fmt);
97  if (!desc) {
98  av_log(avctx, AV_LOG_ERROR, "Invalid pixel format.\n");
99  return AVERROR(EINVAL);
100  }
101 
104  if (!context->palette)
105  return AVERROR(ENOMEM);
106  if (desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)
107  avpriv_set_systematic_pal2((uint32_t*)context->palette->data, avctx->pix_fmt);
108  else
109  memset(context->palette->data, 0, AVPALETTE_SIZE);
110  }
111 
112  context->frame_size = avpicture_get_size(avctx->pix_fmt, avctx->width,
113  avctx->height);
114  if ((avctx->bits_per_coded_sample == 4 || avctx->bits_per_coded_sample == 2) &&
115  avctx->pix_fmt == AV_PIX_FMT_PAL8 &&
116  (!avctx->codec_tag || avctx->codec_tag == MKTAG('r','a','w',' ')))
117  context->is_2_4_bpp = 1;
118 
119  if ((avctx->extradata_size >= 9 &&
120  !memcmp(avctx->extradata + avctx->extradata_size - 9, "BottomUp", 9)) ||
121  avctx->codec_tag == MKTAG(3, 0, 0, 0) ||
122  avctx->codec_tag == MKTAG('W','R','A','W'))
123  context->flip = 1;
124 
125  if (avctx->codec_tag == AV_RL32("yuv2") &&
126  avctx->pix_fmt == AV_PIX_FMT_YUYV422)
127  context->is_yuv2 = 1;
128 
129  return 0;
130 }
131 
132 static void flip(AVCodecContext *avctx, AVPicture *picture)
133 {
134  picture->data[0] += picture->linesize[0] * (avctx->height - 1);
135  picture->linesize[0] *= -1;
136 }
137 
138 static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame,
139  AVPacket *avpkt)
140 {
141  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt);
142  RawVideoContext *context = avctx->priv_data;
143  const uint8_t *buf = avpkt->data;
144  int buf_size = avpkt->size;
145  int need_copy = !avpkt->buf || context->is_2_4_bpp || context->is_yuv2;
146  int res;
147 
148  AVFrame *frame = data;
149  AVPicture *picture = data;
150 
151  frame->pict_type = AV_PICTURE_TYPE_I;
152  frame->key_frame = 1;
153 
154  res = ff_decode_frame_props(avctx, frame);
155  if (res < 0)
156  return res;
157 
158  if (buf_size < context->frame_size - (avctx->pix_fmt == AV_PIX_FMT_PAL8 ?
159  AVPALETTE_SIZE : 0))
160  return -1;
161 
162  if (need_copy)
163  frame->buf[0] = av_buffer_alloc(context->frame_size);
164  else
165  frame->buf[0] = av_buffer_ref(avpkt->buf);
166  if (!frame->buf[0])
167  return AVERROR(ENOMEM);
168 
169  //2bpp and 4bpp raw in avi and mov (yes this is ugly ...)
170  if (context->is_2_4_bpp) {
171  int i;
172  uint8_t *dst = frame->buf[0]->data;
173  buf_size = context->frame_size - AVPALETTE_SIZE;
174  if (avctx->bits_per_coded_sample == 4) {
175  for (i = 0; 2 * i + 1 < buf_size; i++) {
176  dst[2 * i + 0] = buf[i] >> 4;
177  dst[2 * i + 1] = buf[i] & 15;
178  }
179  } else {
180  for (i = 0; 4 * i + 3 < buf_size; i++) {
181  dst[4 * i + 0] = buf[i] >> 6;
182  dst[4 * i + 1] = buf[i] >> 4 & 3;
183  dst[4 * i + 2] = buf[i] >> 2 & 3;
184  dst[4 * i + 3] = buf[i] & 3;
185  }
186  }
187  buf = dst;
188  } else if (need_copy) {
189  memcpy(frame->buf[0]->data, buf, FFMIN(buf_size, context->frame_size));
190  buf = frame->buf[0]->data;
191  }
192 
193  if (avctx->codec_tag == MKTAG('A', 'V', '1', 'x') ||
194  avctx->codec_tag == MKTAG('A', 'V', 'u', 'p'))
195  buf += buf_size - context->frame_size;
196 
197  if ((res = avpicture_fill(picture, buf, avctx->pix_fmt,
198  avctx->width, avctx->height)) < 0)
199  return res;
200 
201  if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
203  NULL);
204 
205  if (pal) {
206  av_buffer_unref(&context->palette);
207  context->palette = av_buffer_alloc(AVPALETTE_SIZE);
208  if (!context->palette)
209  return AVERROR(ENOMEM);
210  memcpy(context->palette->data, pal, AVPALETTE_SIZE);
211  frame->palette_has_changed = 1;
212  }
213  }
214 
215  if ((avctx->pix_fmt == AV_PIX_FMT_PAL8 && buf_size < context->frame_size) ||
216  (desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL)) {
217  frame->buf[1] = av_buffer_ref(context->palette);
218  if (!frame->buf[1])
219  return AVERROR(ENOMEM);
220  frame->data[1] = frame->buf[1]->data;
221  }
222  if (avctx->pix_fmt == AV_PIX_FMT_BGR24 &&
223  ((frame->linesize[0] + 3) & ~3) * avctx->height <= buf_size)
224  frame->linesize[0] = (frame->linesize[0] + 3) & ~3;
225 
226  if (context->flip)
227  flip(avctx, picture);
228 
229  if (avctx->codec_tag == MKTAG('Y', 'V', '1', '2') ||
230  avctx->codec_tag == MKTAG('Y', 'V', '1', '6') ||
231  avctx->codec_tag == MKTAG('Y', 'V', '2', '4') ||
232  avctx->codec_tag == MKTAG('Y', 'V', 'U', '9'))
233  FFSWAP(uint8_t *, picture->data[1], picture->data[2]);
234 
235  if (avctx->codec_tag == AV_RL32("yuv2") &&
236  avctx->pix_fmt == AV_PIX_FMT_YUYV422) {
237  int x, y;
238  uint8_t *line = picture->data[0];
239  for (y = 0; y < avctx->height; y++) {
240  for (x = 0; x < avctx->width; x++)
241  line[2 * x + 1] ^= 0x80;
242  line += picture->linesize[0];
243  }
244  }
245 
246  *got_frame = 1;
247  return buf_size;
248 }
249 
251 {
252  RawVideoContext *context = avctx->priv_data;
253 
254  av_buffer_unref(&context->palette);
255  return 0;
256 }
257 
259  .name = "rawvideo",
260  .long_name = NULL_IF_CONFIG_SMALL("raw video"),
261  .type = AVMEDIA_TYPE_VIDEO,
262  .id = AV_CODEC_ID_RAWVIDEO,
263  .priv_data_size = sizeof(RawVideoContext),
266  .decode = raw_decode,
267 };
#define AV_PIX_FMT_FLAG_PAL
Pixel format has a palette in data[1], values are indexes in this palette.
Definition: pixdesc.h:112
#define AVPALETTE_SIZE
Definition: avcodec.h:3029
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it...
Definition: buffer.c:105
unsigned int fourcc
Definition: raw.h:34
int linesize[AV_NUM_DATA_POINTERS]
number of bytes per line
Definition: avcodec.h:3022
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:1599
This structure describes decoded (raw) audio or video data.
Definition: frame.h:135
AVCodec ff_rawvideo_decoder
Definition: rawdec.c:258
int avpicture_fill(AVPicture *picture, uint8_t *ptr, enum AVPixelFormat pix_fmt, int width, int height)
Fill in the AVPicture fields.
Definition: avpicture.c:34
misc image utilities
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:67
AVBufferRef * buf[AV_NUM_DATA_POINTERS]
AVBuffer references backing the data for this frame.
Definition: frame.h:393
int is_2_4_bpp
Definition: rawdec.c:39
int size
Definition: avcodec.h:968
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1248
enum AVPixelFormat pix_fmt
Definition: raw.h:33
static enum AVPixelFormat find_pix_fmt(const PixelFormatTag *tags, unsigned int fourcc)
Definition: rawdec.c:68
#define AV_PIX_FMT_RGB444
Definition: pixfmt.h:232
four components are given, that's all.
Definition: avcodec.h:3020
int frame_size
Definition: rawdec.c:37
AVCodec.
Definition: avcodec.h:2790
static int decode(MimicContext *ctx, int quality, int num_coeffs, int is_iframe)
Definition: mimic.c:275
uint8_t
#define av_cold
Definition: attributes.h:66
8 bit with PIX_FMT_RGB32 palette
Definition: pixfmt.h:76
uint8_t * data[AV_NUM_DATA_POINTERS]
Definition: avcodec.h:3021
int avpriv_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt)
Definition: imgutils.c:141
int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
Set various frame properties from the codec context / packet data.
Definition: utils.c:560
const PixelFormatTag ff_raw_pix_fmt_tags[]
Definition: raw.c:31
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1158
static const PixelFormatTag pix_fmt_bps_avi[]
Definition: rawdec.c:43
const char data[16]
Definition: mxf.c:70
uint8_t * data
Definition: avcodec.h:967
int bits_per_coded_sample
bits per sample/pixel from the demuxer (needed for huffyuv).
Definition: avcodec.h:2501
static const uint8_t frame_size[4]
Definition: g723_1_data.h:47
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:123
#define AVERROR(e)
Definition: error.h:43
AVBufferRef * palette
Definition: rawdec.c:36
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:150
AVBufferRef * buf
A reference to the reference-counted buffer where the packet data is stored.
Definition: avcodec.h:950
Definition: graph2dot.c:49
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:168
const char * name
Name of the codec implementation.
Definition: avcodec.h:2797
static const PixelFormatTag pix_fmt_bps_mov[]
Definition: rawdec.c:54
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition: pixfmt.h:95
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:196
#define FFMIN(a, b)
Definition: common.h:57
Raw Video Codec.
int width
picture width / height.
Definition: avcodec.h:1218
static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: rawdec.c:138
#define AV_PIX_FMT_FLAG_PSEUDOPAL
The pixel format is "pseudo-paletted".
Definition: pixdesc.h:134
#define AV_RL32
Definition: intreadwrite.h:146
packed RGB 8:8:8, 24bpp, BGRBGR...
Definition: pixfmt.h:68
NULL
Definition: eval.c:55
Libavcodec external API header.
AVBufferRef * av_buffer_alloc(int size)
Allocate an AVBuffer of the given size using av_malloc().
Definition: buffer.c:65
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:153
uint8_t flags
Definition: pixdesc.h:90
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:69
main external API structure.
Definition: avcodec.h:1044
static void close(AVCodecParserContext *s)
Definition: h264_parser.c:490
#define AV_PIX_FMT_RGB32
Definition: pixfmt.h:222
uint8_t * data
The data buffer.
Definition: buffer.h:89
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A').
Definition: avcodec.h:1076
packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr
Definition: pixfmt.h:66
int extradata_size
Definition: avcodec.h:1159
static av_cold int raw_close_decoder(AVCodecContext *avctx)
Definition: rawdec.c:250
int palette_has_changed
Tell user application that palette has changed from previous frame.
Definition: frame.h:330
refcounted data buffer API
packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), big-endian, most significant bit to 0 ...
Definition: pixfmt.h:117
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:141
A reference to a data buffer.
Definition: buffer.h:81
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:65
common internal api header.
common internal and external API header
Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb...
Definition: pixfmt.h:74
static void flip(AVCodecContext *avctx, AVPicture *picture)
Definition: rawdec.c:132
static av_cold int raw_init_decoder(AVCodecContext *avctx)
Definition: rawdec.c:79
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
Definition: buffer.c:91
#define AV_PIX_FMT_RGB555
Definition: pixfmt.h:231
static av_cold int init(AVCodecParserContext *s)
Definition: h264_parser.c:499
void * priv_data
Definition: avcodec.h:1086
int avpicture_get_size(enum AVPixelFormat pix_fmt, int width, int height)
Calculate the size in bytes that a picture of the given width and height would occupy if stored in th...
Definition: avpicture.c:85
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:191
uint8_t * av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type, int *size)
Get side information from packet.
Definition: avpacket.c:287
#define FFSWAP(type, a, b)
Definition: common.h:60
#define MKTAG(a, b, c, d)
Definition: common.h:238
AVPixelFormat
Pixel format.
Definition: pixfmt.h:63
This structure stores compressed data.
Definition: avcodec.h:944