1 /* Schrodinger decoder wrapper to for non GStreamer applications
2 * derived from gstschrodec.c & testsuite/decode.c
3 * 2006 Jon Rosser BBC R&D
14 #include <schroedinger/schro.h>
15 #include <schroedinger/schroparams.h>
17 #include <boost/program_options.hpp>
18 namespace po
= boost::program_options
;
23 /* global variables */
24 static std::string inFileName
;
25 static std::string outFileName
;
26 static bool verbose
= false;
28 /* function prototypes */
29 static bool parseCommandLine(int argc
, char *argv
[]);
30 static void decode(FILE*, FILE*);
32 int main(int argc
, char **argv
)
39 if(parseCommandLine(argc
, argv
)) {
43 /* open an input and output files */
44 inFile
= fopen(inFileName
.c_str(), "rb");
46 fprintf(stderr
, "Could not open input file %s\n", inFileName
.c_str());
50 outFile
= fopen(outFileName
.c_str(), "wb");
52 fprintf(stderr
, "Could not open output file %s\n", outFileName
.c_str());
56 decode(inFile
, outFile
);
58 if(verbose
) printf("\nClosing files\n");
64 bool parseCommandLine(int argc
, char **argv
)
70 //Video format options
71 po::options_description
desc("Allowed Options");
73 ("help", " Show this message")
74 ("verbose,v", " Enable verbose decoding")
75 ("input", po::value(&inFileName
), "string Dirac bitstream to decode")
76 ("output", po::value(&outFileName
), "string YUV planar output file");
78 //the filenames are 'positional options'
79 po::positional_options_description p
;
83 //do the command line parsing
85 po::store(po::command_line_parser(argc
, argv
). options(desc
).positional(p
).run(), vm
);
89 if(vm
.count("verbose")) verbose
=true;
90 if(vm
.count("help")) {
91 std::cout
<< "Usage : schro_decode [flags] input output" << std::endl
;
92 std::cout
<< desc
<< std::endl
;
96 if(vm
.count("input") == 0)
97 throw(std::runtime_error("No input file specified"));
99 if(vm
.count("output") == 0)
100 throw(std::runtime_error("No output file specified"));
103 catch(std::exception
& e
)
105 printf("Command line error : ");
106 std::cout
<< e
.what() << "\n";
114 buffer_free (SchroBuffer
*buf
, void *priv
)
119 /* push the data through the decoder */
120 static void decode(FILE *infile
, FILE *outfile
)
122 SchroDecoder
*decoder
;
124 SchroVideoFormat
*format
= NULL
;
133 decoder
= schro_decoder_new();
137 //on the previous iteration feof(inFile) = true, so stop
141 //get a packet from the stream and push it to the decoder
142 ret
= parse_packet (infile
, &packet
, &size
);
149 //unexpected end of file from parser
150 schro_decoder_push_end_of_stream (decoder
);
152 buffer
= schro_buffer_new_with_data (packet
, size
);
153 buffer
->free
= buffer_free
;
154 buffer
->priv
= packet
;
156 it
= schro_decoder_push (decoder
, buffer
);
157 if (it
== SCHRO_DECODER_FIRST_ACCESS_UNIT
) {
158 format
= schro_decoder_get_video_format (decoder
);
160 printf("\nFirst Sequence Header:\n");
161 showVideoFormat(format
);
166 //iterate the decoder until it needs more data
169 it
= schro_decoder_wait (decoder
);
172 case SCHRO_DECODER_NEED_BITS
:
175 case SCHRO_DECODER_NEED_FRAME
:
176 switch(format
->chroma_format
) {
177 case SCHRO_CHROMA_444
:
178 frame
= schro_frame_new_and_alloc (NULL
, SCHRO_FRAME_FORMAT_U8_444
,
179 format
->width
, format
->height
);
181 case SCHRO_CHROMA_422
:
182 frame
= schro_frame_new_and_alloc (NULL
, SCHRO_FRAME_FORMAT_U8_422
,
183 format
->width
, format
->height
);
185 case SCHRO_CHROMA_420
:
186 frame
= schro_frame_new_and_alloc (NULL
, SCHRO_FRAME_FORMAT_U8_420
,
187 format
->width
, format
->height
);
190 printf("error: unrecognised chroma format\n");
194 schro_decoder_add_output_picture (decoder
, frame
);
196 case SCHRO_DECODER_OK
:
197 frame
= schro_decoder_pull (decoder
);
200 printf("writing output frame %d\r", framecount
++);
203 // write frame data out in planar format
204 fwrite(frame
->components
[0].data
, frame
->components
[0].length
, 1, outfile
);
205 fwrite(frame
->components
[1].data
, frame
->components
[1].length
, 1, outfile
);
206 fwrite(frame
->components
[2].data
, frame
->components
[2].length
, 1, outfile
);
207 schro_frame_unref(frame
);
210 case SCHRO_DECODER_EOS
:
211 if(verbose
) printf("\nGot End of Sequence");
212 schro_decoder_reset(decoder
);
215 case SCHRO_DECODER_ERROR
:
216 printf("\nerror: got decoder internal error - exiting\n");
225 if(verbose
) printf("\nFreeing decoder");
226 schro_decoder_free (decoder
);