3 #include <schroedinger/schro.h>
10 SchroVideoFormat
*p_format
;
13 #define DIRAC_PARSE_MAGIC "BBCD"
15 int parse_packet( dirac_input_t
*h
, uint8_t **pp_data
, int *p_size
);
16 static void buffer_free( SchroBuffer
*buf
, void *priv
);
18 int open_file_dirac( char *psz_filename
, hnd_t
*p_handle
, config_t
*p_config
)
22 uint8_t *packet
= NULL
;
23 dirac_input_t
*h
= calloc(1, sizeof(*h
));
26 if( !strcmp(psz_filename
, "-") )
29 h
->fh
= fopen(psz_filename
, "rb");
33 if( parse_packet( h
, &packet
, &size
) )
41 h
->p_schro
= schro_decoder_new();
43 buffer
= schro_buffer_new_with_data( packet
, size
);
44 buffer
->free
= buffer_free
;
45 buffer
->priv
= packet
;
47 it
= schro_decoder_push( h
->p_schro
, buffer
);
48 if( it
== SCHRO_DECODER_FIRST_ACCESS_UNIT
)
50 h
->p_format
= schro_decoder_get_video_format( h
->p_schro
);
53 if( h
->p_format
->interlaced
)
54 fprintf( stderr
, "warning: sequence may be interlaced!\n" );
56 p_config
->i_width
= h
->p_format
->width
;
57 p_config
->i_height
= h
->p_format
->height
;
58 switch(h
->p_format
->chroma_format
) {
59 case SCHRO_CHROMA_420
:
60 p_config
->i_csp
= COLORSPACE_420
;
62 case SCHRO_CHROMA_444
:
63 case SCHRO_CHROMA_422
:
64 fprintf( stderr
, "ERROR: Unsupported chroma format.\n" );
72 int read_frame_dirac( hnd_t handle
, picture_t
*p_pic
, int i_frame
)
74 dirac_input_t
*h
= handle
;
81 /* This function assumes that it will be called with i_frame increasing. */
82 schro_decoder_set_earliest_frame( h
->p_schro
, i_frame
);
86 /* Handle EOF from previous iteration */
92 switch( schro_decoder_wait( h
->p_schro
) ) {
93 case SCHRO_DECODER_NEED_BITS
:
96 case SCHRO_DECODER_NEED_FRAME
:
97 switch(h
->p_format
->chroma_format
) {
98 case SCHRO_CHROMA_444
:
99 frame
= schro_frame_new_and_alloc( NULL
, SCHRO_FRAME_FORMAT_U8_444
,
100 h
->p_format
->width
, h
->p_format
->height
);
102 case SCHRO_CHROMA_422
:
103 frame
= schro_frame_new_and_alloc( NULL
, SCHRO_FRAME_FORMAT_U8_422
,
104 h
->p_format
->width
, h
->p_format
->height
);
106 case SCHRO_CHROMA_420
:
107 frame
= schro_frame_new_and_alloc( NULL
, SCHRO_FRAME_FORMAT_U8_420
,
108 h
->p_format
->width
, h
->p_format
->height
);
111 printf("ERROR: unsupported chroma format\n");
114 schro_decoder_add_output_picture( h
->p_schro
, frame
);
116 case SCHRO_DECODER_OK
:
118 int i_dts
= schro_decoder_get_picture_number( h
->p_schro
);
119 frame
= schro_decoder_pull( h
->p_schro
);
120 if( i_dts
!= i_frame
)
122 /* This shouldn't happen, why does it? */
123 schro_frame_unref(frame
);
127 memcpy( p_pic
->img
.plane
[0], frame
->components
[0].data
, frame
->components
[0].length
);
128 memcpy( p_pic
->img
.plane
[1], frame
->components
[1].data
, frame
->components
[1].length
);
129 memcpy( p_pic
->img
.plane
[2], frame
->components
[2].data
, frame
->components
[2].length
);
131 schro_frame_unref(frame
);
135 case SCHRO_DECODER_EOS
:
136 schro_decoder_reset( h
->p_schro
);
139 case SCHRO_DECODER_ERROR
:
144 if( parse_packet( h
, &packet
, &size
) )
151 schro_decoder_push_end_of_stream( h
->p_schro
);
154 buffer
= schro_buffer_new_with_data( packet
, size
);
155 buffer
->free
= buffer_free
;
156 buffer
->priv
= packet
;
158 schro_decoder_push( h
->p_schro
, buffer
);
166 int close_file_dirac( hnd_t handle
)
168 dirac_input_t
*h
= handle
;
169 if( !h
|| !h
->fh
|| !h
->p_schro
|| !h
->p_format
)
173 schro_decoder_free( h
->p_schro
);
178 /* From schroedinger-tools */
179 int parse_packet( dirac_input_t
*h
, uint8_t **pp_data
, int *p_size
)
186 n
= fread( header
, 1, 13, h
->fh
);
187 if( feof( h
->fh
) ) {
193 fprintf( stderr
, "ERROR: truncated header\n" );
197 if( strncmp((char *)header
, DIRAC_PARSE_MAGIC
, strlen(DIRAC_PARSE_MAGIC
)) ) {
198 fprintf( stderr
, "ERROR: header magic incorrect\n" );
202 size
= (header
[5]<<24) | (header
[6]<<16) | (header
[7]<<8) | (header
[8]);
207 fprintf( stderr
, "ERROR: packet too small? (%d)\n", size
);
211 fprintf( stderr
, "ERROR: packet too large? (%d > 1<<24)\n", size
);
215 packet
= malloc( size
);
216 memcpy( packet
, header
, 13 );
217 n
= fread( packet
+ 13, 1, size
- 13, h
->fh
);
218 if( n
< size
- 13 ) {
228 static void buffer_free( SchroBuffer
*buf
, void *priv
)