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  if (!a->mjpeg_avctx)
58  return AVERROR(ENOMEM);
59 
60  av_dict_set(&thread_opt, "threads", "1", 0); // Is this needed ?
61  a->mjpeg_avctx->refcounted_frames = 1;
62  a->mjpeg_avctx->flags = avctx->flags;
63  a->mjpeg_avctx->idct_algo = avctx->idct_algo;
64  a->mjpeg_avctx->lowres = avctx->lowres;
65  a->mjpeg_avctx->width = avctx->width;
66  a->mjpeg_avctx->height = avctx->height;
67 
68  if ((ret = ff_codec_open2_recursive(a->mjpeg_avctx, codec, &thread_opt)) < 0) {
69  av_log(avctx, AV_LOG_ERROR, "MJPEG codec failed to open\n");
70  }
71  av_dict_free(&thread_opt);
72 
73  return ret;
74  }
75 
76  if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0)
77  return ret;
78 
79  avctx->pix_fmt = AV_PIX_FMT_UYVY422;
80 
81  if(avctx->extradata_size >= 9 && avctx->extradata[4]+28 < avctx->extradata_size) {
82  int ndx = avctx->extradata[4] + 4;
83  a->interlace = !memcmp(avctx->extradata + ndx, "1:1(", 4);
84  if(a->interlace) {
85  a->tff = avctx->extradata[ndx + 24] == 1;
86  }
87  }
88 
89  return 0;
90 }
91 
92 static av_cold int end(AVCodecContext *avctx)
93 {
94  AVRnContext *a = avctx->priv_data;
95 
96  avcodec_close(a->mjpeg_avctx);
97  av_freep(&a->mjpeg_avctx);
98 
99  return 0;
100 }
101 
102 static int decode_frame(AVCodecContext *avctx, void *data,
103  int *got_frame, AVPacket *avpkt)
104 {
105  AVRnContext *a = avctx->priv_data;
106  AVFrame *p = data;
107  const uint8_t *buf = avpkt->data;
108  int buf_size = avpkt->size;
109  int y, ret, true_height;
110 
111  if(a->is_mjpeg) {
112  ret = avcodec_decode_video2(a->mjpeg_avctx, data, got_frame, avpkt);
113 
114  if (ret >= 0 && *got_frame && avctx->width <= p->width && avctx->height <= p->height) {
115  int shift = p->height - avctx->height;
116  int subsample_h, subsample_v;
117 
118  av_pix_fmt_get_chroma_sub_sample(p->format, &subsample_h, &subsample_v);
119 
120  p->data[0] += p->linesize[0] * shift;
121  if (p->data[2]) {
122  p->data[1] += p->linesize[1] * (shift>>subsample_v);
123  p->data[2] += p->linesize[2] * (shift>>subsample_v);
124  }
125 
126  p->width = avctx->width;
127  p->height = avctx->height;
128  }
129  avctx->pix_fmt = a->mjpeg_avctx->pix_fmt;
130  return ret;
131  }
132 
133  true_height = buf_size / (2*avctx->width);
134 
135  if(buf_size < 2*avctx->width * avctx->height) {
136  av_log(avctx, AV_LOG_ERROR, "packet too small\n");
137  return AVERROR_INVALIDDATA;
138  }
139 
140  if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
141  return ret;
143  p->key_frame= 1;
144 
145  if(a->interlace) {
146  buf += (true_height - avctx->height)*avctx->width;
147  for(y = 0; y < avctx->height-1; y+=2) {
148  memcpy(p->data[0] + (y+ a->tff)*p->linesize[0], buf , 2*avctx->width);
149  memcpy(p->data[0] + (y+!a->tff)*p->linesize[0], buf + avctx->width*true_height+4, 2*avctx->width);
150  buf += 2*avctx->width;
151  }
152  } else {
153  buf += (true_height - avctx->height)*avctx->width*2;
154  for(y = 0; y < avctx->height; y++) {
155  memcpy(p->data[0] + y*p->linesize[0], buf, 2*avctx->width);
156  buf += 2*avctx->width;
157  }
158  }
159 
160  *got_frame = 1;
161  return buf_size;
162 }
163 
165  .name = "avrn",
166  .long_name = NULL_IF_CONFIG_SMALL("Avid AVI Codec"),
167  .type = AVMEDIA_TYPE_VIDEO,
168  .id = AV_CODEC_ID_AVRN,
169  .priv_data_size = sizeof(AVRnContext),
170  .init = init,
171  .close = end,
172  .decode = decode_frame,
173  .max_lowres = 3,
175 };
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:1143
AVCodec
AVCodec.
Definition: codec.h:190
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:92
decode_frame
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: avrndec.c:102
mjpegdec.h
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:300
AVFrame::width
int width
Definition: frame.h:358
internal.h
AVPacket::data
uint8_t * data
Definition: packet.h:355
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:314
AVRnContext::mjpeg_avctx
AVCodecContext * mjpeg_avctx
Definition: avrndec.c:29
AVFrame::key_frame
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:378
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:606
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:2577
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
av_cold
#define av_cold
Definition: attributes.h:90
decode
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
AVCodecContext::extradata_size
int extradata_size
Definition: avcodec.h:628
avcodec_alloc_context3
AVCodecContext * avcodec_alloc_context3(const AVCodec *codec)
Allocate an AVCodecContext and set its fields to default values.
Definition: options.c:157
width
#define width
AV_CODEC_ID_AVRN
@ AV_CODEC_ID_AVRN
Definition: codec_id.h:254
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:1765
AVFrame::pict_type
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:383
ff_get_buffer
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: decode.c:1854
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: packet.h:356
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:373
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: codec_id.h:56
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:627
FF_CODEC_CAP_INIT_CLEANUP
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: internal.h:48
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:806
uint8_t
uint8_t
Definition: audio_convert.c:194
AVCodecContext::idct_algo
int idct_algo
IDCT algorithm, see FF_IDCT_* below.
Definition: avcodec.h:1729
AVCodec::name
const char * name
Name of the codec implementation.
Definition: codec.h:197
AVRnContext::interlace
int interlace
Definition: avrndec.c:31
AVCodecContext::height
int height
Definition: avcodec.h:699
AVCodecContext::pix_fmt
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:736
avcodec.h
ret
ret
Definition: filter_design.txt:187
avcodec_find_decoder
AVCodec * avcodec_find_decoder(enum AVCodecID id)
Find a registered decoder with a matching codec ID.
Definition: allcodecs.c:919
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:526
AVFrame::height
int height
Definition: frame.h:358
AVRnContext::is_mjpeg
int is_mjpeg
Definition: avrndec.c:30
ff_avrn_decoder
AVCodec ff_avrn_decoder
Definition: avrndec.c:164
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: packet.h:332
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:553
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:699
imgutils.h
AVFrame::linesize
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:331
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