SSDV keep sorted packets.

ssdv
Michal Fratczak 2020-04-24 12:57:10 +02:00
rodzic 507351d6a6
commit cfaa6797a0
2 zmienionych plików z 60 dodań i 57 usunięć

Wyświetl plik

@ -19,6 +19,7 @@
*/
#include "ssdv_wrapper.h"
#include <memory>
#include <cstddef>
#include <cstring>
#include <iostream>
@ -26,28 +27,17 @@
#include <stdio.h>
#include "../ssdv/ssdv.h"
void print_hex(const std::vector<uint8_t>& v)
static void print_hex(const std::array<uint8_t,256>& v)
{
for(auto c : v) std::cout<<"0x"<<std::hex<<(int)c<<" ";
std::cout<<std::dec<<std::endl;
}
namespace habdec
{
SSDV_wraper_t::SSDV_wraper_t()
{
jpeg = new uint8_t[1024 * 1024 * 3];
ssdv_dec_init(&ssdv);
ssdv_dec_set_buffer(&ssdv, jpeg, 1024*1024*3);
}
SSDV_wraper_t::~SSDV_wraper_t()
{
delete [] jpeg;
}
bool SSDV_wraper_t::push(const std::vector<char>& i_chars)
{
@ -82,8 +72,6 @@ bool SSDV_wraper_t::push(const std::vector<char>& i_chars)
if( buff_.size() < SSDV_PKT_SIZE )
return false;
// print_hex(buff_);
int errors = 0;
const int is_packet = ssdv_dec_is_packet( buff_.data(), &errors );
if( is_packet != 0 ) // no packet starting at packet_begin_
@ -95,53 +83,43 @@ bool SSDV_wraper_t::push(const std::vector<char>& i_chars)
return false;
}
ssdv_packet_info_t packet_header;
ssdv_dec_header( &packet_header, buff_.data() );
cout<<"SSDV Packet "
<<packet_header.packet_id<<" of image "<<(int)packet_header.image_id
<<" MCU id "<<(int)packet_header.mcu_id
<<" MCU offset "<<(int)packet_header.mcu_offset
<<" EOI "<<(int)packet_header.eoi
<<endl;
if(0)
{
fprintf(stderr, "Decoded image packet. Callsign: %s, Image ID: %d, Packet ID: %d, Resolution: %dx%d, (%d errors corrected) "
"Type: %d, Quality: %d, EOI: %d, MCU Mode: %d, MCU Offset: %d, MCU ID: %d/%d\n",
packet_header.callsign_s,
packet_header.image_id,
packet_header.packet_id,
packet_header.width,
packet_header.height,
errors,
packet_header.type,
packet_header.quality,
packet_header.eoi,
packet_header.mcu_mode,
packet_header.mcu_offset,
packet_header.mcu_id,
packet_header.mcu_count
);
}
ssdv_dec_feed( &ssdv, buff_.data() );
// make packet and decode header
shared_ptr<packet_t> p_packet(new packet_t);
memcpy( p_packet->data_.data(), buff_.data(), sizeof(p_packet->data_) );
buff_.erase( buff_.begin(), buff_.begin() + SSDV_PKT_SIZE);
packet_begin_ = -1;
ssdv_dec_header( &(p_packet->header_), p_packet->data_.data() );
// save jpeg
if(packet_header.eoi)
//insert to image_ map
pair<string,uint16_t> image_key(p_packet->header_.callsign_s, p_packet->header_.image_id);
if( images_.find(image_key) == images_.end() )
images_[image_key] = packet_set_t();
auto& packet_list = images_[image_key];
cout<<image_key.first<<" "<<image_key.second<<" "<<packet_list.size()<<endl;
packet_list.insert(p_packet);
// decode and save image
{
ssdv_t ssdv;
ssdv_dec_init(&ssdv);
uint8_t* jpeg = new uint8_t[1024*1024*3];
ssdv_dec_set_buffer( &ssdv, jpeg, 1024*1024*3 );
for(auto p_pkt : packet_list)
ssdv_dec_feed( &ssdv, p_pkt->data_.data() );
size_t jpeg_sz = 0;
ssdv_dec_get_jpeg(&ssdv, &jpeg, &jpeg_sz);
string fname = "./ssdv_" + string(packet_header.callsign_s) + "_" + std::to_string(int(packet_header.image_id)) + ".jpeg";
string fname = "./ssdv_" + string(p_packet->header_.callsign_s)
+ "_" + std::to_string(int(p_packet->header_.image_id)) + ".jpeg";
FILE* fh = fopen( fname.c_str(), "wb" );
fwrite(jpeg, 1, jpeg_sz, fh);
fclose(fh);
delete [] jpeg;
ssdv_dec_init(&ssdv);
ssdv_dec_set_buffer(&ssdv, jpeg, 1024*1024*3);
if( (*packet_list.rbegin())->header_.eoi )
images_.erase(image_key);
}
return true;

Wyświetl plik

@ -20,8 +20,14 @@
#pragma once
#include <array>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <memory>
#include <functional>
#include <utility>
#include "../ssdv/ssdv.h"
namespace habdec
@ -31,16 +37,35 @@ class SSDV_wraper_t
{
public:
SSDV_wraper_t();
~SSDV_wraper_t();
bool push(const std::vector<char>& i_chars);
private:
uint8_t* jpeg;
ssdv_t ssdv;
// incomming data buffer
std::vector<uint8_t> buff_;
int packet_begin_ = -1;
// ssdv packet with header
struct packet_t {
ssdv_packet_info_t header_;
std::array<uint8_t, 256> data_;
};
using packet_t_ptr = std::shared_ptr<packet_t>;
struct packet_t_ptr_less { // comparator
bool operator()(const packet_t_ptr& lhs, const packet_t_ptr& rhs) {
return lhs->header_.packet_id < rhs->header_.packet_id;
}
};
using packet_set_t = std::set<packet_t_ptr, packet_t_ptr_less>;
using image_map_t = std::map< // indexed by (callsign,imageID)
std::pair<std::string,uint16_t>,
packet_set_t >;
image_map_t images_;
};
}