$search
00001 #include <ros/ros.h> 00002 00003 #include <theora_image_transport/Packet.h> 00004 00005 #include <theora/codec.h> 00006 #include <theora/theoraenc.h> 00007 #include <theora/theoradec.h> 00008 #include <ogg/ogg.h> 00009 00010 #include <fstream> 00011 #include <vector> 00012 #include <boost/scoped_array.hpp> 00013 00014 using namespace std; 00015 00016 class OggSaver 00017 { 00018 public: 00019 OggSaver(const char* filename) 00020 : fout_(filename, std::ios::out|std::ios::binary) 00021 { 00022 if (ogg_stream_init(&stream_state_, 0) == -1) { 00023 ROS_FATAL("Unable to initialize ogg_stream_state structure"); 00024 exit(1); 00025 } 00026 00027 sub_ = nh_.subscribe("stream", 10, &OggSaver::processMsg, this); 00028 } 00029 00030 ~OggSaver() 00031 { 00032 ogg_page page; 00033 if (ogg_stream_flush(&stream_state_, &page) != 0) 00034 writePage(page); 00035 fout_.close(); 00036 ogg_stream_clear(&stream_state_); 00037 } 00038 00039 private: 00040 00041 ros::NodeHandle nh_; 00042 ogg_stream_state stream_state_; 00043 ofstream fout_; 00044 ros::Subscriber sub_; 00045 00046 // When using this caller is responsible for deleting oggpacket.packet!! 00047 void msgToOggPacket(const theora_image_transport::Packet &msg, ogg_packet &oggpacket) 00048 { 00049 oggpacket.bytes = msg.data.size(); 00050 oggpacket.b_o_s = msg.b_o_s; 00051 oggpacket.e_o_s = msg.e_o_s; 00052 oggpacket.granulepos = msg.granulepos; 00053 oggpacket.packetno = msg.packetno; 00054 oggpacket.packet = new unsigned char[oggpacket.bytes]; 00055 memcpy(oggpacket.packet, &msg.data[0], oggpacket.bytes); 00056 } 00057 00058 void writePage(ogg_page& page) 00059 { 00060 fout_.write((char*)page.header, page.header_len); 00061 fout_.write((char*)page.body, page.body_len); 00062 } 00063 00064 void processMsg(const theora_image_transport::PacketConstPtr& message) 00065 { 00071 ogg_packet oggpacket; 00072 msgToOggPacket(*message, oggpacket); 00073 boost::scoped_array<unsigned char> packet_guard(oggpacket.packet); // Make sure packet memory gets deleted 00074 00075 if (ogg_stream_packetin(&stream_state_, &oggpacket)) { 00076 ROS_ERROR("Error while adding packet to stream."); 00077 exit(2); 00078 } 00079 00080 ogg_page page; 00081 if (ogg_stream_pageout(&stream_state_, &page) != 0) 00082 writePage(page); 00083 } 00084 }; 00085 00086 int main(int argc, char** argv) 00087 { 00090 ros::init(argc, argv, "OggSaver", ros::init_options::AnonymousName); 00091 00092 if(argc < 2) { 00093 cerr << "Usage: " << argv[0] << " stream:=/theora/image/stream outputFile" << endl; 00094 exit(3); 00095 } 00096 if (ros::names::remap("stream") == "stream") { 00097 ROS_WARN("ogg_saver: stream has not been remapped! Typical command-line usage:\n" 00098 "\t$ ./ogg_saver stream:=<theora stream topic> outputFile"); 00099 } 00100 00101 OggSaver saver(argv[1]); 00102 00103 ros::spin(); 00104 return 0; 00105 }