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