FFmpeg
smvjpegdec.c
Go to the documentation of this file.
1 /*
2  * SMV JPEG decoder
3  * Copyright (c) 2013 Ash Hughes
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 /**
23  * @file
24  * SMV JPEG decoder.
25  */
26 
27 // #define DEBUG
28 #include "avcodec.h"
29 #include "libavutil/opt.h"
30 #include "libavutil/imgutils.h"
31 #include "mjpegdec.h"
32 #include "internal.h"
33 
34 typedef struct SMVJpegDecodeContext {
36  AVFrame *picture[2]; /* pictures array */
41 
42 static inline void smv_img_pnt_plane(uint8_t **dst, uint8_t *src,
43  int src_linesize, int height, int nlines)
44 {
45  if (!dst || !src)
46  return;
47  src += (nlines) * src_linesize * height;
48  *dst = src;
49 }
50 
51 static inline void smv_img_pnt(uint8_t *dst_data[4], uint8_t *src_data[4],
52  const int src_linesizes[4],
53  enum AVPixelFormat pix_fmt, int width, int height,
54  int nlines)
55 {
57  int i, planes_nb = 0;
58 
59  if (desc->flags & AV_PIX_FMT_FLAG_HWACCEL)
60  return;
61 
62  for (i = 0; i < desc->nb_components; i++)
63  planes_nb = FFMAX(planes_nb, desc->comp[i].plane + 1);
64 
65  for (i = 0; i < planes_nb; i++) {
66  int h = height;
67  if (i == 1 || i == 2) {
68  h = AV_CEIL_RSHIFT(height, desc->log2_chroma_h);
69  }
70  smv_img_pnt_plane(&dst_data[i], src_data[i],
71  src_linesizes[i], h, nlines);
72  }
73  if (desc->flags & AV_PIX_FMT_FLAG_PAL ||
74  desc->flags & FF_PSEUDOPAL)
75  dst_data[1] = src_data[1];
76 }
77 
79 {
81  MJpegDecodeContext *jpg = &s->jpg;
82  int ret;
83 
84  jpg->picture_ptr = NULL;
85  av_frame_free(&s->picture[0]);
86  av_frame_free(&s->picture[1]);
87  ret = avcodec_close(s->avctx);
88  av_freep(&s->avctx);
89  return ret;
90 }
91 
93 {
95  AVCodec *codec;
96  AVDictionary *thread_opt = NULL;
97  int ret = 0, r;
98 
99  s->frames_per_jpeg = 0;
100 
101  s->picture[0] = av_frame_alloc();
102  if (!s->picture[0])
103  return AVERROR(ENOMEM);
104 
105  s->picture[1] = av_frame_alloc();
106  if (!s->picture[1]) {
107  av_frame_free(&s->picture[0]);
108  return AVERROR(ENOMEM);
109  }
110 
111  s->jpg.picture_ptr = s->picture[0];
112 
113  if (avctx->extradata_size >= 4)
114  s->frames_per_jpeg = AV_RL32(avctx->extradata);
115 
116  if (s->frames_per_jpeg <= 0) {
117  av_log(avctx, AV_LOG_ERROR, "Invalid number of frames per jpeg.\n");
118  ret = AVERROR_INVALIDDATA;
119  }
120 
122  if (!codec) {
123  av_log(avctx, AV_LOG_ERROR, "MJPEG codec not found\n");
124  smvjpeg_decode_end(avctx);
126  }
127 
128  s->avctx = avcodec_alloc_context3(codec);
129 
130  av_dict_set(&thread_opt, "threads", "1", 0);
131  s->avctx->refcounted_frames = 1;
132  s->avctx->flags = avctx->flags;
133  s->avctx->idct_algo = avctx->idct_algo;
134  if ((r = ff_codec_open2_recursive(s->avctx, codec, &thread_opt)) < 0) {
135  av_log(avctx, AV_LOG_ERROR, "MJPEG codec failed to open\n");
136  ret = r;
137  }
138  av_dict_free(&thread_opt);
139 
140  if (ret < 0)
141  smvjpeg_decode_end(avctx);
142  return ret;
143 }
144 
145 static int smvjpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
146  AVPacket *avpkt)
147 {
148  const AVPixFmtDescriptor *desc;
149  SMVJpegDecodeContext *s = avctx->priv_data;
150  AVFrame* mjpeg_data = s->picture[0];
151  int i, cur_frame = 0, ret = 0;
152 
153  cur_frame = avpkt->pts % s->frames_per_jpeg;
154 
155  /* cur_frame is later used to calculate the buffer offset, so it mustn't be negative */
156  if (cur_frame < 0)
157  cur_frame += s->frames_per_jpeg;
158 
159  /* Are we at the start of a block? */
160  if (!cur_frame) {
161  av_frame_unref(mjpeg_data);
162  ret = avcodec_decode_video2(s->avctx, mjpeg_data, &s->mjpeg_data_size, avpkt);
163  if (ret < 0) {
164  s->mjpeg_data_size = 0;
165  return ret;
166  }
167  } else if (!s->mjpeg_data_size)
168  return AVERROR(EINVAL);
169 
170  desc = av_pix_fmt_desc_get(s->avctx->pix_fmt);
171  av_assert0(desc);
172 
173  if (mjpeg_data->height % (s->frames_per_jpeg << desc->log2_chroma_h)) {
174  av_log(avctx, AV_LOG_ERROR, "Invalid height\n");
175  return AVERROR_INVALIDDATA;
176  }
177 
178  /*use the last lot... */
179  *data_size = s->mjpeg_data_size;
180 
181  avctx->pix_fmt = s->avctx->pix_fmt;
182 
183  /* We shouldn't get here if frames_per_jpeg <= 0 because this was rejected
184  in init */
185  ret = ff_set_dimensions(avctx, mjpeg_data->width, mjpeg_data->height / s->frames_per_jpeg);
186  if (ret < 0) {
187  av_log(s, AV_LOG_ERROR, "Failed to set dimensions\n");
188  return ret;
189  }
190 
191  if (*data_size) {
192  s->picture[1]->extended_data = NULL;
193  s->picture[1]->width = avctx->width;
194  s->picture[1]->height = avctx->height;
195  s->picture[1]->format = avctx->pix_fmt;
196  smv_img_pnt(s->picture[1]->data, mjpeg_data->data, mjpeg_data->linesize,
197  avctx->pix_fmt, avctx->width, avctx->height, cur_frame);
198  for (i = 0; i < AV_NUM_DATA_POINTERS; i++)
199  s->picture[1]->linesize[i] = mjpeg_data->linesize[i];
200 
201  ret = av_frame_ref(data, s->picture[1]);
202  if (ret < 0)
203  return ret;
204  }
205 
206  return avpkt->size;
207 }
208 
209 static const AVClass smvjpegdec_class = {
210  .class_name = "SMVJPEG decoder",
211  .item_name = av_default_item_name,
212  .version = LIBAVUTIL_VERSION_INT,
213 };
214 
216  .name = "smvjpeg",
217  .long_name = NULL_IF_CONFIG_SMALL("SMV JPEG"),
218  .type = AVMEDIA_TYPE_VIDEO,
219  .id = AV_CODEC_ID_SMVJPEG,
220  .priv_data_size = sizeof(SMVJpegDecodeContext),
222  .close = smvjpeg_decode_end,
224  .priv_class = &smvjpegdec_class,
225 };
#define AV_PIX_FMT_FLAG_PAL
Pixel format has a palette in data[1], values are indexes in this palette.
Definition: pixdesc.h:132
AVCodec ff_smvjpeg_decoder
Definition: smvjpegdec.c:215
int plane
Which of the 4 planes contains the component.
Definition: pixdesc.h:35
#define NULL
Definition: coverity.c:32
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
static enum AVPixelFormat pix_fmt
#define AV_NUM_DATA_POINTERS
Definition: frame.h:296
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2522
This structure describes decoded (raw) audio or video data.
Definition: frame.h:295
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
misc image utilities
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
Definition: utils.c:104
const char * desc
Definition: nvenc.c:68
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
int size
Definition: avcodec.h:1481
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1778
static av_cold int smvjpeg_decode_init(AVCodecContext *avctx)
Definition: smvjpegdec.c:92
#define src
Definition: vp8dsp.c:254
AVCodec.
Definition: avcodec.h:3492
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
AVFrame * picture[2]
Definition: smvjpegdec.c:36
static void smv_img_pnt(uint8_t *dst_data[4], uint8_t *src_data[4], const int src_linesizes[4], enum AVPixelFormat pix_fmt, int width, int height, int nlines)
Definition: smvjpegdec.c:51
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:117
uint8_t
#define av_cold
Definition: attributes.h:82
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:189
AVOptions.
static int smvjpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
Definition: smvjpegdec.c:145
int av_frame_ref(AVFrame *dst, const AVFrame *src)
Set up a new reference to the data described by the source frame.
Definition: frame.c:443
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1669
AVFrame * picture_ptr
Definition: mjpegdec.h:101
#define height
#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
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
int width
Definition: frame.h:353
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:101
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
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:202
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:186
const char * r
Definition: vf_curves.c:114
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
#define AV_PIX_FMT_FLAG_HWACCEL
Pixel format is an HW accelerated format.
Definition: pixdesc.h:140
const char * name
Name of the codec implementation.
Definition: avcodec.h:3499
#define FFMAX(a, b)
Definition: common.h:94
uint64_t flags
Combination of AV_PIX_FMT_FLAG_...
Definition: pixdesc.h:106
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:83
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
#define s(width, name)
Definition: cbs_vp9.c:257
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
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:81
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 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
Describe the class of an AVClass context structure.
Definition: log.h:67
AVCodecContext * avctx
Definition: smvjpegdec.c:37
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
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:553
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:309
MJpegDecodeContext jpg
Definition: smvjpegdec.c:35
common internal api header.
static void smv_img_pnt_plane(uint8_t **dst, uint8_t *src, int src_linesize, int height, int nlines)
Definition: smvjpegdec.c:42
void * priv_data
Definition: avcodec.h:1595
#define AVERROR_DECODER_NOT_FOUND
Decoder not found.
Definition: error.h:52
static const AVClass smvjpegdec_class
Definition: smvjpegdec.c:209
#define FF_PSEUDOPAL
Definition: internal.h:367
int height
Definition: frame.h:353
#define av_freep(p)
static av_cold int smvjpeg_decode_end(AVCodecContext *avctx)
Definition: smvjpegdec.c:78
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.
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:342
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:87
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
This structure stores compressed data.
Definition: avcodec.h:1457
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1473
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58