2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 #include "gnashconfig.h"
23 #include "GnashFileUtilities.h"
24 #include "GnashSystemNetHeaders.h"
26 #include <boost/shared_ptr.hpp>
43 #include "arg_parser.h"
45 using namespace cygnal
;
47 using namespace gnash
;
50 gnash::LogFile
& dbglogfile
= gnash::LogFile::getDefaultInstance();
51 gnash::RcInitFile
& rcfile
= gnash::RcInitFile::getDefaultInstance();
54 #ifdef BOOST_NO_EXCEPTIONS
58 void throw_exception(std::exception
const & e
)
67 static const char *codec_strs
[] = {
80 static const char *format_strs
[] = {
88 // These next are only supported by Gnash
92 static const char *frame_strs
[] = {
99 static const char *size_strs
[] = {
104 static const char *type_strs
[] = {
109 static const char *rate_strs
[] = {
117 main(int argc
, char *argv
[])
119 bool dump
= false; // dump the FLV data
120 bool all
= false; // dump all the tags too
121 bool meta
= true; // dump all Meta tags only
122 vector
<string
> infiles
;
124 // Enable native language support, i.e. internationalization
126 std::setlocale (LC_ALL
, "");
127 bindtextdomain (PACKAGE
, LOCALEDIR
);
128 textdomain (PACKAGE
);
130 const Arg_parser::Option opts
[] =
132 { 'h', "help", Arg_parser::no
},
133 { 'v', "verbose", Arg_parser::no
},
134 { 'd', "dump", Arg_parser::no
},
135 { 'a', "all", Arg_parser::no
},
136 { 'm', "meta", Arg_parser::no
},
139 Arg_parser
parser(argc
, argv
, opts
);
140 if( ! parser
.error().empty() ) {
141 cout
<< parser
.error() << endl
;
145 for( int i
= 0; i
< parser
.arguments(); ++i
) {
146 const int code
= parser
.code(i
);
153 dbglogfile
.setVerbosity();
154 log_debug(_("Verbose output turned on"));
166 infiles
.push_back(parser
.argument(i
));
171 catch (Arg_parser::ArgParserException
&e
) {
172 cerr
<< _("Error parsing command line options: ") << e
.what() << endl
;
173 cerr
<< _("This is a Gnash flvdumper bug.") << endl
;
177 if (infiles
.empty()) {
178 cerr
<< _("Error: no input file was specified. Exiting.") << endl
;
183 // Get the filename from the command line
184 string filespec
= infiles
[0];
189 // boost::shared_ptr<Flv::flv_header_t> head;
190 Flv::previous_size_t previous
= 0;
191 boost::shared_ptr
<Flv::flv_tag_t
> tag
;
193 // Make sure it's an FLV file
194 if (stat(filespec
.c_str(), &st
) == 0) {
196 // Open the binary file
197 ifstream
ifs(filespec
.c_str(), ios::binary
);
198 boost::shared_ptr
<cygnal::Buffer
> buf(new Buffer
);
199 // Read just the initial 9 byte header
200 ifs
.read(reinterpret_cast<char *>(buf
->reference()), sizeof(Flv::flv_header_t
));
201 log_debug("header is: %s", hexify(buf
->reference(), 9, false));
202 boost::shared_ptr
<Flv::flv_header_t
> head
= flv
.decodeHeader(buf
);
204 log_error("Couldn't decode the header! %s", hexify(buf
->reference(), 9, false));
207 if ((head
->type
& Flv::FLV_VIDEO
) && (head
->type
& Flv::FLV_AUDIO
)) {
208 cout
<<"FLV File type: Video and Audio" << endl
;
209 } else if (head
->type
&& Flv::FLV_VIDEO
) {
210 cout
<< "FLV File type: Video" << endl
;
211 } else if (head
->type
&& Flv::FLV_AUDIO
) {
212 cout
<<"FLV File type: Audio" << endl
;
215 cout
<< "FLV Version: " << int(head
->version
) << " (should always be 1)" << endl
;
216 boost::uint32_t headsize
= flv
.convert24(head
->head_size
);
218 cout
<< "FLV Header size: " << headsize
<< " (should always be 9)" << endl
;
220 // Extract all the Tags
221 size_t total
= st
.st_size
- sizeof(Flv::flv_header_t
);
223 ifs
.read(reinterpret_cast<char *>(&previous
), sizeof(Flv::previous_size_t
));
224 if (ifs
.gcount() != sizeof(Flv::previous_size_t
)) {
225 log_error("Couldn't read the entire header");
228 previous
= ntohl(previous
);
229 total
-= sizeof(Flv::previous_size_t
);
231 cout
<< "FLV Previous Tag Size was: " << previous
<< endl
;
233 ifs
.read(reinterpret_cast<char *>(buf
->reference()), sizeof(Flv::flv_tag_t
));
234 if (ifs
.gcount() != sizeof(Flv::flv_tag_t
)) {
235 log_error("Couldn't read the entire tag");
237 tag
= flv
.decodeTagHeader(buf
);
239 total
-= sizeof(Flv::previous_size_t
);
240 size_t bodysize
= flv
.convert24(tag
->bodysize
);
242 cerr
<< "FLV Tag size is zero, skipping reading packet body " << bodysize
<< endl
;
246 cout
<< "FLV Tag size is: " << bodysize
+ sizeof(Flv::previous_size_t
) << endl
;
249 buf
->resize(bodysize
);
250 ifs
.read(reinterpret_cast<char *>(buf
->reference()), bodysize
);
251 // if (ifs.gcount() != bodysize) {
252 // log_error("Couldn't read the entire body");
259 cerr
<< "FLV Tag type is: Audio" << endl
;
260 boost::shared_ptr
<Flv::flv_audio_t
> data
= flv
.decodeAudioData(*(buf
->reference() + sizeof(Flv::flv_tag_t
)));
261 cout
<< "\tSound Type is: " << type_strs
[data
->type
] << endl
;
262 cout
<< "\tSound Size is: " << size_strs
[data
->size
] << endl
;
263 cout
<< "\tSound Rate is: " << rate_strs
[data
->rate
] << endl
;
264 cout
<< "\tSound Format is: " << format_strs
[data
->format
] << endl
;
271 cout
<< "FLV Tag type is: Video" << endl
;
272 boost::shared_ptr
<Flv::flv_video_t
> data
= flv
.decodeVideoData(*(buf
->reference() + sizeof(Flv::flv_tag_t
)));
273 cout
<< "\tCodec ID is: " << codec_strs
[data
->codecID
] << endl
;
274 cout
<< "\tFrame Type is: " << frame_strs
[data
->type
] << endl
;
278 case Flv::TAG_METADATA
:
280 cout
<< "FLV Tag type is: MetaData" << endl
;
282 boost::shared_ptr
<cygnal::Element
> metadata
= flv
.decodeMetaData(buf
->reference(), bodysize
);
283 if (meta
&& metadata
) {
289 } catch (std::exception
& e
) {
290 log_error("Reading %s: %s", filespec
, e
.what());
296 /// \brief Display the command line arguments
300 cerr
<< _("This program dumps the internal data of an FLV video file")
302 cerr
<< _("Usage: flvdumper [-h] [-m] [-a] filename") << endl
;
303 cerr
<< _("-h\tHelp") << endl
;
304 cerr
<< _("-m\tPrint only Meta tags (default)") << endl
;
305 cerr
<< _("-a\tPrint all tags.") << endl
;
311 // indent-tabs-mode: t