FFmpeg
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
Examples
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
libavcodec
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
{
35
MJpegDecodeContext
jpg
;
36
AVFrame
*
picture
[2];
/* pictures array */
37
AVCodecContext
*
avctx
;
38
int
frames_per_jpeg
;
39
int
mjpeg_data_size
;
40
}
SMVJpegDecodeContext
;
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
||
74
desc->
flags
&
AV_PIX_FMT_FLAG_PSEUDOPAL
)
75
dst_data[1] = src_data[1];
76
}
77
78
static
av_cold
int
smvjpeg_decode_init
(
AVCodecContext
*avctx)
79
{
80
SMVJpegDecodeContext
*
s
= avctx->
priv_data
;
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
105
codec =
avcodec_find_decoder
(
AV_CODEC_ID_MJPEG
);
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
176
static
av_cold
int
smvjpeg_decode_end
(
AVCodecContext
*avctx)
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]);
184
ff_codec_close_recursive
(s->
avctx
);
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
195
AVCodec
ff_smvjpeg_decoder
= {
196
.
name
=
"smvjpeg"
,
197
.type =
AVMEDIA_TYPE_VIDEO
,
198
.id =
AV_CODEC_ID_SMVJPEG
,
199
.priv_data_size =
sizeof
(
SMVJpegDecodeContext
),
200
.
init
=
smvjpeg_decode_init
,
201
.
close
=
smvjpeg_decode_end
,
202
.
decode
=
smvjpeg_decode_frame
,
203
.long_name =
NULL_IF_CONFIG_SMALL
(
"SMV JPEG"
),
204
.priv_class = &
smvjpegdec_class
,
205
};
Generated on Wed Jul 10 2013 23:48:05 for FFmpeg by
1.8.2