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
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
...
...
@@ -35,9 +35,6 @@
#include "ivi_common.h"
#include "indeo4data.h"
#define IVI4_STREAM_ANALYSER 0
#define IVI4_DEBUG_CHECKSUM 0
/**
* Indeo 4 frame types.
*/
...
...
@@ -54,46 +51,6 @@ enum {
#define IVI4_PIC_SIZE_ESC 7
typedef
struct
{
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
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
IVIHuffTab
mb_vlc
;
///< current macroblock table descriptor
IVIHuffTab
blk_vlc
;
///< current block table descriptor
uint16_t
checksum
;
///< frame checksum
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
;
#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
}
IVI4DecContext
;
static
const
struct
{
InvTransformPtr
*
inv_trans
;
DCTransformPtr
*
dc_trans
;
...
...
@@ -158,7 +115,7 @@ static inline int scale_tile_size(int def_size, int size_factor)
* @param[in] avctx pointer to the AVCodecContext
* @return result code: 0 = OK, negative number = error
*/
static
int
decode_pic_hdr
(
IVI4DecContext
*
ctx
,
AVCodecContext
*
avctx
)
static
int
decode_pic_hdr
(
IVI4
5
DecContext
*
ctx
,
AVCodecContext
*
avctx
)
{
int
pic_size_indx
,
i
,
p
;
IVIPicConfig
pic_conf
;
...
...
@@ -322,7 +279,7 @@ static int decode_pic_hdr(IVI4DecContext *ctx, AVCodecContext *avctx)
* @param[in] avctx pointer to the AVCodecContext
* @return result code: 0 = OK, negative number = error
*/
static
int
decode_band_hdr
(
IVI4DecContext
*
ctx
,
IVIBandDesc
*
band
,
static
int
decode_band_hdr
(
IVI4
5
DecContext
*
ctx
,
IVIBandDesc
*
band
,
AVCodecContext
*
avctx
)
{
int
plane
,
band_num
,
indx
,
transform_id
,
scan_indx
;
...
...
@@ -458,7 +415,7 @@ static int decode_band_hdr(IVI4DecContext *ctx, IVIBandDesc *band,
* @param[in] avctx pointer to the AVCodecContext
* @return result code: 0 = OK, negative number = error
*/
static
int
decode_mb_info
(
IVI4DecContext
*
ctx
,
IVIBandDesc
*
band
,
static
int
decode_mb_info
(
IVI4
5
DecContext
*
ctx
,
IVIBandDesc
*
band
,
IVITile
*
tile
,
AVCodecContext
*
avctx
)
{
int
x
,
y
,
mv_x
,
mv_y
,
mv_delta
,
offs
,
mb_offset
,
blks_per_mb
,
...
...
@@ -573,126 +530,12 @@ static int decode_mb_info(IVI4DecContext *ctx, IVIBandDesc *band,
}
/**
* Decode an Indeo 4 band.
*
* @param[in,out] ctx pointer to the decoder context
* @param[in,out] band pointer to the band descriptor
* @param[in] avctx pointer to the AVCodecContext
* @return result code: 0 = OK, negative number = error
*/
static
int
decode_band
(
IVI4DecContext
*
ctx
,
int
plane_num
,
IVIBandDesc
*
band
,
AVCodecContext
*
avctx
)
{
int
result
,
i
,
t
,
pos
,
idx1
,
idx2
;
IVITile
*
tile
;
band
->
buf
=
band
->
bufs
[
ctx
->
dst_buf
];
band
->
ref_buf
=
band
->
bufs
[
ctx
->
ref_buf
];
result
=
decode_band_hdr
(
ctx
,
band
,
avctx
);
if
(
result
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Error decoding band header
\n
"
);
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
=
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
]);
}
#if defined(DEBUG) && IVI4_DEBUG_CHECKSUM
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
0
;
}
static
av_cold
int
decode_init
(
AVCodecContext
*
avctx
)
{
IVI4DecContext
*
ctx
=
avctx
->
priv_data
;
ff_ivi_init_static_vlc
();
/* copy rvmap tables in our context so we can apply changes to them */
memcpy
(
ctx
->
rvmap_tabs
,
ff_ivi_rvmap_tabs
,
sizeof
(
ff_ivi_rvmap_tabs
));
/* Force allocation of the internal buffers */
/* during picture header decoding. */
ctx
->
pic_conf
.
pic_width
=
0
;
ctx
->
pic_conf
.
pic_height
=
0
;
avctx
->
pix_fmt
=
PIX_FMT_YUV410P
;
return
0
;
}
/**
* Rearrange decoding and reference buffers.
*
* @param[in,out] ctx pointer to the decoder context
*/
static
void
switch_buffers
(
IVI4DecContext
*
ctx
)
static
void
switch_buffers
(
IVI4
5
DecContext
*
ctx
)
{
switch
(
ctx
->
prev_frame_type
)
{
case
FRAMETYPE_INTRA
:
...
...
@@ -721,95 +564,33 @@ static void switch_buffers(IVI4DecContext *ctx)
}
static
int
decode_frame
(
AVCodecContext
*
avctx
,
void
*
data
,
int
*
data_size
,
AVPacket
*
avpkt
)
static
int
is_nonnull_frame
(
IVI45DecContext
*
ctx
)
{
IVI4DecContext
*
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
);
result
=
decode_pic_hdr
(
ctx
,
avctx
);
if
(
result
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Error decoding picture header
\n
"
);
return
result
;
}
switch_buffers
(
ctx
);
if
(
ctx
->
frame_type
<
FRAMETYPE_NULL_FIRST
)
{
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 decoding band: %d, plane: %d
\n
"
,
b
,
p
);
return
result
;
}
}
}
}
/* 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
(
ctx
->
frame_type
==
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
)
{
ff_ivi_recompose_haar
(
&
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
;
return
ctx
->
frame_type
<
FRAMETYPE_NULL_FIRST
;
}
static
av_cold
int
decode_
close
(
AVCodecContext
*
avctx
)
static
av_cold
int
decode_
init
(
AVCodecContext
*
avctx
)
{
IVI4DecContext
*
ctx
=
avctx
->
priv_data
;
IVI4
5
DecContext
*
ctx
=
avctx
->
priv_data
;
ff_ivi_
free_buffers
(
&
ctx
->
planes
[
0
]
);
ff_ivi_
init_static_vlc
(
);
if
(
ctx
->
frame
.
data
[
0
])
avctx
->
release_buffer
(
avctx
,
&
ctx
->
frame
);
/* copy rvmap tables in our context so we can apply changes to them */
memcpy
(
ctx
->
rvmap_tabs
,
ff_ivi_rvmap_tabs
,
sizeof
(
ff_ivi_rvmap_tabs
)
);
#if IVI4_STREAM_ANALYSER
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
/* Force allocation of the internal buffers */
/* during picture header decoding. */
ctx
->
pic_conf
.
pic_width
=
0
;
ctx
->
pic_conf
.
pic_height
=
0
;
avctx
->
pix_fmt
=
PIX_FMT_YUV410P
;
ctx
->
decode_pic_hdr
=
decode_pic_hdr
;
ctx
->
decode_band_hdr
=
decode_band_hdr
;
ctx
->
decode_mb_info
=
decode_mb_info
;
ctx
->
switch_buffers
=
switch_buffers
;
ctx
->
is_nonnull_frame
=
is_nonnull_frame
;
return
0
;
}
...
...
@@ -819,9 +600,9 @@ AVCodec ff_indeo4_decoder = {
.
name
=
"indeo4"
,
.
type
=
AVMEDIA_TYPE_VIDEO
,
.
id
=
CODEC_ID_INDEO4
,
.
priv_data_size
=
sizeof
(
IVI4DecContext
),
.
priv_data_size
=
sizeof
(
IVI4
5
DecContext
),
.
init
=
decode_init
,
.
close
=
decode_close
,
.
decode
=
decode_frame
,
.
close
=
ff_ivi_
decode_close
,
.
decode
=
ff_ivi_
decode_frame
,
.
long_name
=
NULL_IF_CONFIG_SMALL
(
"Intel Indeo Video Interactive 4"
),
};
libavcodec/indeo5.c
View file @
aa372cf4
...
...
@@ -48,37 +48,6 @@ enum {
#define IVI5_PIC_SIZE_ESC 15
#define IVI5_IS_PROTECTED 0x20
typedef
struct
{
GetBitContext
gb
;
AVFrame
frame
;
RVMapDesc
rvmap_tabs
[
9
];
///< local corrected copy of the static rvmap tables
IVIPlaneDesc
planes
[
3
];
///< color planes
const
uint8_t
*
frame_data
;
///< input frame data pointer
int
buf_switch
;
///< used to switch between three buffers
int
inter_scal
;
///< signals a sequence of scalable inter frames
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
uint32_t
frame_size
;
///< frame size in bytes
int
frame_type
;
int
prev_frame_type
;
///< frame type of the previous frame
int
frame_num
;
uint32_t
pic_hdr_size
;
///< picture header size in bytes
uint8_t
frame_flags
;
uint16_t
checksum
;
///< frame checksum
IVIHuffTab
mb_vlc
;
///< vlc table for decoding macroblock data
uint16_t
gop_hdr_size
;
uint8_t
gop_flags
;
int
is_scalable
;
uint32_t
lock_word
;
IVIPicConfig
pic_conf
;
}
IVI5DecContext
;
/**
* Decode Indeo5 GOP (Group of pictures) header.
* This header is present in key frames only.
...
...
@@ -88,7 +57,7 @@ typedef struct {
* @param[in] avctx ptr to the AVCodecContext
* @return result code: 0 = OK, -1 = error
*/
static
int
decode_gop_header
(
IVI5DecContext
*
ctx
,
AVCodecContext
*
avctx
)
static
int
decode_gop_header
(
IVI
4
5DecContext
*
ctx
,
AVCodecContext
*
avctx
)
{
int
result
,
i
,
p
,
tile_size
,
pic_size_indx
,
mb_size
,
blk_size
;
int
quant_mat
,
blk_size_changed
=
0
;
...
...
@@ -318,7 +287,7 @@ static inline void skip_hdr_extension(GetBitContext *gb)
* @param[in] avctx ptr to the AVCodecContext
* @return result code: 0 = OK, -1 = error
*/
static
int
decode_pic_hdr
(
IVI5DecContext
*
ctx
,
AVCodecContext
*
avctx
)
static
int
decode_pic_hdr
(
IVI
4
5DecContext
*
ctx
,
AVCodecContext
*
avctx
)
{
if
(
get_bits
(
&
ctx
->
gb
,
5
)
!=
0x1F
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Invalid picture start code!
\n
"
);
...
...
@@ -371,7 +340,7 @@ static int decode_pic_hdr(IVI5DecContext *ctx, AVCodecContext *avctx)
* @param[in] avctx ptr to the AVCodecContext
* @return result code: 0 = OK, -1 = error
*/
static
int
decode_band_hdr
(
IVI5DecContext
*
ctx
,
IVIBandDesc
*
band
,
static
int
decode_band_hdr
(
IVI
4
5DecContext
*
ctx
,
IVIBandDesc
*
band
,
AVCodecContext
*
avctx
)
{
int
i
;
...
...
@@ -441,7 +410,7 @@ static int decode_band_hdr(IVI5DecContext *ctx, IVIBandDesc *band,
* @param[in] avctx ptr to the AVCodecContext
* @return result code: 0 = OK, -1 = error
*/
static
int
decode_mb_info
(
IVI5DecContext
*
ctx
,
IVIBandDesc
*
band
,
static
int
decode_mb_info
(
IVI
4
5DecContext
*
ctx
,
IVIBandDesc
*
band
,
IVITile
*
tile
,
AVCodecContext
*
avctx
)
{
int
x
,
y
,
mv_x
,
mv_y
,
mv_delta
,
offs
,
mb_offset
,
...
...
@@ -560,102 +529,12 @@ static int decode_mb_info(IVI5DecContext *ctx, IVIBandDesc *band,
}
/**
* Decode an Indeo5 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
(
IVI5DecContext
*
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
=
decode_band_hdr
(
ctx
,
band
,
avctx
);
if
(
result
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Error while decoding band header: %d
\n
"
,
result
);
return
-
1
;
}
if
(
band
->
is_empty
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"Empty band encountered!
\n
"
);
return
-
1
;
}
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
));
}
else
{
tile
->
data_size
=
ff_ivi_dec_tile_data_size
(
&
ctx
->
gb
);
result
=
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
;
}
/**
* Switch buffers.
*
* @param[in,out] ctx ptr to the decoder context
*/
static
void
switch_buffers
(
IVI5DecContext
*
ctx
)
static
void
switch_buffers
(
IVI
4
5DecContext
*
ctx
)
{
switch
(
ctx
->
prev_frame_type
)
{
case
FRAMETYPE_INTRA
:
...
...
@@ -693,12 +572,18 @@ static void switch_buffers(IVI5DecContext *ctx)
}
static
int
is_nonnull_frame
(
IVI45DecContext
*
ctx
)
{
return
ctx
->
frame_type
!=
FRAMETYPE_NULL
;
}
/**
* Initialize Indeo5 decoder.
*/
static
av_cold
int
decode_init
(
AVCodecContext
*
avctx
)
{
IVI5DecContext
*
ctx
=
avctx
->
priv_data
;
IVI
4
5DecContext
*
ctx
=
avctx
->
priv_data
;
int
result
;
ff_ivi_init_static_vlc
();
...
...
@@ -726,97 +611,13 @@ static av_cold int decode_init(AVCodecContext *avctx)
ctx
->
buf_switch
=
0
;
ctx
->
inter_scal
=
0
;
avctx
->
pix_fmt
=
PIX_FMT_YUV410P
;
return
0
;
}
/**
* main decoder function
*/
static
int
decode_frame
(
AVCodecContext
*
avctx
,
void
*
data
,
int
*
data_size
,
AVPacket
*
avpkt
)
{
IVI5DecContext
*
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
=
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
->
decode_pic_hdr
=
decode_pic_hdr
;
ctx
->
decode_band_hdr
=
decode_band_hdr
;
ctx
->
decode_mb_info
=
decode_mb_info
;
ctx
->
switch_buffers
=
switch_buffers
;
ctx
->
is_nonnull_frame
=
is_nonnull_frame
;
switch_buffers
(
ctx
);
//{ START_TIMER;
if
(
ctx
->
frame_type
!=
FRAMETYPE_NULL
)
{
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
(
ctx
->
frame
.
data
[
0
])
avctx
->
release_buffer
(
avctx
,
&
ctx
->
frame
);
ctx
->
frame
.
reference
=
0
;
if
(
avctx
->
get_buffer
(
avctx
,
&
ctx
->
frame
)
<
0
)
{
av_log
(
avctx
,
AV_LOG_ERROR
,
"get_buffer() failed
\n
"
);
return
-
1
;
}
if
(
ctx
->
is_scalable
)
{
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.
*/
static
av_cold
int
decode_close
(
AVCodecContext
*
avctx
)
{
IVI5DecContext
*
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
);
avctx
->
pix_fmt
=
PIX_FMT_YUV410P
;
return
0
;
}
...
...
@@ -826,9 +627,9 @@ AVCodec ff_indeo5_decoder = {
.
name
=
"indeo5"
,
.
type
=
AVMEDIA_TYPE_VIDEO
,
.
id
=
CODEC_ID_INDEO5
,
.
priv_data_size
=
sizeof
(
IVI5DecContext
),
.
priv_data_size
=
sizeof
(
IVI
4
5DecContext
),
.
init
=
decode_init
,
.
close
=
decode_close
,
.
decode
=
decode_frame
,
.
close
=
ff_ivi_
decode_close
,
.
decode
=
ff_ivi_
decode_frame
,
.
long_name
=
NULL_IF_CONFIG_SMALL
(
"Intel Indeo Video Interactive 5"
),
};
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