FFmpeg  2.1.1
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 PixelFormat pix_fmt, int width, int height,
54  int nlines)
55 {
56  const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
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 = FF_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 ||
75  dst_data[1] = src_data[1];
76 }
77 
79 {
81  AVCodec *codec;
82  AVDictionary *thread_opt = NULL;
83  int ret = 0;
84 
85  s->frames_per_jpeg = 0;
86 
87  s->picture[0] = av_frame_alloc();
88  if (!s->picture[0])
89  return AVERROR(ENOMEM);
90 
91  s->picture[1] = av_frame_alloc();
92  if (!s->picture[1])
93  return AVERROR(ENOMEM);
94 
95  s->jpg.picture_ptr = s->picture[0];
96 
97  if (avctx->extradata_size >= 4)
98  s->frames_per_jpeg = AV_RL32(avctx->extradata);
99 
100  if (s->frames_per_jpeg <= 0) {
101  av_log(avctx, AV_LOG_ERROR, "Invalid number of frames per jpeg.\n");
102  ret = -1;
103  }
104 
106  if (!codec) {
107  av_log(avctx, AV_LOG_ERROR, "MJPEG codec not found\n");
108  ret = -1;
109  }
110 
111  s->avctx = avcodec_alloc_context3(codec);
112 
113  av_dict_set(&thread_opt, "threads", "1", 0);
114  s->avctx->refcounted_frames = 1;
115  s->avctx->flags = avctx->flags;
116  s->avctx->idct_algo = avctx->idct_algo;
117  if (ff_codec_open2_recursive(s->avctx, codec, &thread_opt) < 0) {
118  av_log(avctx, AV_LOG_ERROR, "MJPEG codec failed to open\n");
119  ret = -1;
120  }
121  av_dict_free(&thread_opt);
122 
123  return ret;
124 }
125 
126 static int smvjpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
127  AVPacket *avpkt)
128 {
129  const AVPixFmtDescriptor *desc;
130  SMVJpegDecodeContext *s = avctx->priv_data;
131  AVFrame* mjpeg_data = s->picture[0];
132  int i, cur_frame = 0, ret = 0;
133 
134  cur_frame = avpkt->pts % s->frames_per_jpeg;
135 
136  /* Are we at the start of a block? */
137  if (!cur_frame) {
138  av_frame_unref(mjpeg_data);
139  ret = avcodec_decode_video2(s->avctx, mjpeg_data, &s->mjpeg_data_size, avpkt);
140  } else if (!s->mjpeg_data_size)
141  return AVERROR(EINVAL);
142 
143  desc = av_pix_fmt_desc_get(s->avctx->pix_fmt);
144  if (desc && mjpeg_data->height % (s->frames_per_jpeg << desc->log2_chroma_h)) {
145  av_log(avctx, AV_LOG_ERROR, "Invalid height\n");
146  return AVERROR_INVALIDDATA;
147  }
148 
149  /*use the last lot... */
150  *data_size = s->mjpeg_data_size;
151 
152  avctx->pix_fmt = s->avctx->pix_fmt;
153 
154  /* We shouldn't get here if frames_per_jpeg <= 0 because this was rejected
155  in init */
156  avcodec_set_dimensions(avctx, mjpeg_data->width,
157  mjpeg_data->height / s->frames_per_jpeg);
158 
159  if (*data_size) {
160  s->picture[1]->extended_data = NULL;
161  s->picture[1]->width = avctx->width;
162  s->picture[1]->height = avctx->height;
163  s->picture[1]->format = avctx->pix_fmt;
164  /* ff_init_buffer_info(avctx, &s->picture[1]); */
165  smv_img_pnt(s->picture[1]->data, mjpeg_data->data, mjpeg_data->linesize,
166  avctx->pix_fmt, avctx->width, avctx->height, cur_frame);
167  for (i = 0; i < AV_NUM_DATA_POINTERS; i++)
168  s->picture[1]->linesize[i] = mjpeg_data->linesize[i];
169 
170  ret = av_frame_ref(data, s->picture[1]);
171  }
172 
173  return ret;
174 }
175 
177 {
178  SMVJpegDecodeContext *s = avctx->priv_data;
179  MJpegDecodeContext *jpg = &s->jpg;
180 
181  jpg->picture_ptr = NULL;
182  av_frame_free(&s->picture[0]);
183  av_frame_free(&s->picture[1]);
185  av_freep(&s->avctx);
186  return 0;
187 }
188 
189 static const AVClass smvjpegdec_class = {
190  .class_name = "SMVJPEG decoder",
191  .item_name = av_default_item_name,
192  .version = LIBAVUTIL_VERSION_INT,
193 };
194 
196  .name = "smvjpeg",
197  .long_name = NULL_IF_CONFIG_SMALL("SMV JPEG"),
198  .type = AVMEDIA_TYPE_VIDEO,
199  .id = AV_CODEC_ID_SMVJPEG,
200  .priv_data_size = sizeof(SMVJpegDecodeContext),
204  .priv_class = &smvjpegdec_class,
205 };
AVCodec ff_smvjpeg_decoder
Definition: smvjpegdec.c:195
const char * s
Definition: avisynth_c.h:668
This structure describes decoded (raw) audio or video data.
Definition: frame.h:96
#define LIBAVUTIL_VERSION_INT
Definition: avcodec.h:820
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
void avcodec_set_dimensions(AVCodecContext *s, int width, int height)
Definition: utils.c:233
uint8_t ** extended_data
pointers to the data planes/channels.
Definition: frame.h:140
AVComponentDescriptor comp[4]
Parameters that describe how pixels are packed.
Definition: pixdesc.h:88
void av_log(void *avcl, int level, const char *fmt,...) av_printf_format(3
Send the specified message to the log if the level is less than or equal to the current av_log_level...
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:1342
static av_cold int smvjpeg_decode_init(AVCodecContext *avctx)
Definition: smvjpegdec.c:78
AVCodec.
Definition: avcodec.h:2922
#define av_cold
Definition: avcodec.h:653
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
Definition: avcodec.h:1254
AVFrame * picture[2]
Definition: smvjpegdec.c:36
void av_freep(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:234
const char * av_default_item_name(void *ctx)
Return the context name.
Definition: log.c:145
uint8_t
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:55
static int smvjpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt)
Definition: smvjpegdec.c:126
const char * name
Name of the codec implementation.
Definition: avcodec.h:2929
#define AV_PIX_FMT_FLAG_PAL
Pixel format has a palette in data[1], values are indexes in this palette.
Definition: pixdesc.h:98
int av_frame_ref(AVFrame *dst, AVFrame *src)
Setup a new reference to the data described by a given frame.
Definition: frame.c:247
#define FF_CEIL_RSHIFT(a, b)
Definition: avcodec.h:916
AVFrame * picture_ptr
Definition: mjpegdec.h:94
const char data[16]
Definition: mxf.c:68
AVCodecContext * avcodec_alloc_context3(const AVCodec *codec)
Allocate an AVCodecContext and set its fields to default values.
Definition: options.c:151
enum AVPixelFormat pix_fmt
Definition: v4l.c:62
#define AV_NUM_DATA_POINTERS
Definition: frame.h:97
#define AV_PIX_FMT_FLAG_PSEUDOPAL
The pixel format is &quot;pseudo-paletted&quot;.
Definition: pixdesc.h:120
static void smv_img_pnt(uint8_t *dst_data[4], uint8_t *src_data[4], const int src_linesizes[4], enum PixelFormat pix_fmt, int width, int height, int nlines)
Definition: smvjpegdec.c:51
int width
width and height of the video frame
Definition: frame.h:145
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: avcodec.h:4147
uint8_t log2_chroma_h
Amount to shift the luma height right to find the chroma height.
Definition: pixdesc.h:77
int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture, int *got_picture_ptr, const AVPacket *avpkt)
Decode the video frame of size avpkt-&gt;size from avpkt-&gt;data into picture.
Definition: utils.c:2029
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:1145
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:151
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:110
void av_dict_free(AVDictionary **m)
Free all the memory allocated for an AVDictionary struct and all keys and values. ...
Definition: dict.c:162
int flags
CODEC_FLAG_*.
Definition: avcodec.h:1234
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:123
Libavcodec external API header.
uint8_t nb_components
The number of components each pixel has, (1-4)
Definition: pixdesc.h:59
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:351
ret
Definition: avfilter.c:961
int width
picture width / height.
Definition: avcodec.h:1314
int idct_algo
IDCT algorithm, see FF_IDCT_* below.
Definition: avcodec.h:2540
int refcounted_frames
If non-zero, the decoded audio and video frames returned from avcodec_decode_video2() and avcodec_dec...
Definition: avcodec.h:2148
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:1938
AVCodec * avcodec_find_decoder(enum AVCodecID id)
Find a registered decoder with a matching codec ID.
Definition: utils.c:2607
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:157
#define AV_PIX_FMT_FLAG_HWACCEL
Pixel format is an HW accelerated format.
Definition: pixdesc.h:106
static int width
Definition: utils.c:158
AVS_Value src
Definition: avisynth_c.h:523
#define FFMAX(a, b)
Definition: avcodec.h:923
uint8_t flags
Definition: pixdesc.h:78
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Definition: pixdesc.h:57
main external API structure.
Definition: avcodec.h:1146
static void close(AVCodecParserContext *s)
Definition: h264_parser.c:538
int extradata_size
Definition: avcodec.h:1255
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:62
BYTE int const BYTE int int int height
Definition: avisynth_c.h:713
Describe the class of an AVClass context structure.
Definition: log.h:50
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:124
AVCodecContext * avctx
Definition: smvjpegdec.c:37
void * priv_data
Definition: avcodec.h:1182
#define PixelFormat
Definition: avcodec.h:4990
uint16_t plane
which of the 4 planes contains the component
Definition: pixdesc.h:31
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
static const AVClass smvjpegdec_class
Definition: smvjpegdec.c:189
#define AVERROR_INVALIDDATA
#define AV_RL32(x)
Definition: intreadwrite.h:275
#define AVERROR(e)
int height
Definition: frame.h:145
static int decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: crystalhd.c:868
int ff_codec_close_recursive(AVCodecContext *avctx)
Call avcodec_close recursively, counterpart to avcodec_open2_recursive.
Definition: utils.c:2493
static av_cold int smvjpeg_decode_end(AVCodecContext *avctx)
Definition: smvjpegdec.c:176
MJPEG decoder.
This structure stores compressed data.
Definition: avcodec.h:1040
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:107
int64_t pts
Presentation timestamp in AVStream-&gt;time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1056