FFmpeg
avrndec.c
Go to the documentation of this file.
1 /*
2  * AVRn decoder
3  * Copyright (c) 2012 Michael Niedermayer
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 #include "avcodec.h"
23 #include "internal.h"
24 #include "mjpeg.h"
25 #include "mjpegdec.h"
26 #include "libavutil/imgutils.h"
27 
28 typedef struct {
30  int is_mjpeg;
31  int interlace;
32  int tff;
33 } AVRnContext;
34 
35 static av_cold int init(AVCodecContext *avctx)
36 {
37  AVRnContext *a = avctx->priv_data;
38  int ret;
39 
40  // Support "Resolution 1:1" for Avid AVI Codec
41  a->is_mjpeg = avctx->extradata_size < 31 || memcmp(&avctx->extradata[28], "1:1", 3);
42 
43  if(!a->is_mjpeg && avctx->lowres) {
44  av_log(avctx, AV_LOG_ERROR, "lowres is not possible with rawvideo\n");
45  return AVERROR(EINVAL);
46  }
47 
48  if(a->is_mjpeg) {
50  AVDictionary *thread_opt = NULL;
51  if (!codec) {
52  av_log(avctx, AV_LOG_ERROR, "MJPEG codec not found\n");
54  }
55 
57 
58  av_dict_set(&thread_opt, "threads", "1", 0); // Is this needed ?
60  a->mjpeg_avctx->flags = avctx->flags;
61  a->mjpeg_avctx->idct_algo = avctx->idct_algo;
62  a->mjpeg_avctx->lowres = avctx->lowres;
63  a->mjpeg_avctx->width = avctx->width;
64  a->mjpeg_avctx->height = avctx->height;
65 
66  if ((ret = ff_codec_open2_recursive(a->mjpeg_avctx, codec, &thread_opt)) < 0) {
67  av_log(avctx, AV_LOG_ERROR, "MJPEG codec failed to open\n");
68  }
69  av_dict_free(&thread_opt);
70 
71  return ret;
72  }
73 
74  if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0)
75  return ret;
76 
77  avctx->pix_fmt = AV_PIX_FMT_UYVY422;
78 
79  if(avctx->extradata_size >= 9 && avctx->extradata[4]+28 < avctx->extradata_size) {
80  int ndx = avctx->extradata[4] + 4;
81  a->interlace = !memcmp(avctx->extradata + ndx, "1:1(", 4);
82  if(a->interlace) {
83  a->tff = avctx->extradata[ndx + 24] == 1;
84  }
85  }
86 
87  return 0;
88 }
89 
90 static av_cold int end(AVCodecContext *avctx)
91 {
92  AVRnContext *a = avctx->priv_data;
93 
95  av_freep(&a->mjpeg_avctx);
96 
97  return 0;
98 }
99 
100 static int decode_frame(AVCodecContext *avctx, void *data,
101  int *got_frame, AVPacket *avpkt)
102 {
103  AVRnContext *a = avctx->priv_data;
104  AVFrame *p = data;
105  const uint8_t *buf = avpkt->data;
106  int buf_size = avpkt->size;
107  int y, ret, true_height;
108 
109  if(a->is_mjpeg) {
110  ret = avcodec_decode_video2(a->mjpeg_avctx, data, got_frame, avpkt);
111 
112  if (ret >= 0 && *got_frame && avctx->width <= p->width && avctx->height <= p->height) {
113  int shift = p->height - avctx->height;
114  int subsample_h, subsample_v;
115 
116  av_pix_fmt_get_chroma_sub_sample(p->format, &subsample_h, &subsample_v);
117 
118  p->data[0] += p->linesize[0] * shift;
119  if (p->data[2]) {
120  p->data[1] += p->linesize[1] * (shift>>subsample_v);
121  p->data[2] += p->linesize[2] * (shift>>subsample_v);
122  }
123 
124  p->width = avctx->width;
125  p->height = avctx->height;
126  }
127  avctx->pix_fmt = a->mjpeg_avctx->pix_fmt;
128  return ret;
129  }
130 
131  true_height = buf_size / (2*avctx->width);
132 
133  if(buf_size < 2*avctx->width * avctx->height) {
134  av_log(avctx, AV_LOG_ERROR, "packet too small\n");
135  return AVERROR_INVALIDDATA;
136  }
137 
138  if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
139  return ret;
141  p->key_frame= 1;
142 
143  if(a->interlace) {
144  buf += (true_height - avctx->height)*avctx->width;
145  for(y = 0; y < avctx->height-1; y+=2) {
146  memcpy(p->data[0] + (y+ a->tff)*p->linesize[0], buf , 2*avctx->width);
147  memcpy(p->data[0] + (y+!a->tff)*p->linesize[0], buf + avctx->width*true_height+4, 2*avctx->width);
148  buf += 2*avctx->width;
149  }
150  } else {
151  buf += (true_height - avctx->height)*avctx->width*2;
152  for(y = 0; y < avctx->height; y++) {
153  memcpy(p->data[0] + y*p->linesize[0], buf, 2*avctx->width);
154  buf += 2*avctx->width;
155  }
156  }
157 
158  *got_frame = 1;
159  return buf_size;
160 }
161 
163  .name = "avrn",
164  .long_name = NULL_IF_CONFIG_SMALL("Avid AVI Codec"),
165  .type = AVMEDIA_TYPE_VIDEO,
166  .id = AV_CODEC_ID_AVRN,
167  .priv_data_size = sizeof(AVRnContext),
168  .init = init,
169  .close = end,
170  .decode = decode_frame,
171  .max_lowres = 3,
172  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
173 };
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
Definition: pixfmt.h:81
AVCodec ff_avrn_decoder
Definition: avrndec.c:162
#define NULL
Definition: coverity.c:32
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
static int shift(int a, int b)
Definition: sonic.c:82
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: avrndec.c:100
misc image utilities
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
int size
Definition: avcodec.h:1481
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:36
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1778
AVCodec.
Definition: avcodec.h:3492
MJPEG encoder and decoder.
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
int is_mjpeg
Definition: avrndec.c:30
AVCodecContext * mjpeg_avctx
Definition: avrndec.c:29
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
Definition: internal.h:40
uint8_t
#define av_cold
Definition: attributes.h:82
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1669
#define height
uint8_t * data
Definition: avcodec.h:1480
int lowres
low resolution decoding, 1-> 1/2 size, 2->1/4 size
Definition: avcodec.h:2807
#define av_log(a,...)
int avcodec_close(AVCodecContext *avctx)
Close a given AVCodecContext and free all the data associated with it (but not the AVCodecContext its...
Definition: utils.c:1100
int width
Definition: frame.h:353
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
int ff_codec_open2_recursive(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
Call avcodec_open2 recursively by decrementing counter, unlocking mutex, calling the function and the...
Definition: utils.c:536
int av_pix_fmt_get_chroma_sub_sample(enum AVPixelFormat pix_fmt, int *h_shift, int *v_shift)
Utility function to access log2_chroma_w log2_chroma_h from the pixel format AVPixFmtDescriptor.
Definition: pixdesc.c:2550
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values. ...
Definition: dict.c:203
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:1648
const char * name
Name of the codec implementation.
Definition: avcodec.h:3499
int interlace
Definition: avrndec.c:31
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of the image can be address...
Definition: imgutils.c:282
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:378
AVCodecContext * avcodec_alloc_context3(const AVCodec *codec)
Allocate an AVCodecContext and set its fields to default values.
Definition: options.c:156
#define width
int width
picture width / height.
Definition: avcodec.h:1741
int idct_algo
IDCT algorithm, see FF_IDCT_* below.
Definition: avcodec.h:2771
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:368
Libavcodec external API header.
attribute_deprecated int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, const AVPacket *avpkt)
Decode the video frame of size avpkt->size from avpkt->data into picture.
Definition: decode.c:897
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:326
main external API structure.
Definition: avcodec.h:1568
AVCodec * avcodec_find_decoder(enum AVCodecID id)
Find a registered decoder with a matching codec ID.
Definition: allcodecs.c:896
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1968
void * buf
Definition: avisynth_c.h:766
int extradata_size
Definition: avcodec.h:1670
int av_dict_set(AVDictionary **pm, const char *key, const char *value, int flags)
Set the given entry in *pm, overwriting an existing entry.
Definition: dict.c:70
attribute_deprecated int refcounted_frames
If non-zero, the decoded audio and video frames returned from avcodec_decode_video2() and avcodec_dec...
Definition: avcodec.h:2399
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
common internal api header.
void * priv_data
Definition: avcodec.h:1595
#define AVERROR_DECODER_NOT_FOUND
Decoder not found.
Definition: error.h:52
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:373
int height
Definition: frame.h:353
#define av_freep(p)
int tff
Definition: avrndec.c:32
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
MJPEG decoder.
This structure stores compressed data.
Definition: avcodec.h:1457