Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
vlc-2-2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
videolan
vlc-2-2
Commits
e229f269
Commit
e229f269
authored
Dec 28, 1999
by
Christophe Massiot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Suite du video_parser et du video_decoder.
parent
ce68167e
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
1507 additions
and
549 deletions
+1507
-549
include/video_decoder.h.new
include/video_decoder.h.new
+63
-0
include/video_fifo.h
include/video_fifo.h
+10
-10
include/video_parser.h
include/video_parser.h
+34
-78
include/vpar_blocks.h
include/vpar_blocks.h
+90
-9
include/vpar_headers.h
include/vpar_headers.h
+141
-0
src/video_decoder/vdec_idct.c
src/video_decoder/vdec_idct.c
+65
-0
src/video_decoder/vdec_motion.c
src/video_decoder/vdec_motion.c
+51
-48
src/video_decoder/video_decoder.c
src/video_decoder/video_decoder.c
+86
-77
src/video_parser/video_fifo.c
src/video_parser/video_fifo.c
+69
-98
src/video_parser/video_parser.c
src/video_parser/video_parser.c
+16
-10
src/video_parser/vpar_blocks.c
src/video_parser/vpar_blocks.c
+417
-0
src/video_parser/vpar_headers.c
src/video_parser/vpar_headers.c
+411
-219
src/video_parser/vpar_motion.c
src/video_parser/vpar_motion.c
+54
-0
No files found.
include/video_decoder.h.new
0 → 100644
View file @
e229f269
/*****************************************************************************
* video_decoder.h : video decoder thread
* (c)1999 VideoLAN
*****************************************************************************
*****************************************************************************
* Requires:
* "config.h"
* "common.h"
* "mtime.h"
* "vlc_thread.h"
* "input.h"
* "video.h"
* "video_output.h"
* "decoder_fifo.h"
*****************************************************************************/
/*****************************************************************************
* vdec_thread_t: video decoder thread descriptor
*****************************************************************************
* ??
*****************************************************************************/
typedef struct vdec_thread_s
{
/* Thread properties and locks */
boolean_t b_die; /* `die' flag */
boolean_t b_run; /* `run' flag */
boolean_t b_error; /* `error' flag */
boolean_t b_active; /* `active' flag */
vlc_thread_t thread_id; /* id for thread functions */
/* Thread configuration */
/* ?? */
/*??*/
// int *pi_status;
/* Input properties */
video_parser_t * p_vpar; /* video_parser thread */
#ifdef STATS
/* Statistics */
count_t c_loops; /* number of loops */
count_t c_idle_loops; /* number of idle loops */
count_t c_decoded_pictures; /* number of pictures decoded */
count_t c_decoded_i_pictures; /* number of I pictures decoded */
count_t c_decoded_p_pictures; /* number of P pictures decoded */
count_t c_decoded_b_pictures; /* number of B pictures decoded */
#endif
} vdec_thread_t;
/*****************************************************************************
* Prototypes
*****************************************************************************/
/* Thread management functions */
vdec_thread_t * vdec_CreateThread ( vpar_thread_t *p_vpar /*, int *pi_status */ );
void vdec_DestroyThread ( vdec_thread_t *p_vdec /*, int *pi_status */ );
/* Time management functions */
/* ?? */
/* Dynamic thread settings */
/* ?? */
include/video_fifo.h
View file @
e229f269
...
...
@@ -29,7 +29,7 @@
/*****************************************************************************
* video_fifo_t
*****************************************************************************
* This rotative FIFO contains undecoded
picture
s that are to be decoded
* This rotative FIFO contains undecoded
macroblock
s that are to be decoded
*****************************************************************************/
typedef
struct
video_fifo_s
{
...
...
@@ -37,7 +37,7 @@ typedef struct video_fifo_s
vlc_cond_t
wait
;
/* fifo data conditional variable */
/* buffer is an array of undec_picture_t pointers */
undec_picture_t
*
buffer
[
VFIFO_SIZE
+
1
];
macroblock_t
*
buffer
[
VFIFO_SIZE
+
1
];
int
i_start
;
int
i_end
;
...
...
@@ -48,22 +48,22 @@ typedef struct video_fifo_s
* video_buffer_t
*****************************************************************************
* This structure enables the parser to maintain a list of free
*
undec_picture
_t structures
*
macroblock
_t structures
*****************************************************************************/
typedef
struct
video_buffer_s
{
vlc_mutex_t
lock
;
/* buffer data lock */
undec_picture_t
p_undec_p
[
VFIFO_SIZE
+
1
];
undec_picture_t
*
pp_undec_free
[
VFIFO_SIZE
+
1
];
/* this is a LIFO */
macroblock_t
p_macroblocks
[
VFIFO_SIZE
+
1
];
macroblock_t
*
pp_mb_free
[
VFIFO_SIZE
+
1
];
/* this is a LIFO */
int
i_index
;
}
video_buffer_t
;
/*****************************************************************************
* Prototypes
*****************************************************************************/
undec_picture_t
*
vpar_GetPicture
(
video_fifo_t
*
p_fifo
);
undec_picture_t
*
vpar_NewPicture
(
video_fifo_t
*
p_fifo
);
void
vpar_Decode
Picture
(
video_fifo_t
*
p_fifo
,
undec_picture_t
*
p_undec_p
);
void
vpar_Release
Picture
(
video_fifo_t
*
p_fifo
,
undec_picture_t
*
p_undec_p
);
void
vpar_Destroy
Picture
(
video_fifo_t
*
p_fifo
,
undec_picture_t
*
p_undec_p
);
macroblock_t
*
vpar_GetMacroblock
(
video_fifo_t
*
p_fifo
);
macroblock_t
*
vpar_NewMacroblock
(
video_fifo_t
*
p_fifo
);
void
vpar_Decode
Macroblock
(
video_fifo_t
*
p_fifo
,
macroblock_t
*
p_mb
);
void
vpar_Release
Macroblock
(
video_fifo_t
*
p_fifo
,
macroblock_t
*
p_mb
);
void
vpar_Destroy
Macroblock
(
video_fifo_t
*
p_fifo
,
macroblock_t
*
p_mb
);
include/video_parser.h
View file @
e229f269
/*****************************************************************************
**
/*****************************************************************************
* video_parser.h : video parser thread
* (c)1999 VideoLAN
*****************************************************************************
**
*****************************************************************************
**
*****************************************************************************
*****************************************************************************
* Requires:
* "config.h"
* "common.h"
...
...
@@ -13,44 +13,22 @@
* "video_output.h"
* "decoder_fifo.h"
* "video_fifo.h"
*******************************************************************************/
* "vpar_headers.h"
*****************************************************************************/
/*******************************************************************************
* sequence_t : sequence descriptor
*******************************************************************************
* ??
*******************************************************************************/
typedef
struct
sequence_s
{
u16
i_height
,
i_width
;
u16
i_mb_height
,
i_mb_width
;
unsigned
int
i_aspect_ratio
;
double
d_frame_rate
;
unsigned
int
i_chroma_format
;
boolean_t
b_mpeg2
;
boolean_t
b_progressive
;
/* Parser context */
picture_t
*
p_forward
,
p_backward
;
pel_lookup_table_t
*
p_frame_lum_lookup
,
p_field_lum_lookup
;
pel_lookup_table_t
*
p_frame_chroma_lookup
,
p_field_chroma_lookup
;
quant_matrix_t
intra_quant
,
nonintra_quant
;
quant_matrix_t
chroma_intra_quant
,
chroma_nonintra_quant
;
}
sequence_t
;
/*******************************************************************************
/*****************************************************************************
* vpar_thread_t: video parser thread descriptor
*****************************************************************************
**
*****************************************************************************
* ??
*****************************************************************************
**
/
*****************************************************************************/
typedef
struct
vpar_thread_s
{
/* Thread properties and locks */
boolean_t
b_die
;
/* `die' flag */
boolean_t
b_run
;
/* `run' flag */
boolean_t
b_error
;
/* `error' flag */
boolean_t
b_active
;
/* `active' flag */
vlc_thread_t
thread_id
;
/* id for thread functions */
boolean_t
b_die
;
/* `die' flag */
boolean_t
b_run
;
/* `run' flag */
boolean_t
b_error
;
/* `error' flag */
boolean_t
b_active
;
/* `active' flag */
vlc_thread_t
thread_id
;
/* id for thread functions */
/* Thread configuration */
/* ?? */
...
...
@@ -59,67 +37,45 @@ typedef struct vpar_thread_s
/* Input properties */
decoder_fifo_t
fifo
;
/* PES input fifo */
decoder_fifo_t
fifo
;
/* PES input fifo */
/* The bit stream structure handles the PES stream at the bit level */
bit_stream_t
bit_stream
;
/* Output properties */
vout_thread_t
*
p_vout
;
/* video output thread */
int
i_stream
;
/* video stream id */
vout_thread_t
*
p_vout
;
/* video output thread */
int
i_stream
;
/* video stream id */
/* Decoder properties */
struct
vdec_thread_s
*
p_vdec
[
MAX
_VDEC
];
struct
vdec_thread_s
*
p_vdec
[
NB
_VDEC
];
video_fifo_t
vfifo
;
video_buffer_t
vbuffer
;
/* Parser properties */
sequence_t
sequence
;
sequence_t
sequence
;
picture_parsing_t
picture
;
slice_parsing_t
slice
;
macroblock_parsing_t
mb
;
#ifdef STATS
/* Statistics */
count_t
c_loops
;
/* number of loops */
count_t
c_idle_loops
;
/* number of idle loops */
count_t
c_sequences
;
/* number of sequences */
count_t
c_pictures
;
/* number of pictures read */
count_t
c_i_pictures
;
/* number of I pictures read */
count_t
c_p_pictures
;
/* number of P pictures read */
count_t
c_b_pictures
;
/* number of B pictures read */
count_t
c_decoded_pictures
;
/* number of pictures decoded */
count_t
c_decoded_i_pictures
;
/* number of I pictures decoded */
count_t
c_decoded_p_pictures
;
/* number of P pictures decoded */
count_t
c_decoded_b_pictures
;
/* number of B pictures decoded */
count_t
c_loops
;
/* number of loops */
count_t
c_idle_loops
;
/* number of idle loops */
count_t
c_sequences
;
/* number of sequences */
count_t
c_pictures
;
/* number of pictures read */
count_t
c_i_pictures
;
/* number of I pictures read */
count_t
c_p_pictures
;
/* number of P pictures read */
count_t
c_b_pictures
;
/* number of B pictures read */
count_t
c_decoded_pictures
;
/* number of pictures decoded */
count_t
c_decoded_i_pictures
;
/* number of I pictures decoded */
count_t
c_decoded_p_pictures
;
/* number of P pictures decoded */
count_t
c_decoded_b_pictures
;
/* number of B pictures decoded */
#endif
}
vpar_thread_t
;
/*******************************************************************************
* Standard start codes
*******************************************************************************/
#define PICTURE_START_CODE 0x100
#define SLICE_START_CODE_MIN 0x101
#define SLICE_START_CODE_MAX 0x1AF
#define USER_DATA_START_CODE 0x1B2
#define SEQUENCE_HEADER_CODE 0x1B3
#define SEQUENCE_ERROR_CODE 0x1B4
#define EXTENSION_START_CODE 0x1B5
#define SEQUENCE_END_CODE 0x1B7
#define GROUP_START_CODE 0x1B8
/* extension start code IDs */
#define SEQUENCE_EXTENSION_ID 1
#define SEQUENCE_DISPLAY_EXTENSION_ID 2
#define QUANT_MATRIX_EXTENSION_ID 3
#define COPYRIGHT_EXTENSION_ID 4
#define SEQUENCE_SCALABLE_EXTENSION_ID 5
#define PICTURE_DISPLAY_EXTENSION_ID 7
#define PICTURE_CODING_EXTENSION_ID 8
#define PICTURE_SPATIAL_SCALABLE_EXTENSION_ID 9
#define PICTURE_TEMPORAL_SCALABLE_EXTENSION_ID 10
/*******************************************************************************
/*****************************************************************************
* Prototypes
*****************************************************************************
**
/
*****************************************************************************/
/* Thread management functions */
vpar_thread_t
*
vpar_CreateThread
(
/* video_cfg_t *p_cfg, */
input_thread_t
*
p_input
/*,
...
...
include/vpar_blocks.h
View file @
e229f269
...
...
@@ -16,16 +16,97 @@
*****************************************************************************/
/*****************************************************************************
* quant_matrix_t : Quantization Matrix
* macroblock_t : information on a macroblock
*****************************************************************************/
typedef
struct
macroblock_s
{
picture_t
*
p_picture
;
int
i_mb_x
,
i_mb_y
;
int
i_structure
;
int
i_l_x
,
i_l_y
;
/* position of macroblock (lum) */
int
i_c_x
,
i_c_y
;
/* position of macroblock (chroma) */
int
i_structure
;
int
i_chroma_nb_blocks
;
/* nb of bks for a chr comp */
/* IDCT information */
elem_t
ppi_blocks
[
12
][
64
];
/* blocks */
f_idct_t
pf_idct
[
12
];
/* sparse IDCT or not ? */
int
pi_sparse_pos
[
12
];
/* Motion compensation information */
f_motion_t
pf_motion
;
/* function to use for motion comp */
f_chroma_motion_t
pf_chroma_motion
;
picture_t
*
p_backw_top
,
p_backw_bot
;
picture_t
*
p_forw_top
,
p_forw_bot
;
int
i_field_select_backw_top
,
i_field_select_backw_bot
;
int
i_field_select_forw_top
,
i_field_select_forw_bot
;
int
pi_motion_vectors_backw_top
[
2
];
int
pi_motion_vectors_backw_bot
[
2
];
int
pi_motion_vectors_forw_top
[
2
];
int
pi_motion_vectors_forw_bot
[
2
];
/* AddBlock information */
f_addb_t
pf_addb
[
12
];
data_t
*
p_data
[
12
];
/* positions of blocks in picture */
int
i_lum_incr
,
i_chroma_incr
;
}
macroblock_t
;
/*****************************************************************************
* macroblock_parsing_t : parser context descriptor #3
*****************************************************************************/
typedef
struct
{
int
i_mb_type
,
i_motion_type
,
i_mv_count
,
i_mv_format
;
int
i_coded_block_pattern
;
boolean_t
b_dct_type
;
}
macroblock_parsing_t
;
/*****************************************************************************
* LoadQuantizerScale
*****************************************************************************
*
??
*
Quantizer scale factor (ISO/IEC 13818-2 7.4.2.2)
*****************************************************************************/
typedef
struct
quant_matrix_s
static
__inline__
void
LoadQuantizerScale
(
vpar_thread_t
*
p_vpar
)
{
int
pi_matrix
[
64
];
boolean_t
b_allocated
;
/* Has the matrix been allocated by vpar_headers ? */
}
quant_matrix_t
;
/* Quantization coefficient table */
static
unsigned
char
ppi_quantizer_scale
[
3
][
32
]
=
{
/* MPEG-2 */
{
/* q_scale_type */
/* linear */
0
,
2
,
4
,
6
,
8
,
10
,
12
,
14
,
16
,
18
,
20
,
22
,
24
,
26
,
28
,
30
,
32
,
34
,
36
,
38
,
40
,
42
,
44
,
46
,
48
,
50
,
52
,
54
,
56
,
58
,
60
,
62
},
{
/* non-linear */
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
10
,
12
,
14
,
16
,
18
,
20
,
22
,
24
,
28
,
32
,
36
,
40
,
44
,
48
,
52
,
56
,
64
,
72
,
80
,
88
,
96
,
104
,
112
},
/* MPEG-1 */
{
0
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
,
18
,
19
,
20
,
21
,
22
,
23
,
24
,
25
,
26
,
27
,
28
,
29
,
30
,
31
}
};
p_vpar
->
slice
.
i_quantizer_scale
=
ppi_quantizer_scale
[(
!
p_vpar
->
sequence
.
b_mpeg2
<<
1
)
|
p_vpar
->
picture
.
b_q_scale_type
]
[
GetBits
(
&
p_vpar
->
bit_stream
,
5
)];
}
/*****************************************************************************
* Standard codes
*****************************************************************************/
/* Macroblock types */
#define MB_INTRA 1
#define MB_PATTERN 2
#define MB_MOTION_BACKWARD 4
#define MB_MOTION_FORWARD 8
#define MB_QUANT 16
extern
int
*
pi_default_intra_quant
;
extern
int
*
pi_default_nonintra_quant
;
/* Motion types */
#define MOTION_FIELD 1
#define MOTION_FRAME 2
#define MOTION_16X8 2
#define MOTION_DMV 3
include/vpar_headers.h
0 → 100644
View file @
e229f269
/*****************************************************************************
* vpar_headers.h : video parser : headers parsing
* (c)1999 VideoLAN
*****************************************************************************
*****************************************************************************
* Requires:
* "config.h"
* "common.h"
* "mtime.h"
* "vlc_thread.h"
* "input.h"
* "video.h"
* "video_output.h"
* "decoder_fifo.h"
* "video_fifo.h"
*****************************************************************************/
/*****************************************************************************
* Function pointers
*****************************************************************************/
typedef
(
void
*
)
f_slice_header_t
(
vpar_thread_t
*
,
int
*
,
int
,
elem_t
*
,
u32
);
/*****************************************************************************
* quant_matrix_t : Quantization Matrix
*****************************************************************************/
typedef
struct
quant_matrix_s
{
int
pi_matrix
[
64
];
boolean_t
b_allocated
;
/* Has the matrix been allocated by vpar_headers ? */
}
quant_matrix_t
;
extern
int
*
pi_default_intra_quant
;
extern
int
*
pi_default_nonintra_quant
;
/*****************************************************************************
* sequence_t : sequence descriptor
*****************************************************************************/
typedef
struct
sequence_s
{
u32
i_height
,
i_width
,
i_chroma_width
,
i_size
;
u32
i_mb_height
,
i_mb_width
,
i_mb_size
;
unsigned
int
i_aspect_ratio
;
double
d_frame_rate
;
unsigned
int
i_chroma_format
;
int
i_chroma_nb_blocks
;
boolean_t
b_mpeg2
;
boolean_t
b_progressive
;
unsigned
int
i_scalable_mode
;
f_slice_header_t
pf_slice_header
;
quant_matrix_t
intra_quant
,
nonintra_quant
;
quant_matrix_t
chroma_intra_quant
,
chroma_nonintra_quant
;
(
void
*
)
pf_decode_mv
(
vpar_thread_t
*
,
int
);
(
void
*
)
pf_decode_pattern
(
vpar_thread_t
*
);
/* Parser context */
picture_t
*
p_forward
,
p_backward
;
}
sequence_t
;
/*****************************************************************************
* picture_parsing_t : parser context descriptor
*****************************************************************************/
typedef
struct
picture_parsing_s
{
boolean_t
b_full_pel_forward_vector
,
b_full_pel_backward_vector
;
int
i_forward_f_code
,
i_backward_f_code
;
int
ppi_f_code
[
2
][
2
];
int
i_intra_dc_precision
;
boolean_t
b_frame_pred_frame_dct
,
b_q_scale_type
;
boolean_t
b_alternate_scan
,
b_progressive_frame
;
boolean_t
b_top_field_first
,
b_concealment_mv
;
int
i_lum_incr
,
i_chroma_incr
;
/* Used for second field management */
int
i_current_structure
;
picture_t
*
p_picture
;
macroblock_t
*
pp_mb
[
MAX_MB
];
/* Relative to the current field */
int
i_coding_type
,
i_structure
;
boolean_t
b_frame_structure
;
(
int
*
)
pf_macroblock_type
(
vpar_thread_t
*
);
boolean_t
b_error
;
}
picture_parsing_t
;
/*****************************************************************************
* slice_parsing_t : parser context descriptor #2
*****************************************************************************/
typedef
struct
slice_parsing_s
{
unsigned
char
i_quantizer_scale
;
int
pi_dc_dct_pred
[
3
];
/* ISO/IEC 13818-2 7.2.1 */
int
pppi_pmv
[
2
][
2
][
2
];
/* Motion vect predictors, 7.6.3 */
}
slice_parsing_t
;
/*****************************************************************************
* Standard codes
*****************************************************************************/
#define PICTURE_START_CODE 0x100
#define SLICE_START_CODE_MIN 0x101
#define SLICE_START_CODE_MAX 0x1AF
#define USER_DATA_START_CODE 0x1B2
#define SEQUENCE_HEADER_CODE 0x1B3
#define SEQUENCE_ERROR_CODE 0x1B4
#define EXTENSION_START_CODE 0x1B5
#define SEQUENCE_END_CODE 0x1B7
#define GROUP_START_CODE 0x1B8
/* extension start code IDs */
#define SEQUENCE_EXTENSION_ID 1
#define SEQUENCE_DISPLAY_EXTENSION_ID 2
#define QUANT_MATRIX_EXTENSION_ID 3
#define COPYRIGHT_EXTENSION_ID 4
#define SEQUENCE_SCALABLE_EXTENSION_ID 5
#define PICTURE_DISPLAY_EXTENSION_ID 7
#define PICTURE_CODING_EXTENSION_ID 8
#define PICTURE_SPATIAL_SCALABLE_EXTENSION_ID 9
#define PICTURE_TEMPORAL_SCALABLE_EXTENSION_ID 10
/* scalable modes */
#define SC_NONE 0
#define SC_DP 1
#define SC_SPAT 2
#define SC_SNR 3
#define SC_TEMP 4
/* Pictures types */
#define I_CODING_TYPE 1
#define P_CODING_TYPE 2
#define B_CODING_TYPE 3
#define D_CODING_TYPE 4
/* MPEG-1 ONLY */
/* other values are reserved */
/* Structures */
#define TOP_FIELD 1
#define BOTTOM_FIELD 2
#define FRAME_STRUCTURE 3
src/video_decoder/vdec_idct.c
0 → 100644
View file @
e229f269
/*****************************************************************************
* vdec_idct.c : IDCT functions
* (c)1999 VideoLAN
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/uio.h>
#include <X11/Xlib.h>
#include <X11/extensions/XShm.h>
#include "config.h"
#include "common.h"
#include "mtime.h"
#include "vlc_thread.h"
#include "intf_msg.h"
#include "debug.h"
/* ?? temporaire, requis par netlist.h */
#include "input.h"
#include "input_netlist.h"
#include "decoder_fifo.h"
#include "video.h"
#include "video_output.h"
#include "video_parser.h"
#include "undec_picture.h"
#include "video_fifo.h"
#include "video_decoder.h"
/*
* Local prototypes
*/
/* Our current implementation is a fast DCT, we might move to a fast DFT or
* an MMX DCT in the future. */
/*****************************************************************************
* vdec_DummyIDCT : dummy function that does nothing
*****************************************************************************/
void
vdec_DummyIDCT
(
elem_t
*
p_block
,
int
i_idontcare
)
{
}
/*****************************************************************************
* vdec_SparseIDCT : IDCT function for sparse matrices
*****************************************************************************/
void
vdec_SparseIDCT
(
elem_t
*
p_block
,
int
i_sparse_pos
)
{
/* Copy from mpeg_play */
}
/*****************************************************************************
* vdec_IDCT : IDCT function for normal matrices
*****************************************************************************/
void
vdec_IDCT
(
elem_t
*
p_block
,
int
i_idontcare
)
{
}
src/video_decoder/vdec_motion.c
View file @
e229f269
...
...
@@ -3,8 +3,6 @@
* (c)1999 VideoLAN
*****************************************************************************/
/* ?? passer en terminate/destroy avec les signaux supplmentaires */
/*****************************************************************************
* Preamble
*****************************************************************************/
...
...
@@ -40,52 +38,46 @@
* Local prototypes
*/
typedef
(
void
*
)
f_motion_c_t
(
coeff_t
*
,
pel_lookup_table_t
*
,
int
,
coeff_t
*
,
int
,
int
,
int
,
int
,
int
,
int
,
int
);
/*****************************************************************************
* vdec_
MotionCompensation : motion compensation
* vdec_
DummyRecon : motion compensation for an intra macroblock
*****************************************************************************/
void
vdec_MotionFrame
(
vdec_thread_t
*
p_vdec
,
undec_picture_t
*
p_undec_p
,
int
i_mb
,
f_motion_mb_t
pf_mb_motion
)
void
vdec_DummyRecon
(
macroblock_t
*
p_mb
)
{
static
int
p_chroma_nb_blocks
[
4
]
=
{
1
,
2
,
4
};
static
int
p_chroma_nb_elems
[
4
]
=
{
0
,
64
,
128
,
256
};
}
int
i_mb_x
,
i_mb_y
;
/* Position of our macroblock in the final picture */
elem_t
*
p_y
,
p_u
,
p_v
;
/* Pointers to our picture's data */
/*****************************************************************************
* vdec_ForwardRecon : motion compensation for a forward predicted macroblock
*****************************************************************************/
void
vdec_ForwardRecon
(
macroblock_t
*
p_mb
)
{
}
/*****************************************************************************
* vdec_BackwardRecon : motion compensation for a backward predicted macroblock
*****************************************************************************/
void
vdec_BackwardRecon
(
macroblock_t
*
p_mb
)
{
#define P_mb_info p_undec_p->p_mb_info[i_mb]
i_mb_x
=
(
i_mb
<<
5
)
%
p_undec_p
->
p_picture
->
i_width
;
i_mb_y
=
(
i_mb
<<
5
)
/
p_undec_p
->
p_picture
->
i_width
;
p_y
=
&
p_undec_p
->
p_picture
->
p_y
[
256
*
i_mb
];
p_u
=
&
p_undec_p
->
p_picture
->
p_u
[
p_chroma_nb_elems
[
p_undec_p
->
p_picture
->
i_chroma_type
]
*
i_mb
];
p_v
=
&
p_undec_p
->
p_picture
->
p_v
[
p_chroma_nb_elems
[
p_undec_p
->
p_picture
->
i_chroma_type
]
*
i_mb
];
if
(
(
p_undec_p
->
i_coding_type
==
P_CODING_TYPE
)
||
(
P_mb_info
->
i_mb_type
&
MB_MOTION_FORWARD
)
)
{
if
(
(
P_mb_info
->
i_motion_type
==
MOTION_FRAME
)
||
!
(
P_mb_info
->
i_mb_type
&
MB_INTRA
)
)
{
MotionBlock
(
p_undec_p
->
p_forward
->
p_u
,
p_undec_p
->
p_forward
->
p_lookup_lum
,
p_undec_p
->
p_picture
->
i_width
,
p_u
,
i_mb_x
,
i_mb_y
,
p_undec_p
->
p_picture
->
i_width
,
p_undec_p
->
ppp_motion_vectors
[
0
][
0
][
0
],
p_undec_p
->
ppp_motion_vectors
[
0
][
0
][
1
]
);
}
}
}
/*****************************************************************************
* MotionMacroblock : motion compensation for a macroblock
* vdec_BidirectionalRecon : motion compensation for a bidirectionally
* predicted macroblock
*****************************************************************************/
void
vdec_MotionMacroblock420
(
coeff_t
*
p_src
,
pel_lookup_table_t
*
p_lookup
,
int
i_width_line
,
coeff_t
*
p_dest
,
int
i_dest_x
,
i_dest_y
,
int
i_stride_line
,
i_mv1_x
,
i_mv1_y
,
i_mv2_x
,
i_mv2_y
)
void
vdec_BidirectionalRecon
(
macroblock_t
*
p_mb
)
{
}
/*****************************************************************************
* vdec_MotionMacroblock420 : motion compensation for a 4:2:0 macroblock
*****************************************************************************/
void
vdec_MotionMacroblock420
(
macroblock_t
*
p_mb
)
{
/* Luminance */
MotionBlock
(
p_undec_p
->
p_forward
->
p_u
,
p_undec_p
->
p_forward
->
p_lookup_lum
,
...
...
@@ -105,12 +97,9 @@ void __inline__ MotionBlock( coeff_t * p_src, pel_lookup_table_t * p_lookup,
int
i_stride_line
,
i_mv1_x
,
i_mv1_y
,
i_mv2_x
,
i_mv2_y
)
{
static
(
void
*
)
ComponentMode
(
coeff_t
*
p_src
,
pel_lookup_table_t
*
p_lookup
,
coeff_t
*
p_dest
,
int
i_dest_x
,
i_dest_y
,
int
i_stride_line
,
i_mv_x
,
i_mv_y
)[
4
]
=
{
ComponentNN
,
ComponentNH
,
ComponentHN
,
ComponentHH
};
static
f_motion_c_t
ComponentMode
[
4
]
=
{
&
ComponentNN
,
&
ComponentNH
,
&
ComponentHN
,
&
ComponentHH
};
int
i_mode
;
...
...
@@ -118,7 +107,8 @@ void __inline__ MotionBlock( coeff_t * p_src, pel_lookup_table_t * p_lookup,
ComponentMode
[
i_mode
](
p_src
,
p_lookup
,
i_width_line
,
p_dest
,
i_dest_x
,
i_dest_y
,
i_stride_line
,
i_mv_x
>>
1
,
i_mv_y
>>
1
);
i_stride_line
,
i_mv1_x
>>
1
,
i_mv1_y
>>
1
,
i_mv2_x
>>
1
,
i_mv2_y
>>
1
);
}
/*****************************************************************************
...
...
@@ -132,9 +122,22 @@ void ComponentNN( coeff_t * p_src, pel_lookup_table_t * p_lookup,
int
i_vpos
;
register
int
i_hpos
,
i_src_loc
;
i_src_loc
=
(
i_dest_y
+
i_mv
_y
)
*
i_width_line
+
i_dest_x
+
i_mv
_x
;
i_src_loc
=
(
i_dest_y
+
i_mv
1_y
)
*
i_width_line
+
i_dest_x
+
i_mv1
_x
;
for
(
i_vpos
=
0
;
i_vpos
<
8
;
i_vpos
++
)
for
(
i_vpos
=
0
;
i_vpos
<
4
;
i_vpos
++
)
{
for
(
i_hpos
=
0
;
i_hpos
<
8
;
i_hpos
++
)
{
p_dest
[
i_hpos
]
+=
p_src
[
p_lookup
->
pi_pel
[
i_src_loc
+
i_hpos
]];
}
p_dest
+=
8
;
i_src_loc
+=
i_stride_line
;
}
i_src_loc
=
(
i_dest_y
+
i_mv2_y
)
*
i_width_line
+
i_dest_x
+
i_mv2_x
;
for
(
i_vpos
=
4
;
i_vpos
<
8
;
i_vpos
++
)
{
for
(
i_hpos
=
0
;
i_hpos
<
8
;
i_hpos
++
)
{
...
...
src/video_decoder/video_decoder.c
View file @
e229f269
...
...
@@ -43,8 +43,8 @@ static int InitThread ( vdec_thread_t *p_vdec );
static
void
RunThread
(
vdec_thread_t
*
p_vdec
);
static
void
ErrorThread
(
vdec_thread_t
*
p_vdec
);
static
void
EndThread
(
vdec_thread_t
*
p_vdec
);
static
void
Decode
Picture
(
vdec_thread_t
*
p_vdec
,
undec_picture_t
*
p_undec_p
);
static
void
Decode
Macroblock
(
vdec_thread_t
*
p_vdec
,
macroblock_t
*
p_mb
);
/*******************************************************************************
* vdec_CreateThread: create a video decoder thread
...
...
@@ -165,11 +165,11 @@ static void RunThread( vdec_thread_t *p_vdec )
*/
while
(
(
!
p_vdec
->
b_die
)
&&
(
!
p_vdec
->
b_error
)
)
{
undec_picture_t
*
p_undec_p
;
macroblock_t
*
p_mb
;
if
(
(
p_
undec_p
=
GetPicture
(
p_vdec
->
p_vpar
->
p_
fifo
))
!=
NULL
)
if
(
(
p_
mb
=
GetMacroblock
(
&
p_vdec
->
p_vpar
.
v
fifo
))
!=
NULL
)
{
Decode
Picture
(
p_vdec
,
p_undec_p
);
Decode
Macroblock
(
p_vdec
,
p_mb
);
}
}
...
...
@@ -220,92 +220,101 @@ static void EndThread( vdec_thread_t *p_vdec )
}
/*******************************************************************************
* Decode
Picture : decode
a picture
* Decode
Macroblock : decode a macroblock of
a picture
*******************************************************************************/
static
void
Decode
Picture
(
vdec_thread_t
*
p_vdec
,
undec_picture_t
*
p_undec_p
)
static
void
Decode
Macroblock
(
vdec_thread_t
*
p_vdec
,
macroblock_t
*
p_mb
)
{
static
int
pi_chroma_nb_blocks
[
4
]
=
{
0
,
1
,
2
,
4
};
static
int
pi_chroma_nb_coeffs
[
4
]
=
{
0
,
64
,
128
,
256
};
static
f_motion_mb_t
ppf_chroma_motion
[
4
]
=
{
NULL
,
&
vdec_MotionMacroBlock420
,
&
vdec_MotionMacroBlock422
,
&
vdec_MotionMacroBlock444
};
static
f_motion_t
pppf_motion_forward
[
4
][
2
]
=
{
{
NULL
,
NULL
}
/* I picture */
{
&
vdec_MotionForward
,
&
vdec_MotionForward
}
/* P */
{
NULL
,
&
vdec_MotionForward
}
/* B */
{
NULL
,
NULL
}
/* D */
};
static
f_motion_t
pppf_motion_backward
[
4
][
2
]
=
{
{
NULL
,
NULL
}
/* I picture */
{
NULL
,
NULL
}
/* P */
{
NULL
,
&
vdec_MotionBackward
}
/* B */
{
NULL
,
NULL
}
/* D */
};
static
f_motion_t
ppf_motion
[
4
]
=
{
NULL
,
&
vdec_MotionTopFirst
,
&
vdec_MotionBottomFirst
,
&
vdec_MotionFrame
};
int
i_mb
,
i_b
,
i_totb
;
coeff_t
*
p_y
,
p_u
,
p_v
;
f_motion_mb_t
pf_chroma_motion
;
f_motion_t
pf_motion_forward
,
pf_motion_backward
;
int
i_chroma_nb_blocks
,
i_chroma_nb_coeffs
;
p_y
=
(
coeff_t
*
)
p_undec_p
->
p_picture
->
p_y
;
p_u
=
(
coeff_t
*
)
p_undec_p
->
p_picture
->
p_u
;
p_v
=
(
coeff_t
*
)
p_undec_p
->
p_picture
->
p_v
;
#define I_chroma_format p_undec_p->p_picture->i_chroma_format
pf_chroma_motion
=
ppf_chroma_motion
[
I_chroma_format
];
pf_motion_forward
pf_motion
=
ppf_motion
[
p_undec_p
->
i_structure
];
int
i_b
;
i_chroma_nb_blocks
=
pi_chroma_nb_blocks
[
I_chroma_format
];
i_chroma_nb_coeffs
=
pi_chroma_nb_coeffs
[
I_chroma_format
];
#undef I_chroma_format
/*
* Motion Compensation (ISO/IEC 13818-2 section 7.6)
*/
(
*
p_mb
->
pf_motion
)(
p_mb
);
for
(
i_mb
=
0
;
i_mb
<
p_undec_p
->
i_mb_height
*
p_undec_p
->
i_mb_width
;
i_mb
++
)
/* luminance */
for
(
i_b
=
0
;
i_b
<
4
;
i_b
++
)
{
#define P_mb_info p_undec_p->p_mb_info[i_ref]
/*
* Inverse DCT (ISO/IEC 13818-2 section Annex A)
*/
/* Luminance : always 4 blocks */
for
(
i_b
=
0
;
i_b
<
4
;
i_b
++
)
{
(
*
P_mb_info
.
p_idct_function
[
i_b
])(
p_y
+
i_b
*
64
);
}
i_totb
=
4
;
/* Chrominance Cr */
for
(
i_b
=
0
;
i_b
<
i_chroma_nb_blocks
;
i_b
++
)
{
(
*
P_mb_info
.
p_idct_function
[
i_totb
+
i_b
])(
p_u
+
i_b
*
64
);
}
i_totb
+=
i_chroma_nb_blocks
;
/* Chrominance Cb */
for
(
i_b
=
0
;
i_b
<
i_chroma_nb_blocks
;
i_b
++
)
{
(
*
P_mb_info
.
p_idct_function
[
i_totb
+
i_b
])(
p_v
+
i_b
*
64
);
}
(
*
p_mb
->
pf_idct
[
i_b
])(
p_mb
,
p_mb
->
ppi_blocks
[
i_b
],
p_mb
->
pi_sparse_pos
[
i_b
]
);
/*
* Adding prediction and coefficient data (ISO/IEC 13818-2 section 7.6.8)
*/
(
*
p_mb
->
pf_addb
[
i_b
])(
p_mb
->
ppi_blocks
[
i_b
],
p_mb
->
p_data
[
i_b
],
p_mb
->
i_lum_incr
);
}
/* chrominance */
for
(
i_b
=
4
;
i_b
<
4
+
2
*
p_mb
->
i_chroma_nb_blocks
;
i_b
++
)
{
/*
*
Motion Compensation (ISO/IEC 13818-2 section 7.6
)
*
Inverse DCT (ISO/IEC 13818-2 section Annex A
)
*/
(
*
p
f_motion
)(
p_vdec
,
p_undec_p
,
i_mb
,
pf_chroma_motion
);
(
*
p
_mb
->
pf_idct
[
i_b
])(
p_mb
,
p_mb
->
ppi_blocks
[
i_b
],
p_mb
->
pi_sparse_pos
[
i_b
]
);
p_y
+=
256
;
p_u
+=
i_chroma_nb_coeffs
;
p_v
+=
i_chroma_nb_coeffs
;
#undef P_mb_info
/*
* Adding prediction and coefficient data (ISO/IEC 13818-2 section 7.6.8)
*/
(
*
p_mb
->
pf_addb
[
i_b
])(
p_mb
->
ppi_blocks
[
i_b
],
p_mb
->
p_data
[
i_b
],
p_mb
->
i_chroma_incr
);
}
/*
* Decoding is finished,
mark the picture ready for displaying
and free
* unneeded memory
* Decoding is finished,
release the macroblock
and free
* unneeded memory
.
*/
vpar_ReleasePicture
(
p_vdec
->
p_vpar
->
p_fifo
,
p_undec_p
);
vpar_ReleaseMacroblock
(
&
p_vdec
->
p_vpar
.
vfifo
,
p_mb
);
}
/*******************************************************************************
* vdec_AddBlock : add a block
*******************************************************************************/
void
vdec_AddBlock
(
elem_t
*
p_block
,
data_t
*
p_data
,
int
i_incr
)
{
int
i_x
,
i_y
;
for
(
i_y
=
0
;
i_y
<
8
;
i_y
++
)
{
for
(
i_x
=
0
;
i_x
<
8
;
i_x
++
)
{
/* ??? Need clip to be MPEG-2 compliant */
*
p_data
++
+=
*
p_block
++
;
}
p_data
+=
i_incr
;
}
}
/*******************************************************************************
* vdec_CopyBlock : copy a block
*******************************************************************************/
void
vdec_CopyBlock
(
elem_t
*
p_block
,
data_t
*
p_data
,
int
i_incr
)
{
int
i_x
,
i_y
;
for
(
i_y
=
0
;
i_y
<
8
;
i_y
++
)
{
#ifndef VDEC_DFT
/* elem_t and data_t are the same */
memcopy
(
p_data
,
p_block
,
8
*
sizeof
(
data_t
)
);
p_data
+=
i_incr
+
8
;
p_block
+=
8
;
#else
for
(
i_x
=
0
;
i_x
<
8
;
i_x
++
)
{
/* ??? Need clip to be MPEG-2 compliant */
/* ??? Why does the reference decoder add 128 ??? */
*
p_data
++
=
*
p_block
++
;
}
p_data
+=
i_incr
;
#endif
}
}
/*******************************************************************************
* vdec_DummyBlock : dummy function that does nothing
*******************************************************************************/
void
vdec_DummyBlock
(
elem_t
*
p_block
,
data_t
*
p_data
,
int
i_incr
)
{
}
src/video_parser/video_fifo.c
View file @
e229f269
...
...
@@ -30,7 +30,7 @@
#include "video_output.h"
#include "video_parser.h"
#include "
undec_picture
.h"
#include "
macroblock
.h"
#include "video_fifo.h"
#include "video_decoder.h"
...
...
@@ -39,7 +39,7 @@
*****************************************************************************/
void
vpar_InitFIFO
(
vpar_thread_t
*
p_vpar
)
{
int
i_dummy
;
int
i_dummy
;
/* Initialize mutex and cond */
vlc_mutex_init
(
p_vpar
->
vfifo
.
lock
);
...
...
@@ -54,17 +54,16 @@ void vpar_InitFIFO( vpar_thread_t * p_vpar )
i_index
=
VFIFO_SIZE
;
/* all structures are available */
for
(
i_dummy
=
0
;
i_dummy
<
VFIFO_SIZE
+
1
;
i_dummy
++
)
{
p_vpar
->
vfifo
.
pp_undec_free
[
i_dummy
]
=
p_vpar
->
vfifo
.
p_undec_p
+
i
;
p_vpar
->
vfifo
.
p_undec_p
[
i
].
p_mb_info
=
NULL
;
p_vpar
->
vfifo
.
pp_mb_free
[
i_dummy
]
=
p_vpar
->
vfifo
.
p_macroblocks
+
i
;
}
}
/*****************************************************************************
* vpar_Get
Picture : return a picture
to be decoded
* vpar_Get
Macroblock : return a macroblock
to be decoded
*****************************************************************************/
undec_picture_t
*
vpar_GetPicture
(
video_fifo_t
*
p_fifo
)
macroblock_t
*
vpar_GetMacroblock
(
video_fifo_t
*
p_fifo
)
{
undec_picture_t
*
p_undec_p
;
macroblock_t
*
p_mb
;
vlc_mutex_lock
(
&
p_fifo
->
lock
);
while
(
VIDEO_FIFO_ISEMPTY
(
*
p_fifo
)
)
...
...
@@ -77,20 +76,20 @@ undec_picture_t * vpar_GetPicture( video_fifo_t * p_fifo )
}
}
p_
undec_p
=
VIDEO_FIFO_START
(
*
p_fifo
);
p_
mb
=
VIDEO_FIFO_START
(
*
p_fifo
);
VIDEO_FIFO_INCSTART
(
*
p_fifo
);
vlc_mutex_unlock
(
&
p_fifo
->
lock
);
return
(
p_
undec_p
);
return
(
p_
mb
);
}
/*****************************************************************************
* vpar_New
Picture
: return a buffer for the parser
* vpar_New
Macroblock
: return a buffer for the parser
*****************************************************************************/
undec_picture_t
*
vpar_NewPicture
(
video_fifo_t
*
p_fifo
)
macroblock_t
*
vpar_NewMacroblock
(
video_fifo_t
*
p_fifo
)
{
undec_picture_t
*
p_undec_p
;
macroblock_t
*
p_mb
;
#define P_buffer p_fifo->p_vpar.vbuffer
vlc_mutex_lock
(
&
P_buffer
->
lock
);
...
...
@@ -100,128 +99,100 @@ undec_picture_t * vpar_NewPicture( video_fifo_t * p_fifo )
return
NULL
;
}
p_
undec_p
=
P_buffer
->
pp_undec_free
[
P_buffer
->
i_index
--
];
p_
mb
=
P_buffer
->
pp_undec_free
[
P_buffer
->
i_index
--
];
#undef P_buffer
vlc_mutex_unlock
(
&
P_buffer
->
lock
);
return
(
p_
undec_p
);
return
(
p_
mb
);
}
/*****************************************************************************
* vpar_Decode
Picture : put a picture in the video fifo, if it is decodable
* vpar_Decode
Macroblock : put a macroblock in the video fifo
*****************************************************************************/
void
vpar_Decode
Picture
(
video_fifo_t
*
p_fifo
,
undec_picture_t
*
p_undec_p
)
void
vpar_Decode
Macroblock
(
video_fifo_t
*
p_fifo
,
macroblock_t
*
p_mb
)
{
boolean_t
b_decodable
;
switch
(
p_undec_p
)
{
case
B_CODING_TYPE
:
b_decodable
=
((
p_undec_p
->
p_backward_p
!=
NULL
)
&&
(
p_undec_p
->
p_forward_p
!=
NULL
));
break
;
case
P_CODING_TYPE
:
b_decodable
=
(
p_undec_p
->
p_backward_p
!=
NULL
);
break
;
case
I_CODING_TYPE
:
case
D_CODING_TYPE
:
b_decodable
=
TRUE
;
break
;
default:
/* That should not happen */
}
if
(
b_decodable
)
{
/* Place picture in the video FIFO */
vlc_mutex_lock
(
&
p_fifo
->
lock
);
/* Place picture in the video FIFO */
vlc_mutex_lock
(
&
p_fifo
->
lock
);
/* By construction, the video FIFO cannot be full */
VIDEO_FIFO_END
(
*
p_fifo
)
=
p_undec_p
;
VIDEO_FIFO_INCEND
(
*
p_fifo
);
/* By construction, the video FIFO cannot be full */
VIDEO_FIFO_END
(
*
p_fifo
)
=
p_mb
;
VIDEO_FIFO_INCEND
(
*
p_fifo
);
vlc_mutex_unlock
(
&
p_fifo
->
lock
);
}
vlc_mutex_unlock
(
&
p_fifo
->
lock
);
}
/*****************************************************************************
* vpar_Release
Picture : put a picture in the video_output fifo, and updat
e
*
links and buffers
* vpar_Release
Macroblock : release a macroblock and put the picture in th
e
*
video output heap, if it is finished
*****************************************************************************/
void
vpar_Release
Picture
(
video_fifo_t
*
p_fifo
,
undec_picture_t
*
p_undec_p
)
void
vpar_Release
Macroblock
(
video_fifo_t
*
p_fifo
,
macroblock_t
*
p_mb
)
{
int
i_ref
;
/* Tell referencing pictures so that they can be decoded */
for
(
i_ref
=
0
;
p_undec_p
->
pp_referencing_undec
[
i_ref
].
p_undec
!=
NULL
&&
i_ref
<
MAX_REFERENCING_UNDEC
;
i_ref
++
)
/* Unlink referenced pictures */
if
(
p_mb
->
p_forw_top
!=
NULL
)
{
*
p_undec_p
->
pp_referencing_undec
[
i_ref
].
pp_frame
=
p_undec_p
->
p_picture
;
vout_LinkPicture
(
p_fifo
->
p_vpar
.
p_vout
,
p_picture
);
/* Try to put the referencing picture in the video FIFO */
vpar_DecodePicture
(
p_fifo
,
p_undec_p
->
pp_referencing_undec
[
i_ref
].
p_undec
);
vout_UnlinkPicture
(
p_fifo
->
p_vpar
.
p_vout
,
p_mb
->
p_forw_top
);
}
if
(
p_mb
->
p_backw_top
!=
NULL
)
{
vout_UnlinkPicture
(
p_fifo
->
p_vpar
.
p_vout
,
p_mb
->
p_backw_top
);
}
if
(
p_mb
->
p_forw_bot
!=
NULL
)
{
vout_UnlinkPicture
(
p_fifo
->
p_vpar
.
p_vout
,
p_mb
->
p_forw_bot
);
}
if
(
p_mb
->
p_backw_bot
!=
NULL
)
{
vout_UnlinkPicture
(
p_fifo
->
p_vpar
.
p_vout
,
p_mb
->
p_backw_bot
);
}
/* Unlink referenced pictures */
if
(
p_undec_p
->
p_forward_ref
!=
NULL
)
/* Unlink picture buffer */
vlc_mutex_lock
(
&
p_mb
->
p_picture
->
lock_deccount
);
p_mb
->
p_picture
->
i_deccount
--
;
if
(
p_mb
->
p_picture
->
i_deccount
==
0
)
{
vout_UnlinkPicture
(
p_fifo
->
p_vpar
.
p_vout
,
p_undec_p
->
p_forward_ref
);
if
(
p_undec_p
->
p_backward_ref
!=
NULL
)
{
vout_UnlinkPicture
(
p_fifo
->
p_vpar
.
p_vout
,
p_undec_p
->
p_backward_ref
);
}
/* Mark the picture to be displayed */
vout_DisplayPicture
(
p_fifo
->
p_vpar
.
p_vout
,
p_mb
->
p_picture
);
/* Warn Synchro for its records. */
vpar_SynchroEnd
(
p_fifo
->
p_vpar
);
}
/* Mark the picture to be displayed */
vout_DisplayPicture
(
p_fifo
->
p_vpar
.
p_vout
,
p_undec_p
->
p_picture
);
vlc_mutex_unlock
(
&
p_mb
->
p_picture
->
lock_deccount
);
/* Release the
undec_picture
_t structure */
/* Release the
macroblock
_t structure */
#define P_buffer p_fifo->p_vpar.vbuffer
vlc_mutex_lock
(
&
P_buffer
->
lock
);
P_buffer
->
pp_undec_free
[
++
P_buffer
->
i_index
]
=
p_undec_p
;
P_buffer
->
pp_mb_free
[
++
P_buffer
->
i_index
]
=
p_mb
;
vlc_mutex_unlock
(
&
P_buffer
->
lock
);
#undef P_buffer
}
}
/*****************************************************************************
* vpar_Destroy
Picture : destroy a picture
in case of error
* vpar_Destroy
Macroblock : destroy a macroblock
in case of error
*****************************************************************************/
void
vpar_Destroy
Picture
(
video_fifo_t
*
p_fifo
,
undec_picture_t
*
p_undec_p
)
void
vpar_Destroy
Macroblock
(
video_fifo_t
*
p_fifo
,
macroblock_t
*
p_mb
)
{
int
i_ref
;
/* Destroy referencing pictures */
for
(
i_ref
=
0
;
p_undec_p
->
pp_referencing_undec
[
i_ref
].
p_undec
!=
NULL
&&
i_ref
<
MAX_REFERENCING_UNDEC
;
i_ref
++
)
/* Unlink referenced pictures */
if
(
p_mb
->
p_forw_top
!=
NULL
)
{
/* Try to put the referencing picture in the video FIFO */
vpar_DestroyPicture
(
p_fifo
,
p_undec_p
->
pp_referencing_undec
[
i_ref
].
p_undec
);
vout_UnlinkPicture
(
p_fifo
->
p_vpar
.
p_vout
,
p_mb
->
p_forw_top
);
}
/* Unlink referenced pictures */
if
(
p_undec_p
->
p_forward_ref
!=
NULL
)
if
(
p_mb
->
p_backw_top
!=
NULL
)
{
vout_UnlinkPicture
(
p_fifo
->
p_vpar
.
p_vout
,
p_undec_p
->
p_forward_ref
);
if
(
p_undec_p
->
p_backward_ref
!=
NULL
)
{
vout_UnlinkPicture
(
p_fifo
->
p_vpar
.
p_vout
,
p_undec_p
->
p_backward_ref
);
}
vout_UnlinkPicture
(
p_fifo
->
p_vpar
.
p_vout
,
p_mb
->
p_backw_top
);
}
/* Release the picture buffer */
vout_DestroyPicture
(
p_fifo
->
p_vpar
.
p_vout
,
p_undec_p
->
p_picture
);
/* Release the undec_picture_t structure */
if
(
p_mb
->
p_forw_bot
!=
NULL
)
{
vout_UnlinkPicture
(
p_fifo
->
p_vpar
.
p_vout
,
p_mb
->
p_forw_bot
);
}
if
(
p_mb
->
p_backw_bot
!=
NULL
)
{
vout_UnlinkPicture
(
p_fifo
->
p_vpar
.
p_vout
,
p_mb
->
p_backw_bot
);
}
/* Release the macroblock_t structure */
#define P_buffer p_fifo->p_vpar.vbuffer
vlc_mutex_lock
(
&
P_buffer
->
lock
);
P_buffer
->
pp_undec_free
[
++
P_buffer
->
i_index
]
=
p_undec_p
;
P_buffer
->
pp_mb_free
[
++
P_buffer
->
i_index
]
=
p_mb
;
vlc_mutex_unlock
(
&
P_buffer
->
lock
);
#undef P_buffer
}
}
src/video_parser/video_parser.c
View file @
e229f269
...
...
@@ -146,6 +146,7 @@ static int CheckConfiguration( video_cfg_t *p_cfg )
*******************************************************************************/
static
int
InitThread
(
vpar_thread_t
*
p_vpar
)
{
int
i_dummy
;
intf_DbgMsg
(
"vpar debug: initializing video parser thread %p
\n
"
,
p_vpar
);
...
...
@@ -181,6 +182,7 @@ static int InitThread( vpar_thread_t *p_vpar )
p_vpar
->
sequence
.
nonintra_quant
.
b_allocated
=
FALSE
;
p_vpar
->
sequence
.
chroma_intra_quant
.
b_allocated
=
FALSE
;
p_vpar
->
sequence
.
chroma_nonintra_quant
.
b_allocated
=
FALSE
;
p_vpar
->
sequence
.
i_frame_number
=
0
;
/* Initialize other properties */
#ifdef STATS
...
...
@@ -201,16 +203,19 @@ static int InitThread( vpar_thread_t *p_vpar )
bzero
(
p_vpar
->
p_vdec
,
MAX_VDEC
*
sizeof
(
vdec_thread_t
*
)
);
/* Spawn
a video_decoder thread
*/
/* ???
add the possibility to launch multiple vdec threads
*/
if
(
(
p_vpar
->
p_vdec
[
0
]
=
vdec_CreateThread
(
p_vpar
))
==
NULL
)
/* Spawn
video_decoder threads
*/
/* ???
modify the number of vdecs at runtime ?
*/
for
(
i_dummy
=
0
;
i_dummy
<
NB_VDEC
;
i_dummy
++
)
{
return
(
1
);
if
(
(
p_vpar
->
p_vdec
[
i_dummy
]
=
vdec_CreateThread
(
p_vpar
))
==
NULL
)
{
return
(
1
);
}
}
/* Mark thread as running and return */
intf_DbgMsg
(
"vpar debug: InitThread(%p) succeeded
\n
"
,
p_vpar
);
return
(
0
);
return
(
0
);
}
/*******************************************************************************
...
...
@@ -289,15 +294,16 @@ static void ErrorThread( vpar_thread_t *p_vpar )
vlc_mutex_lock
(
&
p_vpar
->
fifo
.
data_lock
);
/* ?? trash all trashable PES packets */
while
(
!
PARS
ER_FIFO_ISEMPTY
(
p_vpar
->
fifo
)
)
while
(
!
DECOD
ER_FIFO_ISEMPTY
(
p_vpar
->
fifo
)
)
{
input_NetlistFreePES
(
p_vpar
->
bit_stream
.
p_input
,
PARSER_FIFO_START
(
p_vpar
->
fifo
)
);
PARSER_FIFO_INCSTART
(
p_vpar
->
fifo
);
input_NetlistFreePES
(
p_vpar
->
bit_stream
.
p_input
,
DECODER_FIFO_START
(
p_vpar
->
fifo
)
);
DECODER_FIFO_INCSTART
(
p_vpar
->
fifo
);
}
vlc_mutex_unlock
(
&
p_vpar
->
fifo
.
data_lock
);
/* Sleep a while */
msleep
(
VPAR_IDLE_SLEEP
);
msleep
(
VPAR_IDLE_SLEEP
);
}
}
...
...
@@ -323,7 +329,7 @@ static void EndThread( vpar_thread_t *p_vpar )
/* ?? */
/* Destroy vdec threads */
for
(
i_dummy
=
0
;
i_dummy
<
MAX
_VDEC
;
i_dummy
++
)
for
(
i_dummy
=
0
;
i_dummy
<
NB
_VDEC
;
i_dummy
++
)
{
if
(
p_vpar
->
p_vdec
[
i_dummy
]
!=
NULL
)
vdec_DestroyThread
(
p_vpar
->
p_vdec
[
i_dummy
]
);
...
...
src/video_parser/vpar_blocks.c
0 → 100644
View file @
e229f269
/*****************************************************************************
* vpar_blocks.c : blocks parsing
* (c)1999 VideoLAN
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/uio.h>
#include <X11/Xlib.h>
#include <X11/extensions/XShm.h>
#include "config.h"
#include "common.h"
#include "mtime.h"
#include "vlc_thread.h"
#include "intf_msg.h"
#include "debug.h"
/* ?? temporaire, requis par netlist.h */
#include "input.h"
#include "input_netlist.h"
#include "decoder_fifo.h"
#include "video.h"
#include "video_output.h"
#include "video_parser.h"
#include "video_fifo.h"
#include "video_decoder.h"
/*
* Local prototypes
*/
static
__inline__
void
InitMacroblock
(
vpar_thread_t
*
p_vpar
,
macroblock_t
*
p_mb
,
int
i_mb_address
);
static
__inline__
int
MacroblockAddressIncrement
(
vpar_thread_t
*
p_vpar
);
static
__inline__
void
MacroblockModes
(
vpar_thread_t
*
p_vpar
,
macroblock_t
*
p_mb
);
typedef
(
void
*
)
f_decode_block_t
(
vpar_thread_t
*
,
macroblock_t
*
,
int
);
/*****************************************************************************
* vpar_ParseMacroblock : Parse the next macroblock
*****************************************************************************/
void
vpar_ParseMacroblock
(
vpar_thread_t
*
p_vpar
,
int
*
pi_mb_address
,
int
i_mb_previous
,
int
i_mb_base
)
{
static
f_addb_t
ppf_addb_intra
[
2
]
=
{
vdec_AddBlock
,
vdec_CopyBlock
};
int
i_mb
,
i_b
,
i_mask
,
i_x
,
i_y
,
pi_pos
[
3
],
pi_width
[
3
];
macroblock_t
*
p_mb
;
f_addb_t
pf_addb
;
*
pi_mb_address
+=
MacroblockAddressIncrement
(
p_vpar
);
for
(
i_mb
=
i_mb_previous
;
i_mb
<
*
pi_mb_address
;
i_mb
++
)
{
/* Skipped macroblock (ISO/IEC 13818-2 7.6.6). */
static
int
pi_dc_dct_reinit
[
4
]
=
{
128
,
256
,
512
,
1024
};
static
f_motion_t
pf_motion_skipped
[
4
]
=
{
NULL
,
vdec_MotionField
,
vdec_MotionField
,
vdec_MotionFrame
};
/* Reset DC predictors (7.2.1). */
p_vpar
->
slice
.
pi_dct_pred
[
0
]
=
p_vpar
->
slice
.
pi_dct_pred
[
1
]
=
p_vpar
->
slice
.
pi_dct_pred
[
2
]
=
pi_dc_dct_reinit
[
p_vpar
->
picture
.
i_intra_dc_precision
];
if
(
p_vpar
->
picture
.
i_coding_type
==
P_CODING_TYPE
)
{
/* Reset motion vector predictors (ISO/IEC 13818-2 7.6.3.4). */
bzero
(
p_vpar
->
slice
.
pppi_pmv
,
8
*
sizeof
(
int
)
);
}
if
(
(
p_mb
=
p_vpar
->
picture
.
pp_mb
[
i_mb_base
+
i_mb
]
=
vpar_NewMacroblock
(
&
p_vpar
->
vfifo
))
==
NULL
)
{
p_vpar
->
picture
.
b_error
=
TRUE
;
intf_ErrMsg
(
"vpar error: macroblock list is empty !"
);
return
;
}
InitMacroblock
(
p_vpar
,
p_mb
,
i_mb
);
/* No IDCT nor AddBlock. */
for
(
i_b
=
0
;
i_b
<
12
;
i_b
++
)
{
p_mb
->
pf_idct
[
i_b
]
=
vdec_DummyIDCT
;
p_mb
->
pf_addb
[
i_b
]
=
vdec_DummyBlock
;
}
/* Motion type is picture structure. */
p_mb
->
pf_motion
=
pf_motion_skipped
[
p_vpar
->
picture
.
i_structure
];
/* Predict from field of same parity. */
/* ??? */
}
/* Get a macroblock structure. */
if
(
(
p_mb
=
p_vpar
->
picture
.
pp_mb
[
i_mb_base
+
*
pi_mb_address
]
=
vpar_NewMacroblock
(
&
p_vpar
->
vfifo
))
==
NULL
)
{
p_vpar
->
picture
.
b_error
=
TRUE
;
intf_ErrMsg
(
"vpar error: macroblock list is empty !"
);
return
;
}
InitMacroblock
(
p_vpar
,
p_mb
,
*
pi_mb_address
);
/* Parse off macroblock_modes structure. */
MacroblockModes
(
p_vpar
,
p_mb
);
if
(
p_vpar
->
mb
.
i_mb_type
&
MB_QUANT
)
{
LoadQuantizerScale
(
p_vpar
);
}
if
(
p_vpar
->
mb
.
i_mb_type
&
MB_MOTION_FORWARD
)
{
(
*
p_vpar
->
sequence
.
pf_decode_mv
)(
p_vpar
,
0
);
}
if
(
p_vpar
->
mb
.
i_mb_type
&
MB_MOTION_BACKWARD
)
{
(
*
p_vpar
->
sequence
.
pf_decode_mv
)(
p_vpar
,
1
);
}
if
(
p_vpar
->
picture
.
b_concealment_mv
&&
(
p_vpar
->
mb
.
i_mb_type
&
MB_INTRA
)
)
{
DumpBits
(
&
p_vpar
->
bit_stream
,
1
);
}
if
(
p_vpar
->
mb
.
i_mb_type
&
MB_PATTERN
)
{
(
*
p_vpar
->
sequence
.
pf_decode_pattern
)(
p_vpar
);
}
else
{
int
pi_coded_block_pattern
[
2
]
=
{
0
,
(
1
<<
4
+
2
*
p_vpar
->
sequence
.
i_chroma_nb_blocks
)
-
1
};
p_vpar
->
mb
.
i_coded_block_pattern
=
pi_coded_block_pattern
[
p_vpar
->
mb
.
i_mb_type
&
MB_INTRA
];
}
pf_addb
=
ppf_addb_intra
[
p_vpar
->
mb
.
i_mb_type
&
MB_INTRA
];
/* C'est de la merde, il faut recommencer */
i_x
=
p_mb
->
i_mb_x
<<
4
;
i_y
=
p_mb
->
i_mb_y
<<
4
;
pi_pos
[
0
]
=
i_y
*
(
p_vpar
->
sequence
.
i_width
<<
(
!
p_vpar
->
picture
.
b_frame_structure
))
+
(
p_mb
->
i_structure
==
BOTTOM_FIELD
)
*
p_vpar
->
sequence
.
i_width
+
i_x
;
pi_pos
[
1
]
=
pi_pos
[
2
]
=
i_y
*
(
p_vpar
->
sequence
.
i_chroma_width
<<
(
!
p_vpar
->
picture
.
b_frame_structure
))
+
(
p_mb
->
i_structure
==
BOTTOM_FIELD
)
*
p_vpar
->
sequence
.
i_chroma_width
+
(
i_x
>>
(
3
-
p_vpar
->
sequence
.
i_chroma_format
));
pi_width
[
0
]
=
p_vpar
->
sequence
.
i_width
<<
(
!
p_vpar
->
picture
.
b_frame_structure
||
p_vpar
->
mb
.
b_dct_type
);
pi_width
[
1
]
=
pi_width
[
2
]
=
p_vpar
->
sequence
.
i_chroma_width
<<
(
!
p_vpar
->
picture
.
b_frame_structure
||
p_vpar
->
mb
.
b_dct_type
);
/* Effectively decode blocks. */
for
(
i_b
=
0
,
i_mask
=
1
<<
(
3
+
2
*
p_vpar
->
sequence
.
i_chroma_nb_blocks
);
i_b
<
4
+
2
*
p_vpar
->
sequence
.
i_chroma_nb_blocks
;
i_b
++
,
i_mask
>>=
1
)
{
if
(
p_vpar
->
mb
.
i_coded_block_pattern
&
i_mask
)
{
static
f_decode_block_t
pppf_decode_block
[
2
][
2
]
=
{
{
vpar_DecodeMPEG1Non
,
vpar_DecodeMPEG1Intra
},
{
vpar_DecodeMPEG2Non
,
vpar_DecodeMPEG2Intra
}
};
static
int
pi_x
[
12
]
=
{
0
,
8
,
0
,
8
,
0
,
0
,
0
,
0
,
8
,
8
,
8
,
8
};
static
int
pi_y
[
12
]
=
{
0
,
0
,
8
,
8
,
0
,
0
,
8
,
8
,
0
,
0
,
8
,
8
};
data_t
pi_data
[
12
]
=
{
p_mb
->
p_picture
->
p_y
,
p_mb
->
p_picture
->
p_y
,
p_mb
->
p_picture
->
p_y
,
p_mb
->
p_picture
->
p_y
,
p_mb
->
p_picture
->
p_u
,
p_mb
->
p_picture
->
p_v
,
p_mb
->
p_picture
->
p_u
,
p_mb
->
p_picture
->
p_v
,
p_mb
->
p_picture
->
p_u
,
p_mb
->
p_picture
->
p_v
,
p_mb
->
p_picture
->
p_u
,
p_mb
->
p_picture
->
p_v
};
bzero
(
p_mb
->
ppi_blocks
[
i_b
],
64
*
sizeof
(
elem_t
)
);
(
*
pppf_decode_block
[
p_vpar
->
sequence
.
b_mpeg2
]
[
p_vpar
->
mb
.
i_mb_type
&
MB_INTRA
])
(
p_vpar
,
p_mb
,
i_b
);
/* decode_block has already set pf_idct and pi_sparse_pos. */
p_mb
->
pf_addb
[
i_b
]
=
pf_addb
;
/* Calculate block coordinates. */
p_mb
->
p_data
[
i_b
]
=
pi_data
[
i_b
]
+
pi_pos
[
i_b
>>
2
]
+
pi_y
[
i_b
]
*
pi_width
[
i_b
>>
2
]
+
(
p_vpar
->
mb
.
b_dct_type
&
((
i_b
&
2
)
>>
1
))
/* INACHEV parce que trop pourri ! */
}
else
{
/* Block not coded, so no IDCT, nor AddBlock */
p_mb
->
pf_addb
[
i_b
]
=
vdec_DummyBlock
;
p_mb
->
pf_idct
[
i_b
]
=
vdec_DummyIDCT
;
}
}
if
(
!
(
p_vpar
->
mb
.
i_mb_type
&
MB_INTRA
)
)
{
static
int
pi_dc_dct_reinit
[
4
]
=
{
128
,
256
,
512
,
1024
};
/* Reset DC predictors (7.2.1). */
p_vpar
->
slice
.
pi_dct_pred
[
0
]
=
p_vpar
->
slice
.
pi_dct_pred
[
1
]
=
p_vpar
->
slice
.
pi_dct_pred
[
2
]
=
pi_dc_dct_reinit
[
p_vpar
->
picture
.
i_intra_dc_precision
];
}
else
if
(
!
p_vpar
->
picture
.
b_concealment_mv
)
{
/* Reset MV predictors. */
bzero
(
p_vpar
->
slice
.
pppi_pmv
,
8
*
sizeof
(
int
)
);
}
if
(
(
p_vpar
->
picture
.
i_coding_type
==
P_CODING_TYPE
)
&&
!
(
p_vpar
->
mb
.
i_mb_type
&
(
MB_MOTION_FORWARD
|
MB_INTRA
))
)
{
/* Special No-MC macroblock in P pictures (7.6.3.5). */
p_vpar
->
slice
.
pppi_pmv
[
0
][
0
][
0
]
=
p_vpar
->
slice
.
pppi_pmv
[
0
][
0
][
1
]
=
p_vpar
->
slice
.
pppi_pmv
[
1
][
0
][
0
]
=
p_vpar
->
slice
.
pppi_pmv
[
1
][
0
][
1
]
=
0
;
/* motion type ?????? */
/* predict from field of same parity ????? */
}
}
/*****************************************************************************
* InitMacroblock : Initialize macroblock values
*****************************************************************************/
static
__inline__
void
InitMacroblock
(
vpar_thread_t
*
p_vpar
,
macroblock_t
*
p_mb
,
int
i_mb_address
)
{
p_mb
->
p_picture
=
p_vpar
->
picture
.
p_picture
;
p_mb
->
i_structure
=
p_vpar
->
picture
.
i_structure
;
p_mb
->
i_mb_x
=
i_mb_address
%
p_vpar
->
sequence
.
i_mb_width
;
p_mb
->
i_mb_y
=
i_mb_address
/
p_vpar
->
sequence
.
i_mb_width
;
p_mb
->
i_chroma_nb_blocks
=
p_vpar
->
sequence
.
i_chroma_nb_blocks
;
p_mb
->
i_lum_incr
=
p_vpar
->
picture
.
i_lum_incr
;
p_mb
->
i_chroma_incr
=
p_vpar
->
picture
.
i_chroma_incr
;
}
/*****************************************************************************
* MacroblockAddressIncrement : Get the macroblock_address_increment field
*****************************************************************************/
static
__inline__
int
MacroblockAddressIncrement
(
vpar_thread_t
*
p_vpar
)
{
/* pomper dans Berkeley */
}
/*****************************************************************************
* MacroblockModes : Get the macroblock_modes structure
*****************************************************************************/
static
__inline__
void
MacroblockModes
(
vpar_thread_t
*
p_vpar
,
macroblock_t
*
p_mb
)
{
static
f_motion_t
pf_motion
[
2
][
4
]
=
{
{
NULL
,
vdec_FieldRecon
,
vdec_16x8Recon
,
vdec_DMVRecon
},
{
NULL
,
vdec_FieldRecon
,
vdec_FrameRecon
,
vdec_DMVRecon
}
};
static
int
ppi_mv_count
[
2
][
4
]
=
{
{
0
,
1
,
2
,
1
},
{
0
,
2
,
1
,
1
}
};
static
int
ppi_mv_format
[
2
][
4
]
=
{
{
0
,
1
,
1
,
1
},
{
0
,
1
,
2
,
1
}
};
/* Get macroblock_type. */
p_vpar
->
mb
.
i_mb_type
=
(
*
p_vpar
->
picture
.
pf_macroblock_type
)
(
vpar_thread_t
*
p_vpar
);
/* SCALABILITY : warning, we don't know if spatial_temporal_weight_code
* has to be dropped, take care if you use scalable streams. */
/* DumpBits( &p_vpar->bit_stream, 2 ); */
if
(
!
(
p_vpar
->
mb
.
i_mb_type
&
(
MB_MOTION_FORWARD
|
MB_MOTION_BACKWARD
))
||
p_vpar
->
picture
.
b_frame_pred_frame_dct
)
{
/* If mb_type has neither MOTION_FORWARD nor MOTION_BACKWARD, this
* is useless, but also harmless. */
p_vpar
->
mb
.
i_motion_type
=
MOTION_FRAME
;
}
else
{
p_vpar
->
mb
.
i_motion_type
=
GetBits
(
&
p_vpar
->
bit_stream
,
2
);
}
p_mb
->
f_motion
=
pf_motion
[
p_vpar
->
picture
.
b_frame_structure
]
[
p_vpar
->
mb
.
i_motion_type
];
p_vpar
->
mb
.
i_mv_count
=
ppi_mv_count
[
p_vpar
->
picture
.
b_frame_structure
]
[
p_vpar
->
mb
.
i_motion_type
];
p_vpar
->
mb
.
i_mv_format
=
ppi_mv_format
[
p_vpar
->
picture
.
b_frame_structure
]
[
p_vpar
->
mb
.
i_motion_type
];
if
(
(
p_vpar
->
picture
.
i_structure
==
FRAME_STRUCTURE
)
&&
(
!
p_vpar
->
picture
.
b_frame_pred_frame_dct
)
&&
(
p_var
->
mb
.
i_mb_type
&
(
MB_PATTERN
|
MB_INTRA
))
)
{
p_vpar
->
mb
.
b_dct_type
=
GetBits
(
&
p_vpar
->
bit_stream
,
1
);
}
else
{
p_vpar
->
mb
.
b_dct_type
=
0
;
}
}
/*****************************************************************************
* vpar_IMBType : macroblock_type in I pictures
*****************************************************************************/
int
vpar_IMBType
(
vpar_thread_t
*
p_vpar
)
{
/* pomper dans Berkeley */
}
/*****************************************************************************
* vpar_PMBType : macroblock_type in P pictures
*****************************************************************************/
int
vpar_PMBType
(
vpar_thread_t
*
p_vpar
)
{
/* pomper dans Berkeley */
}
/*****************************************************************************
* vpar_BMBType : macroblock_type in B pictures
*****************************************************************************/
int
vpar_BMBType
(
vpar_thread_t
*
p_vpar
)
{
/* pomper dans Berkeley */
}
/*****************************************************************************
* vpar_DMBType : macroblock_type in D pictures
*****************************************************************************/
int
vpar_DMBType
(
vpar_thread_t
*
p_vpar
)
{
/* pomper dans Berkeley */
}
/*****************************************************************************
* vpar_CodedPattern420 : coded_block_pattern with 420 chroma
*****************************************************************************/
int
vpar_CodedPattern420
(
vpar_thread_t
*
p_vpar
)
{
/* pomper dans Berkeley */
}
/*****************************************************************************
* vpar_CodedPattern422 : coded_block_pattern with 422 chroma
*****************************************************************************/
int
vpar_CodedPattern422
(
vpar_thread_t
*
p_vpar
)
{
/* pomper dans Berkeley + attention ! y'a 2 bits en plus en MPEG2 */
}
/*****************************************************************************
* vpar_CodedPattern444 : coded_block_pattern with 444 chroma
*****************************************************************************/
int
vpar_CodedPattern444
(
vpar_thread_t
*
p_vpar
)
{
/* pomper dans Berkeley + attention ! y'a 4 bits en plus en MPEG2 */
}
/*****************************************************************************
* vpar_DecodeMPEG1Non : decode MPEG-1 non-intra blocks
*****************************************************************************/
void
vpar_DecodeMPEG1Non
(
vpar_thread_t
*
p_vpar
,
macroblock_t
*
p_mb
,
int
i_b
)
{
/* pomper dans Berkeley. Pour toutes ces fonctions, il faut mettre
p_mb->pf_idct[i_b] :
- vdec_IDCT ou
- vdec_SparseIDCT si la matrice n'a qu'un coefficient non nul.
Dans le deuxime cas, p_mb->pi_sparse_pos[i_b] contient le numro
de ce coefficient. */
if
(
p_vpar
->
picture
.
i_coding_type
==
D_CODING_TYPE
)
{
/* Remove end_of_macroblock (always 1, prevents startcode emulation)
* ISO/IEC 11172-2 section 2.4.2.7 and 2.4.3.6 */
DumpBits
(
&
p_vpar
->
fifo
,
1
);
}
}
/*****************************************************************************
* vpar_DecodeMPEG1Intra : decode MPEG-1 intra blocks
*****************************************************************************/
void
vpar_DecodeMPEG1Intra
(
vpar_thread_t
*
p_vpar
,
macroblock_t
*
p_mb
,
int
i_b
)
{
/* pomper dans Berkeley. */
if
(
p_vpar
->
picture
.
i_coding_type
==
D_CODING_TYPE
)
{
/* Remove end_of_macroblock (always 1, prevents startcode emulation)
* ISO/IEC 11172-2 section 2.4.2.7 and 2.4.3.6 */
DumpBits
(
&
p_vpar
->
fifo
,
1
);
}
}
/*****************************************************************************
* vpar_DecodeMPEG2Non : decode MPEG-2 non-intra blocks
*****************************************************************************/
void
vpar_DecodeMPEG2Non
(
vpar_thread_t
*
p_vpar
,
macroblock_t
*
p_mb
,
int
i_b
)
{
/* pomper dans Berkeley. Bien sr les matrices seront diffrentes... */
}
/*****************************************************************************
* vpar_DecodeMPEG2Intra : decode MPEG-2 intra blocks
*****************************************************************************/
void
vpar_DecodeMPEG2Intra
(
vpar_thread_t
*
p_vpar
,
macroblock_t
*
p_mb
,
int
i_b
)
{
/* pomper dans Berkeley. */
}
src/video_parser/vpar_headers.c
View file @
e229f269
...
...
@@ -3,8 +3,6 @@
* (c)1999 VideoLAN
*****************************************************************************/
/* ?? passer en terminate/destroy avec les signaux supplmentaires */
/*****************************************************************************
* Preamble
*****************************************************************************/
...
...
@@ -30,15 +28,41 @@
#include "decoder_fifo.h"
#include "video.h"
#include "video_output.h"
#include "vpar_blocks.h"
#include "video_parser.h"
#include "
undec_picture
.h"
#include "
macroblock
.h"
#include "video_fifo.h"
#include "video_decoder.h"
/*
* Local prototypes
*/
static
__inline__
void
NextStartCode
(
vpar_thread_t
*
p_vpar
);
static
void
GroupHeader
(
vpar_thread_t
*
p_vpar
)
static
void
PictureHeader
(
vpar_thread_t
*
p_vpar
)
static
void
__inline__
ReferenceUpdate
(
vpar_thread_t
*
p_vpar
,
int
i_coding_type
,
picture_t
*
p_newref
)
static
void
__inline__
ReferenceReplace
(
vpar_thread_t
*
p_vpar
,
int
i_coding_type
,
picture_t
*
p_newref
)
static
void
SliceHeader00
(
vpar_thread_t
*
p_vpar
,
int
*
pi_mb_address
,
int
i_mb_base
,
elem_t
*
p_y
,
p_u
,
p_v
,
u32
i_vert_code
)
static
void
SliceHeader01
(
vpar_thread_t
*
p_vpar
,
int
*
pi_mb_address
,
int
i_mb_base
,
elem_t
*
p_y
,
p_u
,
p_v
,
u32
i_vert_code
)
static
void
SliceHeader10
(
vpar_thread_t
*
p_vpar
,
int
*
pi_mb_address
,
int
i_mb_base
,
elem_t
*
p_y
,
p_u
,
p_v
,
u32
i_vert_code
)
static
void
SliceHeader11
(
vpar_thread_t
*
p_vpar
,
int
*
pi_mb_address
,
int
i_mb_base
,
elem_t
*
p_y
,
p_u
,
p_v
,
u32
i_vert_code
)
static
__inline__
void
SliceHeader
(
vpar_thread_t
*
p_vpar
,
int
*
pi_mb_address
,
int
i_mb_base
,
elem_t
*
p_y
,
p_u
,
p_v
,
u32
i_vert_code
)
static
void
ExtensionAndUserData
(
vpar_thread_t
*
p_vpar
)
/*****************************************************************************
* vpar_NextSequenceHeader : Find the next sequence header
...
...
@@ -98,7 +122,7 @@ int vpar_ParseHeader( vpar_thread_t * p_vpar )
*****************************************************************************/
static
__inline__
void
NextStartCode
(
vpar_thread_t
*
p_vpar
)
{
/* Re-align the buffer
to
an 8-bit boundary */
/* Re-align the buffer
on
an 8-bit boundary */
DumpBits
(
&
p_vpar
->
bit_stream
,
p_vpar
->
bit_stream
.
fifo
.
i_available
&
7
);
while
(
ShowBits
(
&
p_vpar
->
bit_stream
,
24
)
!=
0x01L
&&
!
p_vpar
->
b_die
)
...
...
@@ -110,37 +134,31 @@ static __inline__ void NextStartCode( vpar_thread_t * p_vpar )
/*****************************************************************************
* SequenceHeader : Parse the next sequence header
*****************************************************************************/
#define RESERVED -1
static
double
d_frame_rate_table
[
16
]
=
{
0
.
0
,
((
23
.
0
*
1000
.
0
)
/
1001
.
0
),
24
.
0
,
25
.
0
,
((
30
.
0
*
1000
.
0
)
/
1001
.
0
),
30
.
0
,
50
.
0
,
((
60
.
0
*
1000
.
0
)
/
1001
.
0
),
60
.
0
,
RESERVED
,
RESERVED
,
RESERVED
,
RESERVED
,
RESERVED
,
RESERVED
,
RESERVED
};
static
void
SequenceHeader
(
vpar_thread_t
*
p_vpar
)
{
#define RESERVED -1
static
double
d_frame_rate_table
[
16
]
=
{
0
.
0
,
((
23
.
0
*
1000
.
0
)
/
1001
.
0
),
24
.
0
,
25
.
0
,
((
30
.
0
*
1000
.
0
)
/
1001
.
0
),
30
.
0
,
50
.
0
,
((
60
.
0
*
1000
.
0
)
/
1001
.
0
),
60
.
0
,
RESERVED
,
RESERVED
,
RESERVED
,
RESERVED
,
RESERVED
,
RESERVED
,
RESERVED
};
#undef RESERVED
int
i_height_save
,
i_width_save
;
i_height_save
=
p_vpar
->
sequence
.
i_height
;
i_width_save
=
p_vpar
->
sequence
.
i_width
;
p_vpar
->
sequence
.
i_height
=
ntohl
(
GetBits
(
p_vpar
->
bit_stream
,
12
)
);
p_vpar
->
sequence
.
i_width
=
ntohl
(
GetBits
(
p_vpar
->
bit_stream
,
12
)
);
p_vpar
->
sequence
.
i_height
=
GetBits
(
p_vpar
->
bit_stream
,
12
);
p_vpar
->
sequence
.
i_width
=
GetBits
(
p_vpar
->
bit_stream
,
12
);
p_vpar
->
sequence
.
i_ratio
=
GetBits
(
p_vpar
->
bit_stream
,
4
);
p_vpar
->
sequence
.
d_frame_rate
=
d_frame_rate_table
(
GetBits
(
p_vpar
->
bit_stream
,
4
)
);
...
...
@@ -182,9 +200,14 @@ static void SequenceHeader( vpar_thread_t * p_vpar )
/*
* Sequence Extension
*/
if
(
ShowBits
(
p_vpar
->
bit_stream
,
32
)
==
EXTENSION_START_CODE
)
NextStartCode
(
p_vpar
);
if
(
ShowBits
(
&
p_vpar
->
bit_stream
,
32
)
==
EXTENSION_START_CODE
)
{
int
i_dummy
;
static
int
pi_chroma_nb_blocks
[
4
]
=
{
0
,
1
,
2
,
4
};
static
(
void
*
)
ppf_chroma_pattern
[
4
](
vpar_thread_t
*
)
=
{
NULL
,
vpar_CodedPattern420
,
vpar_CodedPattern422
,
vpar_CodedPattern444
};
/* Parse sequence_extension */
DumpBits32
(
&
p_vpar
->
bit_stream
);
...
...
@@ -192,6 +215,12 @@ static void SequenceHeader( vpar_thread_t * p_vpar )
DumpBits
(
&
p_vpar
->
bit_stream
,
12
);
p_vpar
->
sequence
.
b_progressive
=
GetBits
(
&
p_vpar
->
bit_stream
,
1
);
p_vpar
->
sequence
.
i_chroma_format
=
GetBits
(
&
p_vpar
->
bit_stream
,
2
);
p_vpar
->
sequence
.
i_chroma_width
=
p_vpar
->
sequence
.
i_width
>>
(
3
-
p_vpar
->
sequence
.
i_chroma_format
);
p_vpar
->
sequence
.
i_chroma_nb_blocks
=
pi_chroma_nb_blocks
[
p_vpar
->
sequence
.
i_chroma_format
];
p_vpar
->
sequence
.
pf_decode_pattern
=
ppf_chroma_pattern
[
p_vpar
->
sequence
.
i_chroma_format
];
p_vpar
->
sequence
.
i_width
|=
GetBits
(
&
p_vpar
->
bit_stream
,
2
)
<<
12
;
p_vpar
->
sequence
.
i_height
|=
GetBits
(
&
p_vpar
->
bit_stream
,
2
)
<<
12
;
/* bit_rate_extension, marker_bit, vbv_buffer_size_extension, low_delay */
...
...
@@ -202,180 +231,64 @@ static void SequenceHeader( vpar_thread_t * p_vpar )
p_vpar
->
sequence
.
d_frame_rate
*=
(
i_dummy
+
1
)
/
(
GetBits
(
&
p_vpar
->
bit_stream
,
5
)
+
1
);
/* Extension and User data */
ExtensionAndUserData
(
p_vpar
);
p_vpar
->
sequence
.
pf_decode_mv
=
vpar_MPEG2MotionVector
;
}
else
{
/* It's an MPEG-1 stream. Put adequate parameters. */
p_vpar
->
sequence
.
b_progressive
=
1
;
p_vpar
->
i_chroma_format
=
CHROMA_420
;
p_vpar
->
sequence
.
i_chroma_format
=
CHROMA_420
;
p_vpar
->
sequence
.
i_chroma_width
=
p_vpar
->
sequence
.
i
->
width
>>
2
;
p_vpar
->
sequence
.
i_chroma_nb_blocks
=
2
;
p_vpar
->
sequence
.
pf_decode_pattern
=
vpar_CodedPattern420
;
p_vpar
->
sequence
.
pf_decode_mv
=
vpar_MPEG1MotionVector
;
}
p_vpar
->
sequence
.
i_mb_width
=
(
p_vpar
->
sequence
.
i_width
+
15
)
/
16
;
p_vpar
->
sequence
.
i_mb_height
=
(
p_vpar
->
sequence
.
b_progressive
)
?
(
p_vpar
->
sequence
.
i_height
+
15
)
/
16
:
2
*
(
p_vpar
->
sequence
.
i_height
+
31
)
/
32
;
p_vpar
->
sequence
.
i_mb_size
=
p_vpar
->
sequence
.
i_mb_width
*
p_vpar
->
sequence
.
i_mb_height
;
p_vpar
->
sequence
.
i_width
=
(
p_vpar
->
sequence
.
i_mb_width
*
16
);
p_vpar
->
sequence
.
i_height
=
(
p_vpar
->
sequence
.
i_mb_height
*
16
);
p_vpar
->
sequence
.
i_size
=
p_vpar
->
sequence
.
i_width
*
p_vpar
->
sequence
.
i_height
;
if
(
p_vpar
->
sequence
.
i_width
!=
i_width_save
||
p_vpar
->
sequence
.
i_height
!=
i_height_save
||
p_vpar
->
sequence
.
p_frame_lum_lookup
==
NULL
)
/* Slice Header functions */
if
(
p_vpar
->
sequence
.
i_height
<=
2800
)
{
int
i_x
,
i_y
;
pel_lookup_table
*
p_fr
,
p_fl
;
int
i_fr
,
i_fl
;
static
int
pi_chroma_size
[
4
]
=
{
0
,
2
,
1
,
0
}
#define Sequence p_vpar->sequence
/* The size of the pictures has changed. Probably a new sequence.
* We must recalculate the lookup matrices. */
/* First unlink the previous lookup matrices so that they can
* be freed in the future. */
if
(
Sequence
.
p_frame_lum_lookup
!=
NULL
)
if
(
p_vpar
->
sequence
.
i_scalable_mode
!=
SC_DP
)
{
UNLINK_LOOKUP
(
Sequence
.
p_frame_lum_lookup
);
UNLINK_LOOKUP
(
Sequence
.
p_field_lum_lookup
);
UNLINK_LOOKUP
(
Sequence
.
p_frame_chroma_lookup
);
UNLINK_LOOKUP
(
Sequence
.
p_field_chroma_lookup
);
p_vpar
->
sequence
.
pf_slice_header
=
SliceHeader00
;
}
/* Allocate the new lookup tables. */
Sequence
.
p_frame_lum_lookup
=
(
pel_lookup_table_t
*
)
malloc
(
sizeof
(
pel_lookup_table_t
)
*
Sequence
.
i_width
*
Sequence
.
i_height
);
Sequence
.
p_field_lum_lookup
=
(
pel_lookup_table_t
*
)
malloc
(
sizeof
(
pel_lookup_table_t
)
*
Sequence
.
i_width
*
Sequence
.
i_height
);
Sequence
.
p_frame_chroma_lookup
=
(
pel_lookup_table_t
*
)
malloc
(
sizeof
(
pel_lookup_table_t
)
*
Sequence
.
i_width
*
Sequence
.
i_height
>>
pi_chroma_size
[
Sequence
.
i_chroma_format
]
);
Sequence
.
p_field_chroma_lookup
=
(
pel_lookup_table_t
*
)
malloc
(
sizeof
(
pel_lookup_table_t
)
*
Sequence
.
i_width
*
Sequence
.
i_height
>>
pi_chroma_size
[
Sequence
.
i_chroma_format
]
);
if
(
!
Sequence
.
p_frame_lum_lookup
||!
Sequence
.
p_field_lum_lookup
||
!
Sequence
.
p_frame_chroma_lookup
||!
Sequence
.
p_field_chroma_lookup
)
else
{
intf_DbgMsg
(
"vpar error: not enough memory for lookup tables"
);
p_vpar
->
b_error
=
1
;
return
;
p_vpar
->
sequence
.
pf_slice_header
=
SliceHeader01
;
}
/* Fill in the luminance lookup tables */
p_fr
=
&
Sequence
.
p_frame_lum_lookup
->
pi_pel
;
p_fl
=
&
Sequence
.
p_field_lum_lookup
->
pi_pel
;
i_fr
=
i_fl
=
0
;
for
(
i_y
=
0
;
i_y
<
Sequence
.
i_height
;
i_y
++
)
}
else
{
if
(
p_vpar
->
sequence
.
i_scalable_mode
!=
SC_DP
)
{
int
i_mb_y
,
i_b_y
,
i_pos_y
;
i_mb_y
=
i_y
>>
4
;
i_b_y
=
(
i_y
&
15
)
>>
3
;
i_pos_y
=
(
i_y
&
7
);
for
(
i_x
=
0
;
i_x
<
Sequence
.
i_width
;
i_x
++
)
{
int
i_mb_x
,
i_b_x
,
i_pos_x
;
i_mb_x
=
i_x
>>
4
;
i_b_x
=
(
i_x
&
15
)
>>
3
;
i_pos_x
=
(
i_x
&
7
);
p_fl
[
i_fr
+
i_x
]
=
p_fr
[
i_fr
+
i_x
]
=
(
i_mb_y
*
Sequence
.
i_mb_width
+
i_mb_y
)
*
256
+
((
i_b_y
<<
1
)
+
i_b_x
)
*
64
+
i_pos_y
*
8
+
i_pos_x
;
}
i_fr
+=
Sequence
.
i_width
;
i_fl
+=
Sequence
.
i_width
<<
1
;
if
(
i_fl
==
Sequence
.
i_width
*
Sequence
.
i_height
)
{
i_fl
=
Sequence
.
i_width
;
}
p_vpar
->
sequence
.
pf_slice_header
=
SliceHeader10
;
}
/* Fill in the chrominance lookup tables */
p_fr
=
&
Sequence
.
p_frame_chroma_lookup
->
pi_pel
;
p_fl
=
&
Sequence
.
p_field_chroma_lookup
->
pi_pel
;
i_fr
=
i_fl
=
0
;
switch
(
p_vpar
->
i_chroma_format
)
else
{
case
CHROMA_444
:
/* That's the same as luminance */
memcopy
(
&
Sequence
.
p_frame_croma_lookup
->
pi_pel
,
&
Sequence
.
p_frame_lum_lookup
->
pi_pel
,
sizeof
(
PEL_P
)
*
Sequence
.
i_height
*
Sequence
.
i_width
);
memcopy
(
&
Sequence
.
p_field_croma_lookup
->
pi_pel
,
&
Sequence
.
p_field_lum_lookup
->
pi_pel
,
sizeof
(
PEL_P
)
*
Sequence
.
i_height
*
Sequence
.
i_width
);
case
CHROMA_422
:
for
(
i_y
=
0
;
i_y
<
Sequence
.
i_height
;
i_y
++
)
{
int
i_mb_y
,
i_b_y
,
i_pos_y
;
i_mb_y
=
i_y
>>
4
;
i_b_y
=
(
i_y
&
15
)
>>
3
;
i_pos_y
=
(
i_y
&
7
);
for
(
i_x
=
0
;
i_x
<
(
Sequence
.
i_width
>>
1
);
i_x
++
)
{
int
i_mb_x
,
i_pos_x
;
i_mb_x
=
i_x
>>
3
;
i_pos_x
=
(
i_x
&
7
);
p_fl
[
i_fr
+
i_x
]
=
p_fr
[
i_fr
+
i_x
]
=
(
i_mb_y
*
Sequence
.
i_mb_width
+
i_mb_y
)
*
128
+
i_b_y
*
64
+
i_pos_y
*
8
+
i_pos_x
;
}
i_fr
+=
Sequence
.
i_width
>>
1
;
i_fl
+=
Sequence
.
i_width
;
if
(
i_fl
==
(
Sequence
.
i_width
*
Sequence
.
i_height
>>
1
)
)
{
i_fl
=
(
Sequence
.
i_width
>>
1
);
}
}
p_vpar
->
sequence
.
pf_slice_header
=
SliceHeader11
;
}
}
if
(
p_vpar
->
sequence
.
i_width
!=
i_width_save
||
p_vpar
->
sequence
.
i_height
!=
i_height_save
||
p_vpar
->
sequence
.
p_frame_lum_lookup
==
NULL
)
{
case
CHROMA_420
:
for
(
i_y
=
0
;
i_y
<
(
Sequence
.
i_height
>>
1
);
i_y
++
)
{
int
i_mb_y
,
i_pos_y
;
i_mb_y
=
i_y
>>
3
;
i_pos_y
=
(
i_y
&
7
);
for
(
i_x
=
0
;
i_x
<
(
Sequence
.
i_width
>>
1
);
i_x
++
)
{
int
i_mb_x
,
i_pos_x
;
i_mb_x
=
i_x
>>
3
;
i_pos_x
=
(
i_x
&
7
);
p_fl
[
i_fr
+
i_x
]
=
p_fr
[
i_fr
+
i_x
]
=
(
i_mb_y
*
Sequence
.
i_mb_width
+
i_mb_y
)
*
64
+
i_pos_y
*
8
+
i_pos_x
;
}
i_fr
+=
Sequence
.
i_width
>>
1
;
i_fl
+=
Sequence
.
i_width
;
if
(
i_fl
==
(
Sequence
.
i_width
*
Sequence
.
i_height
>>
2
)
)
{
i_fl
=
Sequence
.
i_width
>>
1
;
}
}
}
/* switch */
/* Link the new lookup tables so that they don't get freed all
* the time. */
LINK_LOOKUP
(
Sequence
.
p_frame_lum_lookup
);
LINK_LOOKUP
(
Sequence
.
p_field_lum_lookup
);
LINK_LOOKUP
(
Sequence
.
p_frame_chroma_lookup
);
LINK_LOOKUP
(
Sequence
.
p_field_chroma_lookup
);
#undef Sequence
}
/* Extension and User data */
ExtensionAndUserData
(
p_vpar
);
}
/*****************************************************************************
...
...
@@ -393,57 +306,233 @@ static void GroupHeader( vpar_thread_t * p_vpar )
*****************************************************************************/
static
void
PictureHeader
(
vpar_thread_t
*
p_vpar
)
{
int
i_coding_type
;
mtime_t
i_pts
;
undec_picture_t
*
p_undec_p
;
static
(
int
*
)
ppf_macroblock_type
[
4
]
=
{
vpar_IMBType
,
vpar_PMBType
,
vpar_BMBType
,
vpar_DMBType
};
int
i_structure
;
int
i_mb_address
,
i_mb_base
,
i_mb
;
elem_t
*
p_y
,
p_u
,
p_v
;
boolean_t
b_parsable
;
u32
i_dummy
;
DumpBits
(
&
p_vpar
->
bit_stream
,
10
);
/* temporal_reference */
i_coding_type
=
GetBits
(
&
p_vpar
->
bit_stream
,
3
);
p_vpar
->
picture
.
i_coding_type
=
GetBits
(
&
p_vpar
->
bit_stream
,
3
);
p_vpar
->
picture
.
pf_macroblock_type
=
ppf_macroblock_type
[
p_vpar
->
picture
.
i_coding_type
];
DumpBits
(
&
p_vpar
->
bit_stream
,
16
);
/* vbv_delay */
if
(
((
i_coding_type
==
P_CODING_TYPE
)
&&
(
p_vpar
->
sequence
.
p_forward
==
NULL
))
||
((
i_coding_type
==
B_CODING_TYPE
)
&&
(
p_vpar
->
sequence
.
p_forward
==
NULL
||
p_vpar
->
sequence
.
p_backward
==
NULL
))
)
{
/* The picture cannot be decoded because we lack one of the
* reference frames */
p_vpar
->
picture
.
b_full_pel_forward_vector
=
GetBits
(
&
p_vpar
->
bit_stream
,
1
);
p_vpar
->
picture
.
i_forward_f_code
=
GetBits
(
&
p_vpar
->
bit_stream
,
3
);
p_vpar
->
picture
.
b_full_pel_backward_vector
=
GetBits
(
&
p_vpar
->
bit_stream
,
1
);
p_vpar
->
picture
.
i_backward_f_code
=
GetBits
(
&
p_vpar
->
bit_stream
,
3
);
/* extra_information_picture */
while
(
GetBits
(
&
p_vpar
->
bit_stream
,
1
)
)
{
DumpBits
(
&
p_vpar
->
bit_stream
,
8
);
}
/*
* Picture Coding Extension
*/
NextStartCode
(
p_vpar
);
if
(
ShowBits
(
&
p_vpar
->
bit_stream
,
32
)
==
EXTENSION_START_CODE
)
{
/* Parse picture_coding_extension */
DumpBits32
(
&
p_vpar
->
bit_stream
);
/* extension_start_code_identifier */
DumpBits
(
&
p_vpar
->
bit_stream
,
4
);
/* Update the reference pointers */
ReferenceUpdate
(
p_vpar
,
i_coding_type
,
NULL
);
p_vpar
->
picture
.
ppi_f_code
[
0
][
0
]
=
GetBits
(
&
p_vpar
->
bit_stream
,
4
);
p_vpar
->
picture
.
ppi_f_code
[
0
][
1
]
=
GetBits
(
&
p_vpar
->
bit_stream
,
4
);
p_vpar
->
picture
.
ppi_f_code
[
1
][
0
]
=
GetBits
(
&
p_vpar
->
bit_stream
,
4
);
p_vpar
->
picture
.
ppi_f_code
[
1
][
1
]
=
GetBits
(
&
p_vpar
->
bit_stream
,
4
);
p_vpar
->
picture
.
i_intra_dc_precision
=
GetBits
(
&
p_vpar
->
bit_stream
,
2
);
i_structure
=
GetBits
(
&
p_vpar
->
bit_stream
,
2
);
p_vpar
->
picture
.
b_top_field_first
=
GetBits
(
&
p_vpar
->
bit_stream
,
1
);
p_vpar
->
picture
.
b_frame_pred_frame_dct
=
GetBits
(
&
p_vpar
->
bit_stream
,
1
);
p_vpar
->
picture
.
b_concealment_mv
=
GetBits
(
&
p_vpar
->
bit_stream
,
1
);
p_vpar
->
picture
.
b_q_scale_type
=
GetBits
(
&
p_vpar
->
bit_stream
,
1
);
p_vpar
->
picture
.
b_intra_vlc_format
=
GetBits
(
&
p_vpar
->
bit_stream
,
1
);
p_vpar
->
picture
.
b_alternate_scan
=
GetBits
(
&
p_vpar
->
bit_stream
,
1
);
/* repeat_first_field (ISO/IEC 13818-2 6.3.10 is cryptic and
* apparently the reference decoder doesn't use it, so trash it),
* chroma_420_type (obsolete) */
DumpBits
(
&
p_vpar
->
bit_stream
,
2
);
p_vpar
->
picture
.
b_progressive_frame
=
GetBits
(
&
p_vpar
->
bit_stream
,
1
);
/* Warn Synchro we have trashed a picture */
vpar_SynchroTrash
(
p_vpar
,
i_coding_type
);
return
;
/* composite_display_flag */
if
(
GetBits
(
&
p_vpar
->
bit_stream
,
1
)
)
{
/* v_axis, field_sequence, sub_carrier, burst_amplitude,
* sub_carrier_phase */
DumpBits
(
&
p_vpar
->
bit_stream
,
20
);
}
}
else
{
/* MPEG-1 compatibility flags */
p_vpar
->
i_intra_dc_precision
=
0
;
/* 8 bits */
i_structure
=
FRAME_STRUCTURE
;
p_vpar
->
b_frame_pred_frame_dct
=
TRUE
;
p_vpar
->
picture
.
b_concealment_mv
=
0
;
p_vpar
->
picture
.
b_q_scale_type
=
0
;
p_vpar
->
picture
.
b_intra_vlc_format
=
0
;
p_vpar
->
picture
.
b_alternate_scan
=
0
;
/* zigzag */
b_repeat_first_field
=
FALSE
;
p_vpar
->
picture
.
b_progressive_frame
=
TRUE
;
}
if
(
!
(
i_pts
=
vpar_SynchroChoose
(
p_vpar
,
i_coding_type
))
)
if
(
p_vpar
->
picture
.
i_current_structure
&&
(
i_structure
==
FRAME_STRUCTURE
||
i_structure
==
p_vpar
->
picture
.
i_current_structure
)
)
{
/* Synchro has decided not to decode the picture */
/* We don't have the second field of the buffered frame. */
if
(
p_pvar
->
picture
.
p_picture
!=
NULL
)
{
ReferenceReplace
(
p_vpar
,
p_vpar
->
picture
.
p_second_field_buffer
->
i_coding_type
,
NULL
);
for
(
i_mb
=
0
;
i_mb
<
p_vpar
->
sequence
.
i_mb_size
>>
1
;
i_mb
++
)
{
vpar_DestroyMacroblock
(
&
p_vpar
->
vfifo
,
p_vpar
->
picture
.
pp_mb
[
i_mb
]
);
}
vout_DestroyPicture
(
p_vpar
->
p_vout
,
p_vpar
->
picture
.
p_picture
);
}
/* Update the reference pointers */
p_pvar
->
picture
.
i_current_structure
=
0
;
intf_DbgMsg
(
"vpar debug: odd number of field picture."
);
}
if
(
p_vpar
->
picture
.
i_current_structure
)
{
/* Second field of a frame. We will decode it if, and only if we
* have decoded the first frame. */
b_parsable
=
(
p_vpar
->
picture
.
p_second_field_buffer
!=
NULL
);
}
else
{
/* Do we have the reference pictures ? */
b_parsable
=
!
((
i_coding_type
==
P_CODING_TYPE
)
&&
(
p_vpar
->
sequence
.
p_forward
==
NULL
))
||
((
i_coding_type
==
B_CODING_TYPE
)
&&
(
p_vpar
->
sequence
.
p_forward
==
NULL
||
p_vpar
->
sequence
.
p_backward
==
NULL
));
/* Does synchro say we have enough time to decode it ? */
b_parsable
&&=
vpar_SynchroChoose
(
p_vpar
,
i_coding_type
,
i_structure
);
}
if
(
!
b_parsable
)
{
/* Update the reference pointers. */
ReferenceUpdate
(
p_vpar
,
i_coding_type
,
NULL
);
/* Warn Synchro we have trashed a picture. */
vpar_SynchroTrash
(
p_vpar
,
i_coding_type
,
i_structure
);
/* Update context. */
if
(
i_structure
!=
FRAME_STRUCTURE
)
p_vpar
->
picture
.
i_current_structure
=
i_structure
;
p_vpar
->
picture
.
p_picture
=
NULL
;
return
;
}
/* OK, now we are sure we will decode the picture. Get a structure. */
p_undec_p
=
vpar_NewPicture
(
&
p_vpar
->
vfifo
);
/* Request a buffer from the video_output. */
p_undec_p
->
p_picture
=
vout_CreatePicture
(
p_vpar
->
p_vout
,
SPLITTED_YUV_PICTURE
,
p_vpar
->
sequence
.
i_width
,
p_vpar
->
sequence
.
i_height
,
p_vpar
->
sequence
.
i_chroma_format
);
/* Initialize values */
p_undec_p
->
i_coding_type
=
i_conding_type
;
p_undec_p
->
b_mpeg2
=
p_vpar
->
sequence
.
b_mpeg2
;
p_undec_p
->
i_mb_height
=
p_vpar
->
sequence
.
i_mb_height
;
p_undec_p
->
i_mb_width
=
p_vpar
->
sequence
.
i_mb_width
;
p_undec_p
->
i_pts
=
i_pts
;
/* OK, now we are sure we will decode the picture. */
#define P_picture p_vpar->picture.p_picture
p_vpar
->
picture
.
b_error
=
FALSE
;
if
(
!
p_vpar
->
picture
.
i_current_structure
)
{
/* This is a new frame. Get a structure from the video_output. */
P_picture
=
vout_CreatePicture
(
p_vpar
->
p_vout
,
SPLITTED_YUV_PICTURE
,
p_vpar
->
sequence
.
i_width
,
p_vpar
->
sequence
.
i_height
,
p_vpar
->
sequence
.
i_chroma_format
);
/* Initialize values. */
P_picture
->
date
=
vpar_SynchroDecode
(
p_vpar
,
i_coding_type
,
i_structure
);
bzero
(
p_vpar
->
picture
.
pp_mb
,
MAX_MB
*
sizeof
(
macroblock_t
*
)
);
p_vpar
->
picture
.
i_lum_incr
=
-
8
+
(
p_vpar
->
sequence
.
i_width
<<
(
i_structure
!=
FRAME_STRUCTURE
)
);
p_vpar
->
picture
.
i_chroma_incr
=
-
8
+
(
p_vpar
->
sequence
.
i_width
<<
((
i_structure
!=
FRAME_STRUCTURE
)
+
(
3
-
p_vpar
->
sequence
.
i_chroma_format
))
);
/* Update the reference pointers. */
ReferenceUpdate
(
p_vpar
,
i_coding_type
,
p_undec_p
);
}
p_vpar
->
picture
.
i_current_structure
|=
i_structure
;
p_vpar
->
picture
.
i_structure
=
i_structure
;
p_vpar
->
picture
.
b_frame_structure
=
(
i_structure
==
FRAME_STRUCTURE
);
/* Initialize picture data for decoding. */
if
(
i_structure
==
BOTTOM_FIELD
)
{
i_mb_base
=
p_vpar
->
sequence
.
i_mb_size
>>
1
;
}
else
{
i_mb_base
=
0
;
}
i_mb_address
=
0
;
/* Extension and User data. */
ExtensionAndUserData
(
p_vpar
);
/* Picture data (ISO/IEC 13818-2 6.2.3.7). */
NextStartCode
(
p_vpar
);
while
(
i_mb_address
+
i_mb_base
<
p_vpar
->
sequence
.
i_mb_size
&&
!
p_vpar
->
picture
.
b_error
)
{
if
(
((
i_dummy
=
ShowBits
(
&
p_vpar
->
bit_stream
,
32
))
<
SLICE_START_CODE_MIN
)
||
(
i_dummy
>
SLICE_START_CODE_MAX
)
)
{
intf_DbgMsg
(
"vpar debug: premature end of picture"
);
p_vpar
->
picture
.
b_error
=
TRUE
;
break
;
}
DumpBits32
(
&
p_vpar
->
bit_stream
);
/* Decode slice data. */
SliceHeader
(
p_vpar
,
&
i_mb_address
,
i_mb_base
,
i_dummy
&
255
);
}
if
(
p_vpar
->
picture
.
b_error
)
{
/* Trash picture. */
for
(
i_mb
=
0
;
p_vpar
->
picture
.
pp_mb
[
i_mb
];
i_mb
++
)
{
vpar_DestroyMacroblock
(
&
p_vpar
->
vfifo
,
p_vpar
->
picture
.
pp_mb
[
i_mb
]
);
}
ReferenceReplace
(
p_vpar
,
p_vpar
->
picture
.
i_coding_type
,
NULL
);
vout_DestroyPicture
(
p_vpar
->
p_vout
,
P_picture
);
/* Prepare context for the next picture. */
P_picture
=
NULL
:
}
else
if
(
p_vpar
->
picture
.
i_current_structure
==
FRAME_STRUCTURE
)
{
/* Frame completely parsed. */
for
(
i_mb
=
0
;
i_mb
<
p_vpar
->
sequence
.
i_mb_size
;
i_mb
++
)
{
vpar_DecodeMacroblock
(
&
p_vpar
->
vfifo
,
p_vpar
->
picture
.
pp_mb
[
i_mb
]
);
}
/* Prepare context for the next picture. */
P_picture
=
NULL
;
}
#undef P_picture
}
/*****************************************************************************
...
...
@@ -455,11 +544,115 @@ static void __inline__ ReferenceUpdate( vpar_thread_t * p_vpar,
{
if
(
i_coding_type
!=
B_CODING_TYPE
)
{
/* The P picture would have become the new p_backward reference. */
vout_UnlinkPicture
(
p_vpar
->
p_vout
,
p_vpar
->
sequence
.
p_forward
);
if
(
p_vpar
->
sequence
.
p_forward
!=
NULL
)
vout_UnlinkPicture
(
p_vpar
->
p_vout
,
p_vpar
->
sequence
.
p_forward
);
p_vpar
->
sequence
.
p_forward
=
p_vpar
->
sequence
.
p_backward
;
p_vpar
->
sequence
.
p_backward
=
p_newref
;
if
(
p_newref
!=
NULL
)
vout_LinkPicture
(
p_vpar
->
p_vout
,
p_newref
);
}
}
/*****************************************************************************
* ReferenceReplace : Replace the last reference pointer when we destroy
* a picture
*****************************************************************************/
static
void
__inline__
ReferenceReplace
(
vpar_thread_t
*
p_vpar
,
int
i_coding_type
,
picture_t
*
p_newref
)
{
if
(
i_coding_type
!=
B_CODING_TYPE
)
{
if
(
p_vpar
->
sequence
.
p_backward
!=
NULL
)
vout_UnlinkPicture
(
p_vpar
->
p_vout
,
p_vpar
->
sequence
.
p_backward
);
p_vpar
->
sequence
.
p_backward
=
p_newref
;
if
(
p_newref
!=
NULL
)
vout_LinkPicture
(
p_vpar
->
p_vout
,
p_newref
);
}
}
/*****************************************************************************
* SliceHeaderXY : Parse the next slice structure
*****************************************************************************
* X = i_height > 2800 ?
* Y = scalable_mode == SC_DP ?
*****************************************************************************/
static
void
SliceHeader00
(
vpar_thread_t
*
p_vpar
,
int
*
pi_mb_address
,
int
i_mb_base
,
u32
i_vert_code
)
{
SliceHeader
(
p_vpar
,
pi_mb_address
,
i_mb_base
,
i_vert_code
);
}
static
void
SliceHeader01
(
vpar_thread_t
*
p_vpar
,
int
*
pi_mb_address
,
int
i_mb_base
,
u32
i_vert_code
)
{
DumpBits
(
&
p_vpar
->
bit_stream
,
7
);
/* priority_breakpoint */
SliceHeader
(
p_vpar
,
pi_mb_address
,
i_mb_base
,
i_vert_code
);
}
static
void
SliceHeader10
(
vpar_thread_t
*
p_vpar
,
int
*
pi_mb_address
,
int
i_mb_base
,
u32
i_vert_code
)
{
i_vert_code
+=
GetBits
(
&
p_vpar
->
bit_stream
,
3
)
<<
7
;
SliceHeader
(
p_vpar
,
pi_mb_address
,
i_mb_base
,
i_vert_code
);
}
static
void
SliceHeader11
(
vpar_thread_t
*
p_vpar
,
int
*
pi_mb_address
,
int
i_mb_base
,
u32
i_vert_code
)
{
i_vert_code
+=
GetBits
(
&
p_vpar
->
bit_stream
,
3
)
<<
7
;
DumpBits
(
&
p_vpar
->
bit_stream
,
7
);
/* priority_breakpoint */
SliceHeader
(
p_vpar
,
pi_mb_address
,
i_mb_base
,
i_vert_code
);
}
/*****************************************************************************
* SliceHeader : Parse the next slice structure
*****************************************************************************/
static
__inline__
void
SliceHeader
(
vpar_thread_t
*
p_vpar
,
int
*
pi_mb_address
,
int
i_mb_base
,
u32
i_vert_code
)
{
/* DC predictors initialization table */
static
int
pi_dc_dct_reinit
[
4
]
=
{
128
,
256
,
512
,
1024
};
int
i_mb_address_save
=
*
pi_mb_address
;
/* slice_vertical_position_extension and priority_breakpoint already done */
LoadQuantizerScale
(
p_vpar
);
if
(
GetBits
(
&
p_vpar
->
bit_stream
,
1
)
)
{
/* intra_slice, slice_id */
DumpBits
(
&
p_vpar
->
bit_stream
,
8
);
/* extra_information_slice */
while
(
GetBits
(
&
p_vpar
->
bit_stream
,
1
)
)
{
DumpBits
(
&
p_vpar
->
bit_stream
,
8
);
}
}
*
pi_mb_address
=
(
i_vert_code
-
1
)
*
p_vpar
->
sequence
.
i_mb_width
;
/* Reset DC coefficients predictors (ISO/IEC 13818-2 7.2.1). Why
* does the reference decoder put 0 instead of the normative values ? */
p_vpar
->
slice
.
pi_dct_pred
[
0
]
=
p_vpar
->
slice
.
pi_dct_pred
[
1
]
=
p_vpar
->
slice
.
pi_dct_pred
[
2
]
=
pi_dc_dct_reinit
[
p_vpar
->
picture
.
i_intra_dc_precision
];
/* Reset motion vector predictors (ISO/IEC 13818-2 7.6.3.4). */
bzero
(
p_vpar
->
slice
.
pppi_pmv
,
8
*
sizeof
(
int
)
);
do
{
vpar_ParseMacroblock
(
p_vpar
,
pi_mb_address
,
i_mb_address_save
,
i_mb_base
);
i_mb_address_save
=
*
pi_mb_address
;
}
while
(
!
ShowBits
(
&
p_vpar
->
bit_stream
,
23
)
);
}
/*****************************************************************************
...
...
@@ -563,4 +756,3 @@ static void LinkMatrix( quant_matrix_t * p_matrix, int * pi_array )
p_matrix
->
pi_matrix
=
pi_array
;
}
src/video_parser/vpar_motion.c
0 → 100644
View file @
e229f269
/*****************************************************************************
* vpar_motion.c : motion vectors parsing
* (c)1999 VideoLAN
*****************************************************************************/
/*****************************************************************************
* Preamble
*****************************************************************************/
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/uio.h>
#include <X11/Xlib.h>
#include <X11/extensions/XShm.h>
#include "config.h"
#include "common.h"
#include "mtime.h"
#include "vlc_thread.h"
#include "intf_msg.h"
#include "debug.h"
/* ?? temporaire, requis par netlist.h */
#include "input.h"
#include "input_netlist.h"
#include "decoder_fifo.h"
#include "video.h"
#include "video_output.h"
#include "video_parser.h"
#include "video_fifo.h"
#include "video_decoder.h"
/*
* Local prototypes
*/
/*****************************************************************************
* vpar_MPEG1MotionVector : Parse the next MPEG-1 motion vector
*****************************************************************************/
void
vpar_MPEG1MotionVector
(
vpar_thread_t
*
p_vpar
,
int
i_mv
)
{
}
/*****************************************************************************
* vpar_MPEG2MotionVector : Parse the next MPEG-2 motion vector
*****************************************************************************/
void
vpar_MPEG2MotionVector
(
vpar_thread_t
*
p_vpar
,
int
i_mv
)
{
}
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