3 #include <schroedinger/schro.h>
10 SchroVideoFormat
*p_format
;
13 int parse_packet( dirac_input_t
*h
, uint8_t **pp_data
, int *p_size
);
14 static void buffer_free( SchroBuffer
*buf
, void *priv
);
16 int open_file_dirac( char *psz_filename
, hnd_t
*p_handle
, config_t
*p_config
)
20 uint8_t *packet
= NULL
;
21 dirac_input_t
*h
= calloc(1, sizeof(*h
));
24 if( !strcmp(psz_filename
, "-") )
27 h
->fh
= fopen(psz_filename
, "rb");
31 if( parse_packet( h
, &packet
, &size
) )
39 h
->p_schro
= schro_decoder_new();
41 buffer
= schro_buffer_new_with_data( packet
, size
);
42 buffer
->free
= buffer_free
;
43 buffer
->priv
= packet
;
45 it
= schro_decoder_push( h
->p_schro
, buffer
);
46 if( it
== SCHRO_DECODER_FIRST_ACCESS_UNIT
)
48 h
->p_format
= schro_decoder_get_video_format( h
->p_schro
);
51 if( h
->p_format
->interlaced
)
52 fprintf( stderr
, "warning: sequence may be interlaced!\n" );
54 p_config
->i_width
= h
->p_format
->width
;
55 p_config
->i_height
= h
->p_format
->height
;
56 switch(h
->p_format
->chroma_format
) {
57 case SCHRO_CHROMA_420
:
58 p_config
->i_csp
= COLORSPACE_420
;
60 case SCHRO_CHROMA_444
:
61 case SCHRO_CHROMA_422
:
62 fprintf( stderr
, "ERROR: Unsupported chroma format.\n" );
70 int read_frame_dirac( hnd_t handle
, picture_t
*p_pic
, int i_frame
)
72 dirac_input_t
*h
= handle
;
79 /* This function assumes that it will be called with i_frame increasing. */
80 schro_decoder_set_earliest_frame( h
->p_schro
, i_frame
);
84 /* Handle EOF from previous iteration */
90 switch( schro_decoder_wait( h
->p_schro
) ) {
91 case SCHRO_DECODER_NEED_BITS
:
94 case SCHRO_DECODER_NEED_FRAME
:
95 switch(h
->p_format
->chroma_format
) {
96 case SCHRO_CHROMA_444
:
97 frame
= schro_frame_new_and_alloc( NULL
, SCHRO_FRAME_FORMAT_U8_444
,
98 h
->p_format
->width
, h
->p_format
->height
);
100 case SCHRO_CHROMA_422
:
101 frame
= schro_frame_new_and_alloc( NULL
, SCHRO_FRAME_FORMAT_U8_422
,
102 h
->p_format
->width
, h
->p_format
->height
);
104 case SCHRO_CHROMA_420
:
105 frame
= schro_frame_new_and_alloc( NULL
, SCHRO_FRAME_FORMAT_U8_420
,
106 h
->p_format
->width
, h
->p_format
->height
);
109 printf("ERROR: unsupported chroma format\n");
112 schro_decoder_add_output_picture( h
->p_schro
, frame
);
114 case SCHRO_DECODER_OK
:
116 int i_dts
= schro_decoder_get_picture_number( h
->p_schro
);
117 frame
= schro_decoder_pull( h
->p_schro
);
118 if( i_dts
!= i_frame
)
120 /* This shouldn't happen, why does it? */
121 schro_frame_unref(frame
);
125 memcpy( p_pic
->img
.plane
[0], frame
->components
[0].data
, frame
->components
[0].length
);
126 memcpy( p_pic
->img
.plane
[1], frame
->components
[1].data
, frame
->components
[1].length
);
127 memcpy( p_pic
->img
.plane
[2], frame
->components
[2].data
, frame
->components
[2].length
);
129 schro_frame_unref(frame
);
133 case SCHRO_DECODER_EOS
:
134 schro_decoder_reset( h
->p_schro
);
137 case SCHRO_DECODER_ERROR
:
142 if( parse_packet( h
, &packet
, &size
) )
149 schro_decoder_push_end_of_stream( h
->p_schro
);
152 buffer
= schro_buffer_new_with_data( packet
, size
);
153 buffer
->free
= buffer_free
;
154 buffer
->priv
= packet
;
156 schro_decoder_push( h
->p_schro
, buffer
);
164 int close_file_dirac( hnd_t handle
)
166 dirac_input_t
*h
= handle
;
167 if( !h
|| !h
->fh
|| !h
->p_schro
|| !h
->p_format
)
171 schro_decoder_free( h
->p_schro
);
176 /* From schroedinger-tools */
177 int parse_packet( dirac_input_t
*h
, uint8_t **pp_data
, int *p_size
)
184 n
= fread( header
, 1, 13, h
->fh
);
185 if( feof( h
->fh
) ) {
191 fprintf( stderr
, "ERROR: truncated header\n" );
195 if( header
[0] != 'B' || header
[1] != 'B' || header
[2] != 'C' ||
197 fprintf( stderr
, "ERROR: header magic incorrect\n" );
201 size
= (header
[5]<<24) | (header
[6]<<16) | (header
[7]<<8) | (header
[8]);
206 fprintf( stderr
, "ERROR: packet too small? (%d)\n", size
);
210 fprintf( stderr
, "ERROR: packet too large? (%d > 1<<24)\n", size
);
214 packet
= malloc( size
);
215 memcpy( packet
, header
, 13 );
216 n
= fread( packet
+ 13, 1, size
- 13, h
->fh
);
217 if( n
< size
- 13 ) {
227 static void buffer_free( SchroBuffer
*buf
, void *priv
)