2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2014
3 // Free Software Foundation, Inc
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"
42 #include "arg_parser.h"
44 using namespace cygnal
;
46 using namespace gnash
;
49 gnash::LogFile
& dbglogfile
= gnash::LogFile::getDefaultInstance();
50 gnash::RcInitFile
& rcfile
= gnash::RcInitFile::getDefaultInstance();
53 #ifdef BOOST_NO_EXCEPTIONS
57 void throw_exception(std::exception
const & e
)
66 static const char *codec_strs
[] = {
79 static const char *format_strs
[] = {
87 // These next are only supported by Gnash
91 static const char *frame_strs
[] = {
98 static const char *size_strs
[] = {
103 static const char *type_strs
[] = {
108 static const char *rate_strs
[] = {
116 main(int argc
, char *argv
[])
118 bool dump
= false; // dump the FLV data
119 bool all
= false; // dump all the tags too
120 bool meta
= true; // dump all Meta tags only
121 vector
<string
> infiles
;
123 // Enable native language support, i.e. internationalization
125 setlocale (LC_ALL
, "");
126 bindtextdomain (PACKAGE
, LOCALEDIR
);
127 textdomain (PACKAGE
);
129 const Arg_parser::Option opts
[] =
131 { 'h', "help", Arg_parser::no
},
132 { 'v', "verbose", Arg_parser::no
},
133 { 'd', "dump", Arg_parser::no
},
134 { 'a', "all", Arg_parser::no
},
135 { 'm', "meta", Arg_parser::no
},
138 Arg_parser
parser(argc
, argv
, opts
);
139 if( ! parser
.error().empty() ) {
140 cout
<< parser
.error() << endl
;
144 for( int i
= 0; i
< parser
.arguments(); ++i
) {
145 const int code
= parser
.code(i
);
152 dbglogfile
.setVerbosity();
153 log_debug(_("Verbose output turned on"));
165 infiles
.push_back(parser
.argument(i
));
170 catch (Arg_parser::ArgParserException
&e
) {
171 cerr
<< _("Error parsing command line options: ") << e
.what() << endl
;
172 cerr
<< _("This is a Gnash flvdumper bug.") << endl
;
176 if (infiles
.empty()) {
177 cerr
<< _("Error: no input file was specified. Exiting.") << endl
;
182 // Get the filename from the command line
183 string filespec
= infiles
[0];
188 // std::shared_ptr<Flv::flv_header_t> head;
189 Flv::previous_size_t previous
= 0;
190 std::shared_ptr
<Flv::flv_tag_t
> tag
;
192 // Make sure it's an FLV file
193 if (stat(filespec
.c_str(), &st
) == 0) {
195 // Open the binary file
196 ifstream
ifs(filespec
.c_str(), ios::binary
);
197 std::shared_ptr
<cygnal::Buffer
> buf(new Buffer
);
198 // Read just the initial 9 byte header
199 ifs
.read(reinterpret_cast<char *>(buf
->reference()), sizeof(Flv::flv_header_t
));
200 log_debug("header is: %s", hexify(buf
->reference(), 9, false));
201 std::shared_ptr
<Flv::flv_header_t
> head
= flv
.decodeHeader(buf
);
203 log_error("Couldn't decode the header! %s", hexify(buf
->reference(), 9, false));
206 if ((head
->type
& Flv::FLV_VIDEO
) && (head
->type
& Flv::FLV_AUDIO
)) {
207 cout
<<"FLV File type: Video and Audio" << endl
;
208 } else if (head
->type
&& Flv::FLV_VIDEO
) {
209 cout
<< "FLV File type: Video" << endl
;
210 } else if (head
->type
&& Flv::FLV_AUDIO
) {
211 cout
<<"FLV File type: Audio" << endl
;
214 cout
<< "FLV Version: " << int(head
->version
) << " (should always be 1)" << endl
;
215 std::uint32_t headsize
= flv
.convert24(head
->head_size
);
217 cout
<< "FLV Header size: " << headsize
<< " (should always be 9)" << endl
;
219 // Extract all the Tags
220 //size_t total = st.st_size - sizeof(Flv::flv_header_t);
222 ifs
.read(reinterpret_cast<char *>(&previous
), sizeof(Flv::previous_size_t
));
223 if (ifs
.gcount() != sizeof(Flv::previous_size_t
)) {
224 log_error("Couldn't read the entire header");
227 previous
= ntohl(previous
);
228 //total -= sizeof(Flv::previous_size_t);
230 cout
<< "FLV Previous Tag Size was: " << previous
<< endl
;
232 ifs
.read(reinterpret_cast<char *>(buf
->reference()), sizeof(Flv::flv_tag_t
));
233 if (ifs
.gcount() != sizeof(Flv::flv_tag_t
)) {
234 log_error("Couldn't read the entire tag");
236 tag
= flv
.decodeTagHeader(buf
);
240 //total -= sizeof(Flv::previous_size_t);
241 size_t bodysize
= flv
.convert24(tag
->bodysize
);
243 cerr
<< "FLV Tag size is zero, skipping reading packet body " << bodysize
<< endl
;
247 cout
<< "FLV Tag size is: " << bodysize
+ sizeof(Flv::previous_size_t
) << endl
;
250 buf
->resize(bodysize
);
251 ifs
.read(reinterpret_cast<char *>(buf
->reference()), bodysize
);
252 // if (ifs.gcount() != bodysize) {
253 // log_error("Couldn't read the entire body");
260 cerr
<< "FLV Tag type is: Audio" << endl
;
261 std::shared_ptr
<Flv::flv_audio_t
> data
= flv
.decodeAudioData(*(buf
->reference() + sizeof(Flv::flv_tag_t
)));
262 cout
<< "\tSound Type is: " << type_strs
[data
->type
] << endl
;
263 cout
<< "\tSound Size is: " << size_strs
[data
->size
] << endl
;
264 cout
<< "\tSound Rate is: " << rate_strs
[data
->rate
] << endl
;
265 cout
<< "\tSound Format is: " << format_strs
[data
->format
] << endl
;
272 cout
<< "FLV Tag type is: Video" << endl
;
273 std::shared_ptr
<Flv::flv_video_t
> data
= flv
.decodeVideoData(*(buf
->reference() + sizeof(Flv::flv_tag_t
)));
274 cout
<< "\tCodec ID is: " << codec_strs
[data
->codecID
] << endl
;
275 cout
<< "\tFrame Type is: " << frame_strs
[data
->type
] << endl
;
279 case Flv::TAG_METADATA
:
281 cout
<< "FLV Tag type is: MetaData" << endl
;
283 std::shared_ptr
<cygnal::Element
> metadata
= flv
.decodeMetaData(buf
->reference(), bodysize
);
284 if (meta
&& metadata
) {
290 } catch (std::exception
& e
) {
291 log_error("Reading %s: %s", filespec
, e
.what());
297 /// \brief Display the command line arguments
301 cerr
<< _("This program dumps the internal data of an FLV video file")
303 cerr
<< _("Usage: flvdumper [-h] [-m] [-a] filename") << endl
;
304 cerr
<< _("-h\tHelp") << endl
;
305 cerr
<< _("-m\tPrint only Meta tags (default)") << endl
;
306 cerr
<< _("-a\tPrint all tags.") << endl
;
312 // indent-tabs-mode: t