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 
56  a->mjpeg_avctx = avcodec_alloc_context3(codec);
57 
58  av_dict_set(&thread_opt, "threads", "1", 0); // Is this needed ?
59  a->mjpeg_avctx->refcounted_frames = 1;
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 
94  avcodec_close(a->mjpeg_avctx);
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 };
avcodec_close
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:1117
AVCodec
AVCodec.
Definition: avcodec.h:3481
FF_CODEC_CAP_INIT_THREADSAFE
#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
mjpeg.h
init
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
AVERROR
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
end
static av_cold int end(AVCodecContext *avctx)
Definition: avrndec.c:90
decode_frame
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: avrndec.c:100
mjpegdec.h
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
AVFrame::width
int width
Definition: frame.h:353
internal.h
AVPacket::data
uint8_t * data
Definition: avcodec.h:1477
data
const char data[16]
Definition: mxf.c:91
AVDictionary
Definition: dict.c:30
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
AVRnContext::mjpeg_avctx
AVCodecContext * mjpeg_avctx
Definition: avrndec.c:29
AVFrame::key_frame
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:373
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:1645
av_pix_fmt_get_chroma_sub_sample
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
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
buf
void * buf
Definition: avisynth_c.h:766
av_cold
#define av_cold
Definition: attributes.h:84
decode
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:42
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:1667
avcodec_alloc_context3
AVCodecContext * avcodec_alloc_context3(const AVCodec *codec)
Allocate an AVCodecContext and set its fields to default values.
Definition: options.c:156
width
#define width
AV_CODEC_ID_AVRN
@ AV_CODEC_ID_AVRN
Definition: avcodec.h:423
NULL
#define NULL
Definition: coverity.c:32
AV_PICTURE_TYPE_I
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
AVCodecContext::lowres
int lowres
low resolution decoding, 1-> 1/2 size, 2->1/4 size
Definition: avcodec.h:2804
AVFrame::pict_type
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:378
ff_get_buffer
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1965
ff_codec_open2_recursive
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:553
AVPacket::size
int size
Definition: avcodec.h:1478
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:188
AVFrame::format
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames,...
Definition: frame.h:368
avcodec_find_decoder
AVCodec * avcodec_find_decoder(enum AVCodecID id)
Find a registered decoder with a matching codec ID.
Definition: allcodecs.c:890
height
#define height
a
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:41
av_dict_free
void av_dict_free(AVDictionary **pm)
Free all the memory allocated for an AVDictionary struct and all keys and values.
Definition: dict.c:203
AV_CODEC_ID_MJPEG
@ AV_CODEC_ID_MJPEG
Definition: avcodec.h:225
AVRnContext::tff
int tff
Definition: avrndec.c:32
AVCodecContext::extradata
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1666
avcodec_decode_video2
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:898
uint8_t
uint8_t
Definition: audio_convert.c:194
AVCodecContext::idct_algo
int idct_algo
IDCT algorithm, see FF_IDCT_* below.
Definition: avcodec.h:2768
AVCodec::name
const char * name
Name of the codec implementation.
Definition: avcodec.h:3488
AVRnContext::interlace
int interlace
Definition: avrndec.c:31
AVCodecContext::height
int height
Definition: avcodec.h:1738
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1775
avcodec.h
ret
ret
Definition: filter_design.txt:187
AV_PIX_FMT_UYVY422
@ AV_PIX_FMT_UYVY422
packed YUV 4:2:2, 16bpp, Cb Y0 Cr Y1
Definition: pixfmt.h:81
AVCodecContext
main external API structure.
Definition: avcodec.h:1565
AVFrame::height
int height
Definition: frame.h:353
AVRnContext::is_mjpeg
int is_mjpeg
Definition: avrndec.c:30
ff_avrn_decoder
AVCodec ff_avrn_decoder
Definition: avrndec.c:162
shift
static int shift(int a, int b)
Definition: sonic.c:82
AVERROR_DECODER_NOT_FOUND
#define AVERROR_DECODER_NOT_FOUND
Decoder not found.
Definition: error.h:52
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AVPacket
This structure stores compressed data.
Definition: avcodec.h:1454
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:1592
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
av_dict_set
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
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:1738
imgutils.h
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:326
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
av_image_check_size
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
AVRnContext
Definition: avrndec.c:28