FFmpeg  4.0
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
const char * s
Definition: avisynth_c.h:768
#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:219
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:2363
This structure describes decoded (raw) audio or video data.
Definition: frame.h:218
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:65
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
int size
Definition: avcodec.h:1431
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:1727
static av_cold int smvjpeg_decode_init(AVCodecContext *avctx)
Definition: smvjpegdec.c:92
#define src
Definition: vp8dsp.c:254
AVCodec.
Definition: avcodec.h:3408
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:42
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:441
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1618
AVFrame * picture_ptr
Definition: mjpegdec.h:100
const char data[16]
Definition: mxf.c:90
#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:1061
int width
Definition: frame.h:276
#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:526
#define AVERROR(e)
Definition: error.h:43
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:111
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:1598
uint16_t width
Definition: gdv.c:47
#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:3415
#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
int width
picture width / height.
Definition: avcodec.h:1690
int idct_algo
IDCT algorithm, see FF_IDCT_* below.
Definition: avcodec.h:2713
#define AV_RL32
Definition: intreadwrite.h:146
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:291
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
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:249
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:1518
AVCodec * avcodec_find_decoder(enum AVCodecID id)
Find a registered decoder with a matching codec ID.
Definition: allcodecs.c:862
int extradata_size
Definition: avcodec.h:1619
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:2344
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:551
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:232
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:1545
#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:276
#define av_freep(p)
static av_cold int smvjpeg_decode_end(AVCodecContext *avctx)
Definition: smvjpegdec.c:78
MJPEG decoder.
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:265
AVPixelFormat
Pixel format.
Definition: pixfmt.h:60
This structure stores compressed data.
Definition: avcodec.h:1407
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1423
#define AV_CEIL_RSHIFT(a, b)
Definition: common.h:58