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 
83  jpg->picture_ptr = NULL;
84  av_frame_free(&s->picture[0]);
85  av_frame_free(&s->picture[1]);
87  return 0;
88 }
89 
91 {
93  AVCodec *codec;
94  AVDictionary *thread_opt = NULL;
95  int ret = 0, r;
96 
97  s->frames_per_jpeg = 0;
98 
99  s->picture[0] = av_frame_alloc();
100  if (!s->picture[0])
101  return AVERROR(ENOMEM);
102 
103  s->picture[1] = av_frame_alloc();
104  if (!s->picture[1]) {
105  av_frame_free(&s->picture[0]);
106  return AVERROR(ENOMEM);
107  }
108 
109  s->jpg.picture_ptr = s->picture[0];
110 
111  if (avctx->extradata_size >= 4)
112  s->frames_per_jpeg = AV_RL32(avctx->extradata);
113 
114  if (s->frames_per_jpeg <= 0) {
115  av_log(avctx, AV_LOG_ERROR, "Invalid number of frames per jpeg.\n");
116  ret = AVERROR_INVALIDDATA;
117  }
118 
120  if (!codec) {
121  av_log(avctx, AV_LOG_ERROR, "MJPEG codec not found\n");
122  smvjpeg_decode_end(avctx);
124  }
125 
126  s->avctx = avcodec_alloc_context3(codec);
127 
128  av_dict_set(&thread_opt, "threads", "1", 0);
129  s->avctx->refcounted_frames = 1;
130  s->avctx->flags = avctx->flags;
131  s->avctx->idct_algo = avctx->idct_algo;
132  if ((r = avcodec_open2(s->avctx, codec, &thread_opt)) < 0) {
133  av_log(avctx, AV_LOG_ERROR, "MJPEG codec failed to open\n");
134  ret = r;
135  }
136  av_dict_free(&thread_opt);
137 
138  if (ret < 0)
139  smvjpeg_decode_end(avctx);
140  return ret;
141 }
142 
143 static int smvjpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
144  AVPacket *avpkt)
145 {
146  const AVPixFmtDescriptor *desc;
147  SMVJpegDecodeContext *s = avctx->priv_data;
148  AVFrame* mjpeg_data = s->picture[0];
149  int i, cur_frame = 0, ret = 0;
150 
151  cur_frame = avpkt->pts % s->frames_per_jpeg;
152 
153  /* cur_frame is later used to calculate the buffer offset, so it mustn't be negative */
154  if (cur_frame < 0)
155  cur_frame += s->frames_per_jpeg;
156 
157  /* Are we at the start of a block? */
158  if (!cur_frame) {
159  av_frame_unref(mjpeg_data);
160  ret = avcodec_decode_video2(s->avctx, mjpeg_data, &s->mjpeg_data_size, avpkt);
161  if (ret < 0) {
162  s->mjpeg_data_size = 0;
163  return ret;
164  }
165  } else if (!s->mjpeg_data_size)
166  return AVERROR(EINVAL);
167 
168  desc = av_pix_fmt_desc_get(s->avctx->pix_fmt);
169  av_assert0(desc);
170 
171  if (mjpeg_data->height % (s->frames_per_jpeg << desc->log2_chroma_h)) {
172  av_log(avctx, AV_LOG_ERROR, "Invalid height\n");
173  return AVERROR_INVALIDDATA;
174  }
175 
176  /*use the last lot... */
177  *data_size = s->mjpeg_data_size;
178 
179  avctx->pix_fmt = s->avctx->pix_fmt;
180 
181  /* We shouldn't get here if frames_per_jpeg <= 0 because this was rejected
182  in init */
183  ret = ff_set_dimensions(avctx, mjpeg_data->width, mjpeg_data->height / s->frames_per_jpeg);
184  if (ret < 0) {
185  av_log(s, AV_LOG_ERROR, "Failed to set dimensions\n");
186  return ret;
187  }
188 
189  if (*data_size) {
190  s->picture[1]->extended_data = NULL;
191  s->picture[1]->width = avctx->width;
192  s->picture[1]->height = avctx->height;
193  s->picture[1]->format = avctx->pix_fmt;
194  smv_img_pnt(s->picture[1]->data, mjpeg_data->data, mjpeg_data->linesize,
195  avctx->pix_fmt, avctx->width, avctx->height, cur_frame);
196  for (i = 0; i < AV_NUM_DATA_POINTERS; i++)
197  s->picture[1]->linesize[i] = mjpeg_data->linesize[i];
198 
199  ret = av_frame_ref(data, s->picture[1]);
200  if (ret < 0)
201  return ret;
202  }
203 
204  return avpkt->size;
205 }
206 
207 static const AVClass smvjpegdec_class = {
208  .class_name = "SMVJPEG decoder",
209  .item_name = av_default_item_name,
210  .version = LIBAVUTIL_VERSION_INT,
211 };
212 
214  .name = "smvjpeg",
215  .long_name = NULL_IF_CONFIG_SMALL("SMV JPEG"),
216  .type = AVMEDIA_TYPE_VIDEO,
217  .id = AV_CODEC_ID_SMVJPEG,
218  .priv_data_size = sizeof(SMVJpegDecodeContext),
220  .close = smvjpeg_decode_end,
222  .priv_class = &smvjpegdec_class,
223  .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
224 };
#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:213
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:315
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2573
This structure describes decoded (raw) audio or video data.
Definition: frame.h:314
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
const char * desc
Definition: libsvtav1.c:79
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:106
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
int size
Definition: packet.h:364
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:741
static av_cold int smvjpeg_decode_init(AVCodecContext *avctx)
Definition: smvjpegdec.c:90
AVCodec.
Definition: codec.h:190
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
#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
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:117
uint8_t
#define av_cold
Definition: attributes.h:88
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:190
AVOptions.
static int smvjpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
Definition: smvjpegdec.c:143
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:632
AVFrame * picture_ptr
Definition: mjpegdec.h:101
#define height
#define av_log(a,...)
#define src
Definition: vp8dsp.c:254
int width
Definition: frame.h:372
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:101
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:153
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:611
#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: codec.h:197
#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:172
#define width
int width
picture width / height.
Definition: avcodec.h:704
int idct_algo
IDCT algorithm, see FF_IDCT_* below.
Definition: avcodec.h:1734
#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:387
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:826
void avcodec_free_context(AVCodecContext **avctx)
Free the codec context and everything associated with it and write NULL to the provided pointer...
Definition: options.c:187
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:345
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:531
int extradata_size
Definition: avcodec.h:633
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
int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
Initialize the AVCodecContext to use the given AVCodec.
Definition: utils.c:538
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:1362
AVCodec * avcodec_find_decoder(enum AVCodecID id)
Find a registered decoder with a matching codec ID.
Definition: allcodecs.c:940
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:328
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:558
#define AVERROR_DECODER_NOT_FOUND
Decoder not found.
Definition: error.h:52
static const AVClass smvjpegdec_class
Definition: smvjpegdec.c:207
#define FF_PSEUDOPAL
Definition: internal.h:335
int height
Definition: frame.h:372
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:361
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:91
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
This structure stores compressed data.
Definition: packet.h:340
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: packet.h:356
int i
Definition: input.c:407
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58