1 /* Schrodinger encoder wrapper for non GStreamer applications
2 * 2006 Jon Rosser BBC R&D
9 #include <schroedinger/schro.h>
11 #include "schrooptions.h"
12 #include <boost/program_options.hpp>
13 namespace po
= boost::program_options
;
17 /* global variables */
18 static std::string inFileName
;
19 static std::string outFileName
;
22 static int start_pos
= 0;
23 static int end_pos
= -1;
24 static SchroVideoFormat
*format
= NULL
;
25 static SchroEncoder
*encoder
= NULL
;
26 static bool verbose
= false;
28 /* function prototypes */
29 static bool parseCommandLine(int argc
, char *argv
[]);
31 static void encode_frame_free (SchroFrame
*frame
, void *priv
)
36 /* main coding loop */
37 int main(int argc
, char *argv
[])
39 SchroBuffer
*buffer
= NULL
;
40 SchroFrame
*frame
= NULL
;
41 int presentation_frame
;
46 encoder
= schro_encoder_new();
47 format
= schro_encoder_get_video_format(encoder
);
49 if(parseCommandLine(argc
, argv
)) {
54 showVideoFormat(format
);
55 showEncoderSettings(encoder
);
58 if(schro_video_format_validate(format
) != 1) {
59 printf("Video format is not valid for encoder\n");
63 schro_encoder_set_video_format(encoder
, format
);
64 size_t frame_size
= (size_t)(format
->width
*format
->height
);
66 switch (format
->chroma_format
)
68 case SCHRO_CHROMA_444
:
71 case SCHRO_CHROMA_422
:
74 case SCHRO_CHROMA_420
:
76 frame_size
= (frame_size
*3)/2;
80 /* open an input and output files */
81 inFile
= fopen(inFileName
.c_str(), "rb");
84 printf("Could not open input file %s\n", inFileName
.c_str());
88 outFile
= fopen(outFileName
.c_str(), "wb");
91 printf("Could not open output file %s\n", outFileName
.c_str());
95 /* seek into the file if required to satisfy start_pos */
96 if (start_pos
!= 0) fseek(inFile
, (frame_size
* start_pos
), SEEK_CUR
);
98 /* if end_pos is -1, make lots of frames */
102 /* encode the required number of frames */
103 schro_encoder_start (encoder
);
105 switch(schro_encoder_wait(encoder
))
107 case SCHRO_STATE_NEED_FRAME
:
110 unsigned char *buf
= (unsigned char *)malloc(frame_size
);
111 /* read from input file into frame */
112 if (inFrame
> (end_pos
- start_pos
) ||fread (buf
, 1, frame_size
, inFile
) != frame_size
)
115 schro_encoder_end_of_stream(encoder
);
119 /* make a new frame */
120 switch (format
->chroma_format
)
122 case SCHRO_CHROMA_444
:
123 frame
= frame_new_from_data_u8_planar444(buf
, format
->width
, format
->height
);
125 case SCHRO_CHROMA_422
:
126 frame
= frame_new_from_data_u8_planar422(buf
, format
->width
, format
->height
);
128 case SCHRO_CHROMA_420
:
129 frame
= schro_frame_new_from_data_I420(buf
, format
->width
, format
->height
);
132 printf("error: unknown chroma format\n");
136 schro_frame_set_free_callback (frame
, encode_frame_free
, buf
);
138 printf("Pushing frame %d \r", inFrame
++);
141 schro_encoder_push_frame(encoder
, frame
);
145 case SCHRO_STATE_HAVE_BUFFER
:
146 buffer
= schro_encoder_pull (encoder
, &presentation_frame
);
147 fwrite(buffer
->data
, 1, buffer
->length
, outFile
);
148 schro_buffer_unref (buffer
);
151 case SCHRO_STATE_AGAIN
:
154 case SCHRO_STATE_END_OF_STREAM
:
155 // pull end of stream info
156 buffer
= schro_encoder_pull (encoder
, &presentation_frame
);
157 fwrite(buffer
->data
, 1, buffer
->length
, outFile
);
158 schro_buffer_unref (buffer
);
166 //while ((inFrame <= (end_pos - start_pos)) && (feof(inFile) == 0) && go == 1);
169 printf("\nFinished encoding\n");
170 schro_encoder_free(encoder
);
177 bool parseCommandLine(int argc
, char **argv
)
179 int wrap_length
=800; //make the internal line from boost have a really long line. The terminal does wrapping instead
180 po::variables_map vm
;
184 //Video format options
185 po::options_description
video_coding_options("Video Format Options Used During Coding", wrap_length
);
186 addVideoCodingOptions(video_coding_options
);
188 po::options_description
video_metadata_options("Video Format MetaData", wrap_length
);
189 addVideoMetadataOptions(video_metadata_options
);
191 po::options_description
other_options("Other", wrap_length
);
192 other_options
.add_options()
193 ("start", po::value(&start_pos
), "uint 0 \t Frame number to start coding")
194 ("stop", po::value(&end_pos
), "uint EOF \t Frame number to stop coding")
195 ("verbose,v", "Show encoder settings before encoding")
196 ("input", po::value(&inFileName
), "Planar YUV file to encode")
197 ("output", po::value(&outFileName
), "Dirac bitstream output file")
198 ("help", "Show help");
200 //add dynamic options
201 po::options_description
dynamic_options("Encoder Coding Options", wrap_length
);
202 addDynamicOptions(dynamic_options
);
204 //merge the groups of option descriptions
205 po::options_description
all("Allowed Options");
206 all
.add(video_coding_options
).add(video_metadata_options
).add(dynamic_options
).add(other_options
);
208 //the filenames are 'positional options'
209 po::positional_options_description p
;
213 //do the command line parsing
214 po::store(po::command_line_parser(argc
, argv
). options(all
).positional(p
).run(), vm
);
217 //decode some overall flags
218 if(vm
.count("verbose")) verbose
=true;
219 if(vm
.count("help")) {
220 std::cout
<< "Usage : schro_encode [flags] input output" << std::endl
;
221 std::cout
<< video_coding_options
<< std::endl
;
222 std::cout
<< video_metadata_options
<< std::endl
;
223 std::cout
<< dynamic_options
<< std::endl
;
224 std::cout
<< other_options
<< std::endl
;
228 catch(std::exception
& e
)
230 printf("Command line error : ");
231 std::cout
<< e
.what() << "\n";
235 applyVideoCodingOptions(format
, vm
);
236 applyVideoMetadataOptions(format
, vm
);
237 return applyDynamicOptions(encoder
, vm
);