Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
F
ffmpeg.wasm-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Linshizhi
ffmpeg.wasm-core
Commits
aa372cf4
Commit
aa372cf4
authored
May 19, 2012
by
Kostya Shishkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
factor out common decoding code for Indeo 4 and Indeo 5
parent
b37d945d
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
317 additions
and
465 deletions
+317
-465
indeo4.c
libavcodec/indeo4.c
+26
-245
indeo5.c
libavcodec/indeo5.c
+21
-220
ivi_common.c
libavcodec/ivi_common.c
+210
-0
ivi_common.h
libavcodec/ivi_common.h
+60
-0
No files found.
libavcodec/indeo4.c
View file @
aa372cf4
This diff is collapsed.
Click to expand it.
libavcodec/indeo5.c
View file @
aa372cf4
This diff is collapsed.
Click to expand it.
libavcodec/ivi_common.c
View file @
aa372cf4
...
...
@@ -620,6 +620,216 @@ void ff_ivi_output_plane(IVIPlaneDesc *plane, uint8_t *dst, int dst_pitch)
}
}
/**
* Decode an Indeo 4 or 5 band.
*
* @param[in,out] ctx ptr to the decoder context
* @param[in,out] band ptr to the band descriptor
* @param[in] avctx ptr to the AVCodecContext
* @return result code: 0 = OK, -1 = error
*/
static
int
decode_band
(
IVI45DecContext
*
ctx
,
int
plane_num
,
IVIBandDesc
*
band
,
AVCodecContext
*
avctx
)
{
int
result
,
i
,
t
,
idx1
,
idx2
,
pos
;
IVITile
*
tile
;
band
->
buf
=
band
->
bufs
[
ctx
->
dst_buf
];
band
->
ref_buf
=
band
->
bufs
[
ctx
->
ref_buf
];
band
->
data_ptr
=
ctx
->
frame_data
+
(
get_bits_count
(
&
ctx
->
gb
)
>>
3
);
result
=
ctx
->
decode_band_hdr
(
ctx
,
band
,
avctx
);
if
(
result
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Error while decoding band header: %d
\n
"
,
result
);
return
result
;
}
if
(
band
->
is_empty
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Empty band encountered!
\n
"
);
return
AVERROR_INVALIDDATA
;
}
band
->
rv_map
=
&
ctx
->
rvmap_tabs
[
band
->
rvmap_sel
];
/* apply corrections to the selected rvmap table if present */
for
(
i
=
0
;
i
<
band
->
num_corr
;
i
++
)
{
idx1
=
band
->
corr
[
i
*
2
];
idx2
=
band
->
corr
[
i
*
2
+
1
];
FFSWAP
(
uint8_t
,
band
->
rv_map
->
runtab
[
idx1
],
band
->
rv_map
->
runtab
[
idx2
]);
FFSWAP
(
int16_t
,
band
->
rv_map
->
valtab
[
idx1
],
band
->
rv_map
->
valtab
[
idx2
]);
}
pos
=
get_bits_count
(
&
ctx
->
gb
);
for
(
t
=
0
;
t
<
band
->
num_tiles
;
t
++
)
{
tile
=
&
band
->
tiles
[
t
];
tile
->
is_empty
=
get_bits1
(
&
ctx
->
gb
);
if
(
tile
->
is_empty
)
{
ff_ivi_process_empty_tile
(
avctx
,
band
,
tile
,
(
ctx
->
planes
[
0
].
bands
[
0
].
mb_size
>>
3
)
-
(
band
->
mb_size
>>
3
));
av_dlog
(
avctx
,
"Empty tile encountered!
\n
"
);
}
else
{
tile
->
data_size
=
ff_ivi_dec_tile_data_size
(
&
ctx
->
gb
);
if
(
!
tile
->
data_size
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Tile data size is zero!
\n
"
);
return
AVERROR_INVALIDDATA
;
}
result
=
ctx
->
decode_mb_info
(
ctx
,
band
,
tile
,
avctx
);
if
(
result
<
0
)
break
;
result
=
ff_ivi_decode_blocks
(
&
ctx
->
gb
,
band
,
tile
);
if
(
result
<
0
||
((
get_bits_count
(
&
ctx
->
gb
)
-
pos
)
>>
3
)
!=
tile
->
data_size
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Corrupted tile data encountered!
\n
"
);
break
;
}
pos
+=
tile
->
data_size
<<
3
;
// skip to next tile
}
}
/* restore the selected rvmap table by applying its corrections in reverse order */
for
(
i
=
band
->
num_corr
-
1
;
i
>=
0
;
i
--
)
{
idx1
=
band
->
corr
[
i
*
2
];
idx2
=
band
->
corr
[
i
*
2
+
1
];
FFSWAP
(
uint8_t
,
band
->
rv_map
->
runtab
[
idx1
],
band
->
rv_map
->
runtab
[
idx2
]);
FFSWAP
(
int16_t
,
band
->
rv_map
->
valtab
[
idx1
],
band
->
rv_map
->
valtab
[
idx2
]);
}
#ifdef DEBUG
if
(
band
->
checksum_present
)
{
uint16_t
chksum
=
ivi_calc_band_checksum
(
band
);
if
(
chksum
!=
band
->
checksum
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Band checksum mismatch! Plane %d, band %d, received: %x, calculated: %x
\n
"
,
band
->
plane
,
band
->
band_num
,
band
->
checksum
,
chksum
);
}
}
#endif
align_get_bits
(
&
ctx
->
gb
);
return
result
;
}
int
ff_ivi_decode_frame
(
AVCodecContext
*
avctx
,
void
*
data
,
int
*
data_size
,
AVPacket
*
avpkt
)
{
IVI45DecContext
*
ctx
=
avctx
->
priv_data
;
const
uint8_t
*
buf
=
avpkt
->
data
;
int
buf_size
=
avpkt
->
size
;
int
result
,
p
,
b
;
init_get_bits
(
&
ctx
->
gb
,
buf
,
buf_size
*
8
);
ctx
->
frame_data
=
buf
;
ctx
->
frame_size
=
buf_size
;
result
=
ctx
->
decode_pic_hdr
(
ctx
,
avctx
);
if
(
result
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Error while decoding picture header: %d
\n
"
,
result
);
return
-
1
;
}
if
(
ctx
->
gop_flags
&
IVI5_IS_PROTECTED
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Password-protected clip!
\n
"
);
return
-
1
;
}
ctx
->
switch_buffers
(
ctx
);
//{ START_TIMER;
if
(
ctx
->
is_nonnull_frame
(
ctx
))
{
for
(
p
=
0
;
p
<
3
;
p
++
)
{
for
(
b
=
0
;
b
<
ctx
->
planes
[
p
].
num_bands
;
b
++
)
{
result
=
decode_band
(
ctx
,
p
,
&
ctx
->
planes
[
p
].
bands
[
b
],
avctx
);
if
(
result
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Error while decoding band: %d, plane: %d
\n
"
,
b
,
p
);
return
-
1
;
}
}
}
}
//STOP_TIMER("decode_planes"); }
/* If the bidirectional mode is enabled, next I and the following P frame will */
/* be sent together. Unfortunately the approach below seems to be the only way */
/* to handle the B-frames mode. That's exactly the same Intel decoders do. */
if
(
avctx
->
codec_id
==
CODEC_ID_INDEO4
&&
ctx
->
frame_type
==
0
/*FRAMETYPE_INTRA*/
)
{
while
(
get_bits
(
&
ctx
->
gb
,
8
));
// skip version string
skip_bits_long
(
&
ctx
->
gb
,
64
);
// skip padding, TODO: implement correct 8-bytes alignment
if
(
get_bits_left
(
&
ctx
->
gb
)
>
18
&&
show_bits
(
&
ctx
->
gb
,
18
)
==
0x3FFF8
)
av_log
(
avctx
,
AV_LOG_ERROR
,
"Buffer contains IP frames!
\n
"
);
}
if
(
ctx
->
frame
.
data
[
0
])
avctx
->
release_buffer
(
avctx
,
&
ctx
->
frame
);
ctx
->
frame
.
reference
=
0
;
if
((
result
=
avctx
->
get_buffer
(
avctx
,
&
ctx
->
frame
))
<
0
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"get_buffer() failed
\n
"
);
return
result
;
}
if
(
ctx
->
is_scalable
)
{
if
(
avctx
->
codec_id
==
CODEC_ID_INDEO4
)
ff_ivi_recompose_haar
(
&
ctx
->
planes
[
0
],
ctx
->
frame
.
data
[
0
],
ctx
->
frame
.
linesize
[
0
],
4
);
else
ff_ivi_recompose53
(
&
ctx
->
planes
[
0
],
ctx
->
frame
.
data
[
0
],
ctx
->
frame
.
linesize
[
0
],
4
);
}
else
{
ff_ivi_output_plane
(
&
ctx
->
planes
[
0
],
ctx
->
frame
.
data
[
0
],
ctx
->
frame
.
linesize
[
0
]);
}
ff_ivi_output_plane
(
&
ctx
->
planes
[
2
],
ctx
->
frame
.
data
[
1
],
ctx
->
frame
.
linesize
[
1
]);
ff_ivi_output_plane
(
&
ctx
->
planes
[
1
],
ctx
->
frame
.
data
[
2
],
ctx
->
frame
.
linesize
[
2
]);
*
data_size
=
sizeof
(
AVFrame
);
*
(
AVFrame
*
)
data
=
ctx
->
frame
;
return
buf_size
;
}
/**
* Close Indeo5 decoder and clean up its context.
*/
av_cold
int
ff_ivi_decode_close
(
AVCodecContext
*
avctx
)
{
IVI45DecContext
*
ctx
=
avctx
->
priv_data
;
ff_ivi_free_buffers
(
&
ctx
->
planes
[
0
]);
if
(
ctx
->
mb_vlc
.
cust_tab
.
table
)
ff_free_vlc
(
&
ctx
->
mb_vlc
.
cust_tab
);
if
(
ctx
->
frame
.
data
[
0
])
avctx
->
release_buffer
(
avctx
,
&
ctx
->
frame
);
#if IVI4_STREAM_ANALYSER
if
(
avctx
->
codec_id
==
CODEC_ID_INDEO4
)
{
if
(
ctx
->
is_scalable
)
av_log
(
avctx
,
AV_LOG_ERROR
,
"This video uses scalability mode!
\n
"
);
if
(
ctx
->
uses_tiling
)
av_log
(
avctx
,
AV_LOG_ERROR
,
"This video uses local decoding!
\n
"
);
if
(
ctx
->
has_b_frames
)
av_log
(
avctx
,
AV_LOG_ERROR
,
"This video contains B-frames!
\n
"
);
if
(
ctx
->
has_transp
)
av_log
(
avctx
,
AV_LOG_ERROR
,
"Transparency mode is enabled!
\n
"
);
if
(
ctx
->
uses_haar
)
av_log
(
avctx
,
AV_LOG_ERROR
,
"This video uses Haar transform!
\n
"
);
if
(
ctx
->
uses_fullpel
)
av_log
(
avctx
,
AV_LOG_ERROR
,
"This video uses fullpel motion vectors!
\n
"
);
}
#endif
return
0
;
}
/**
* These are 2x8 predefined Huffman codebooks for coding macroblock/block
...
...
libavcodec/ivi_common.h
View file @
aa372cf4
...
...
@@ -34,6 +34,8 @@
#include <stdint.h>
#define IVI_VLC_BITS 13 ///< max number of bits of the ivi's huffman codes
#define IVI4_STREAM_ANALYSER 0
#define IVI5_IS_PROTECTED 0x20
/**
* huffman codebook descriptor
...
...
@@ -192,6 +194,60 @@ typedef struct {
uint8_t
chroma_bands
;
}
IVIPicConfig
;
typedef
struct
IVI45DecContext
{
GetBitContext
gb
;
AVFrame
frame
;
RVMapDesc
rvmap_tabs
[
9
];
///< local corrected copy of the static rvmap tables
uint32_t
frame_num
;
int
frame_type
;
int
prev_frame_type
;
///< frame type of the previous frame
uint32_t
data_size
;
///< size of the frame data in bytes from picture header
int
is_scalable
;
int
transp_status
;
///< transparency mode status: 1 - enabled
const
uint8_t
*
frame_data
;
///< input frame data pointer
int
inter_scal
;
///< signals a sequence of scalable inter frames
uint32_t
frame_size
;
///< frame size in bytes
uint32_t
pic_hdr_size
;
///< picture header size in bytes
uint8_t
frame_flags
;
uint16_t
checksum
;
///< frame checksum
IVIPicConfig
pic_conf
;
IVIPlaneDesc
planes
[
3
];
///< color planes
int
buf_switch
;
///< used to switch between three buffers
int
dst_buf
;
///< buffer index for the currently decoded frame
int
ref_buf
;
///< inter frame reference buffer index
int
ref2_buf
;
///< temporal storage for switching buffers
IVIHuffTab
mb_vlc
;
///< current macroblock table descriptor
IVIHuffTab
blk_vlc
;
///< current block table descriptor
uint8_t
rvmap_sel
;
uint8_t
in_imf
;
uint8_t
in_q
;
///< flag for explicitly stored quantiser delta
uint8_t
pic_glob_quant
;
uint8_t
unknown1
;
uint16_t
gop_hdr_size
;
uint8_t
gop_flags
;
uint32_t
lock_word
;
#if IVI4_STREAM_ANALYSER
uint8_t
has_b_frames
;
uint8_t
has_transp
;
uint8_t
uses_tiling
;
uint8_t
uses_haar
;
uint8_t
uses_fullpel
;
#endif
int
(
*
decode_pic_hdr
)
(
struct
IVI45DecContext
*
ctx
,
AVCodecContext
*
avctx
);
int
(
*
decode_band_hdr
)
(
struct
IVI45DecContext
*
ctx
,
IVIBandDesc
*
band
,
AVCodecContext
*
avctx
);
int
(
*
decode_mb_info
)
(
struct
IVI45DecContext
*
ctx
,
IVIBandDesc
*
band
,
IVITile
*
tile
,
AVCodecContext
*
avctx
);
void
(
*
switch_buffers
)
(
struct
IVI45DecContext
*
ctx
);
int
(
*
is_nonnull_frame
)(
struct
IVI45DecContext
*
ctx
);
}
IVI45DecContext
;
/** compare some properties of two pictures */
static
inline
int
ivi_pic_config_cmp
(
IVIPicConfig
*
str1
,
IVIPicConfig
*
str2
)
{
...
...
@@ -348,4 +404,8 @@ uint16_t ivi_calc_band_checksum (IVIBandDesc *band);
*/
int
ivi_check_band
(
IVIBandDesc
*
band
,
const
uint8_t
*
ref
,
int
pitch
);
int
ff_ivi_decode_frame
(
AVCodecContext
*
avctx
,
void
*
data
,
int
*
data_size
,
AVPacket
*
avpkt
);
av_cold
int
ff_ivi_decode_close
(
AVCodecContext
*
avctx
);
#endif
/* AVCODEC_IVI_COMMON_H */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment