I would like to test libvpx (vp9) temporal svc. For that matter I take examples/vpx_temporal_svc_encoder.c and modify it to add a decoder. If I take for example mode 3 with 3 temporal layers and 6 frame period and try to decode only layer 0 or layers 0 and 1 I get an error: "Failed to decode frame.: Corrupt frame detected. Failed to decode tile data". What am I missing ? Here is my code (had to remove unmodified part due to post limits):
/*
* Copyright (c) 2012 The WebM project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// This is an example demonstrating how to implement a multi-layer VPx
// encoding scheme based on temporal scalability for video applications
// that benefit from a scalable bitstream.
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "./vpx_config.h"
#include "./y4minput.h"
#include "../vpx_ports/vpx_timer.h"
#include "vpx/vp8cx.h"
#include "vpx/vpx_encoder.h"
#include "vpx_ports/bitops.h"
#include "../tools_common.h"
#include "../video_writer.h"
#include "vpx/vpx_decoder.h"
#define ROI_MAP 0
#define zero(Dest) memset(&(Dest), 0, sizeof(Dest));
static const char *exec_name;
void usage_exit(void) { exit(EXIT_FAILURE); }
// Denoiser states for vp8, for temporal denoising.
enum denoiserStateVp8 {
kVp8DenoiserOff,
kVp8DenoiserOnYOnly,
kVp8DenoiserOnYUV,
kVp8DenoiserOnYUVAggressive,
kVp8DenoiserOnAdaptive
};
// Denoiser states for vp9, for temporal denoising.
enum denoiserStateVp9 {
kVp9DenoiserOff,
kVp9DenoiserOnYOnly,
// For SVC: denoise the top two spatial layers.
kVp9DenoiserOnYTwoSpatialLayers
};
static int mode_to_num_layers[13] = { 1, 2, 2, 3, 3, 3, 3, 5, 2, 3, 3, 3, 3 };
int main(int argc, char **argv) {
VpxVideoWriter *outfile[VPX_TS_MAX_LAYERS] = { NULL };
vpx_codec_ctx_t codec;
vpx_codec_enc_cfg_t cfg;
int frame_cnt = 0;
vpx_image_t raw;
vpx_codec_err_t res;
unsigned int width;
unsigned int height;
uint32_t error_resilient = 0;
int speed;
int frame_avail;
int got_data;
int flags = 0;
unsigned int i;
int pts = 0; // PTS starts at 0.
int frame_duration = 1; // 1 timebase tick per frame.
int layering_mode = 0;
int layer_flags[VPX_TS_MAX_PERIODICITY] = { 0 };
int flag_periodicity = 1;
#if ROI_MAP
vpx_roi_map_t roi;
#endif
vpx_svc_layer_id_t layer_id;
const VpxInterface *encoder = NULL;
struct VpxInputContext input_ctx;
struct RateControlMetrics rc;
int64_t cx_time = 0;
const int min_args_base = 13;
#if CONFIG_VP9_HIGHBITDEPTH
vpx_bit_depth_t bit_depth = VPX_BITS_8;
int input_bit_depth = 8;
const int min_args = min_args_base + 1;
#else
const int min_args = min_args_base;
#endif // CONFIG_VP9_HIGHBITDEPTH
double sum_bitrate = 0.0;
double sum_bitrate2 = 0.0;
double framerate = 30.0;
zero(rc.layer_target_bitrate);
memset(&layer_id, 0, sizeof(vpx_svc_layer_id_t));
memset(&input_ctx, 0, sizeof(input_ctx));
/* Setup default input stream settings */
input_ctx.framerate.numerator = 30;
input_ctx.framerate.denominator = 1;
input_ctx.only_i420 = 1;
input_ctx.bit_depth = 0;
exec_name = argv[0];
// Check usage and arguments.
if (argc < min_args) {
#if CONFIG_VP9_HIGHBITDEPTH
die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
"<rate_num> <rate_den> <speed> <frame_drop_threshold> "
"<error_resilient> <threads> <mode> "
"<Rate_0> ... <Rate_nlayers-1> <bit-depth> \n",
argv[0]);
#else
//./vpx_temporal_svc_encoder ../9.yuv svc vp9 256 256 1 25 9 0 0 1 3 500000 500000 50000
die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
"<rate_num> <rate_den> <speed> <frame_drop_threshold> "
"<error_resilient> <threads> <mode> "
"<Rate_0> ... <Rate_nlayers-1> \n",
argv[0]);
#endif // CONFIG_VP9_HIGHBITDEPTH
}
encoder = get_vpx_encoder_by_name(argv[3]);
if (!encoder) die("Unsupported codec.");
printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));
width = (unsigned int)strtoul(argv[4], NULL, 0);
height = (unsigned int)strtoul(argv[5], NULL, 0);
if (width < 16 || width % 2 || height < 16 || height % 2) {
die("Invalid resolution: %d x %d", width, height);
}
layering_mode = (int)strtol(argv[12], NULL, 0);
if (layering_mode < 0 || layering_mode > 13) {
die("Invalid layering mode (0..12) %s", argv[12]);
}
if (argc != min_args + mode_to_num_layers[layering_mode]) {
die("Invalid number of arguments");
}
input_ctx.filename = argv[1];
open_input_file(&input_ctx);
#if CONFIG_VP9_HIGHBITDEPTH
switch (strtol(argv[argc - 1], NULL, 0)) {
case 8:
bit_depth = VPX_BITS_8;
input_bit_depth = 8;
break;
case 10:
bit_depth = VPX_BITS_10;
input_bit_depth = 10;
break;
case 12:
bit_depth = VPX_BITS_12;
input_bit_depth = 12;
break;
default: die("Invalid bit depth (8, 10, 12) %s", argv[argc - 1]);
}
// Y4M reader has its own allocation.
if (input_ctx.file_type != FILE_TYPE_Y4M) {
if (!vpx_img_alloc(
&raw,
bit_depth == VPX_BITS_8 ? VPX_IMG_FMT_I420 : VPX_IMG_FMT_I42016,
width, height, 32)) {
die("Failed to allocate image", width, height);
}
}
#else
// Y4M reader has its own allocation.
if (input_ctx.file_type != FILE_TYPE_Y4M) {
if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, width, height, 32)) {
die("Failed to allocate image", width, height);
}
}
#endif // CONFIG_VP9_HIGHBITDEPTH
// Populate encoder configuration.
res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
if (res) {
printf("Failed to get config: %s\n", vpx_codec_err_to_string(res));
return EXIT_FAILURE;
}
// Update the default configuration with our settings.
cfg.g_w = width;
cfg.g_h = height;
#if CONFIG_VP9_HIGHBITDEPTH
if (bit_depth != VPX_BITS_8) {
cfg.g_bit_depth = bit_depth;
cfg.g_input_bit_depth = input_bit_depth;
cfg.g_profile = 2;
}
#endif // CONFIG_VP9_HIGHBITDEPTH
// Timebase format e.g. 30fps: numerator=1, demoninator = 30.
cfg.g_timebase.num = (int)strtol(argv[6], NULL, 0);
cfg.g_timebase.den = (int)strtol(argv[7], NULL, 0);
speed = (int)strtol(argv[8], NULL, 0);
if (speed < 0) {
die("Invalid speed setting: must be positive");
}
if (strncmp(encoder->name, "vp9", 3) == 0 && speed > 9) {
warn("Mapping speed %d to speed 9.\n", speed);
}
for (i = min_args_base;
(int)i < min_args_base + mode_to_num_layers[layering_mode]; ++i) {
rc.layer_target_bitrate[i - 13] = (int)strtol(argv[i], NULL, 0);
if (strncmp(encoder->name, "vp8", 3) == 0)
cfg.ts_target_bitrate[i - 13] = rc.layer_target_bitrate[i - 13];
else if (strncmp(encoder->name, "vp9", 3) == 0)
cfg.layer_target_bitrate[i - 13] = rc.layer_target_bitrate[i - 13];
}
// Real time parameters.
cfg.rc_dropframe_thresh = (unsigned int)strtoul(argv[9], NULL, 0);
cfg.rc_end_usage = VPX_CBR;
cfg.rc_min_quantizer = 2;
cfg.rc_max_quantizer = 56;
if (strncmp(encoder->name, "vp9", 3) == 0) cfg.rc_max_quantizer = 52;
cfg.rc_undershoot_pct = 50;
cfg.rc_overshoot_pct = 50;
cfg.rc_buf_initial_sz = 600;
cfg.rc_buf_optimal_sz = 600;
cfg.rc_buf_sz = 1000;
// Disable dynamic resizing by default.
cfg.rc_resize_allowed = 0;
// Use 1 thread as default.
cfg.g_threads = (unsigned int)strtoul(argv[11], NULL, 0);
error_resilient = (uint32_t)strtoul(argv[10], NULL, 0);
if (error_resilient != 0 && error_resilient != 1) {
die("Invalid value for error resilient (0, 1): %d.", error_resilient);
}
// Enable error resilient mode.
cfg.g_error_resilient = error_resilient;
cfg.g_lag_in_frames = 0;
cfg.kf_mode = VPX_KF_AUTO;
// Disable automatic keyframe placement.
cfg.kf_min_dist = cfg.kf_max_dist = 3000;
cfg.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;
set_temporal_layer_pattern(layering_mode, &cfg, layer_flags,
&flag_periodicity);
set_rate_control_metrics(&rc, &cfg);
if (input_ctx.file_type == FILE_TYPE_Y4M) {
if (input_ctx.width != cfg.g_w || input_ctx.height != cfg.g_h) {
die("Incorrect width or height: %d x %d", cfg.g_w, cfg.g_h);
}
if (input_ctx.framerate.numerator != cfg.g_timebase.den ||
input_ctx.framerate.denominator != cfg.g_timebase.num) {
die("Incorrect framerate: numerator %d denominator %d",
cfg.g_timebase.num, cfg.g_timebase.den);
}
}
framerate = cfg.g_timebase.den / cfg.g_timebase.num;
// Open an output file for each stream.
for (i = 0; i < cfg.ts_number_layers; ++i) {
char file_name[PATH_MAX];
VpxVideoInfo info;
info.codec_fourcc = encoder->fourcc;
info.frame_width = cfg.g_w;
info.frame_height = cfg.g_h;
info.time_base.numerator = cfg.g_timebase.num;
info.time_base.denominator = cfg.g_timebase.den;
snprintf(file_name, sizeof(file_name), "%s_%d.ivf", argv[2], i);
outfile[i] = vpx_video_writer_open(file_name, kContainerIVF, &info);
if (!outfile[i]) die("Failed to open %s for writing", file_name);
assert(outfile[i] != NULL);
}
// No spatial layers in this encoder.
cfg.ss_number_layers = 1;
// Initialize codec.
#if CONFIG_VP9_HIGHBITDEPTH
if (vpx_codec_enc_init(
&codec, encoder->codec_interface(), &cfg,
bit_depth == VPX_BITS_8 ? 0 : VPX_CODEC_USE_HIGHBITDEPTH))
#else
if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0))
#endif // CONFIG_VP9_HIGHBITDEPTH
die("Failed to initialize encoder");
if (strncmp(encoder->name, "vp8", 3) == 0) {
vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed);
vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kVp8DenoiserOff);
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
vpx_codec_control(&codec, VP8E_SET_GF_CBR_BOOST_PCT, 0);
#if ROI_MAP
set_roi_map(encoder->name, &cfg, &roi);
if (vpx_codec_control(&codec, VP8E_SET_ROI_MAP, &roi))
die_codec(&codec, "Failed to set ROI map");
#endif
} else if (strncmp(encoder->name, "vp9", 3) == 0) {
vpx_svc_extra_cfg_t svc_params;
memset(&svc_params, 0, sizeof(svc_params));
vpx_codec_control(&codec, VP9E_SET_POSTENCODE_DROP, 0);
vpx_codec_control(&codec, VP9E_SET_DISABLE_OVERSHOOT_MAXQ_CBR, 0);
vpx_codec_control(&codec, VP8E_SET_CPUUSED, speed);
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3);
vpx_codec_control(&codec, VP9E_SET_GF_CBR_BOOST_PCT, 0);
vpx_codec_control(&codec, VP9E_SET_FRAME_PARALLEL_DECODING, 0);
vpx_codec_control(&codec, VP9E_SET_FRAME_PERIODIC_BOOST, 0);
vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, kVp9DenoiserOff);
vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 1);
vpx_codec_control(&codec, VP9E_SET_TUNE_CONTENT, 0);
vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, get_msb(cfg.g_threads));
vpx_codec_control(&codec, VP9E_SET_DISABLE_LOOPFILTER, 0);
#if ROI_MAP
set_roi_map(encoder->name, &cfg, &roi);
if (vpx_codec_control(&codec, VP9E_SET_ROI_MAP, &roi))
die_codec(&codec, "Failed to set ROI map");
vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 0);
#endif
if (cfg.g_threads > 1)
vpx_codec_control(&codec, VP9E_SET_ROW_MT, 1);
else
vpx_codec_control(&codec, VP9E_SET_ROW_MT, 0);
if (vpx_codec_control(&codec, VP9E_SET_SVC, layering_mode > 0 ? 1 : 0))
die_codec(&codec, "Failed to set SVC");
for (i = 0; i < cfg.ts_number_layers; ++i) {
svc_params.max_quantizers[i] = cfg.rc_max_quantizer;
svc_params.min_quantizers[i] = cfg.rc_min_quantizer;
}
svc_params.scaling_factor_num[0] = cfg.g_h;
svc_params.scaling_factor_den[0] = cfg.g_h;
vpx_codec_control(&codec, VP9E_SET_SVC_PARAMETERS, &svc_params);
}
if (strncmp(encoder->name, "vp8", 3) == 0) {
vpx_codec_control(&codec, VP8E_SET_SCREEN_CONTENT_MODE, 0);
}
vpx_codec_control(&codec, VP8E_SET_TOKEN_PARTITIONS, 1);
// This controls the maximum target size of the key frame.
// For generating smaller key frames, use a smaller max_intra_size_pct
// value, like 100 or 200.
{
const int max_intra_size_pct = 1000;
vpx_codec_control(&codec, VP8E_SET_MAX_INTRA_BITRATE_PCT,
max_intra_size_pct);
}
const VpxInterface *decoder = NULL;
decoder = get_vpx_decoder_by_name( "vp9" );
if (!decoder) die("Unsupported codec.");
vpx_codec_ctx_t codec_dec;
vpx_codec_dec_cfg_t cfg_dec;
cfg_dec.w = width;
cfg_dec.h = height;
cfg_dec.threads = 1;
if (vpx_codec_dec_init( &codec_dec, decoder->codec_interface(), &cfg_dec, 0))
die_codec( &codec_dec, "Failed to initialize decoder.");
if(!codec.iface)
die_codec( &codec_dec, "vvv no iface" );
vpx_image_t *img_dec;
frame_avail = 1;
while (frame_avail || got_data) {
struct vpx_usec_timer timer;
vpx_codec_iter_t iter = NULL;
const vpx_codec_cx_pkt_t *pkt;
// Update the temporal layer_id. No spatial layers in this test.
layer_id.spatial_layer_id = 0;
layer_id.temporal_layer_id =
cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity];
layer_id.temporal_layer_id_per_spatial[0] = layer_id.temporal_layer_id;
if (strncmp(encoder->name, "vp9", 3) == 0) {
vpx_codec_control(&codec, VP9E_SET_SVC_LAYER_ID, &layer_id);
} else if (strncmp(encoder->name, "vp8", 3) == 0) {
vpx_codec_control(&codec, VP8E_SET_TEMPORAL_LAYER_ID,
layer_id.temporal_layer_id);
}
flags = layer_flags[frame_cnt % flag_periodicity];
if (layering_mode == 0) flags = 0;
frame_avail = read_frame(&input_ctx, &raw);
if (frame_avail) ++rc.layer_input_frames[layer_id.temporal_layer_id];
vpx_usec_timer_start(&timer);
if (vpx_codec_encode(&codec, frame_avail ? &raw : NULL, pts, 1, flags,
VPX_DL_REALTIME)) {
die_codec(&codec, "Failed to encode frame");
}
vpx_usec_timer_mark(&timer);
cx_time += vpx_usec_timer_elapsed(&timer);
// Reset KF flag.
if (layering_mode != 7) {
layer_flags[0] &= ~VPX_EFLAG_FORCE_KF;
}
got_data = 0;
while ((pkt = vpx_codec_get_cx_data(&codec, &iter))) {
got_data = 1;
switch (pkt->kind) {
case VPX_CODEC_CX_FRAME_PKT:
for (i = cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity];
i < cfg.ts_number_layers; ++i) {
vpx_video_writer_write_frame(outfile[i], pkt->data.frame.buf,
pkt->data.frame.sz, pts);
++rc.layer_tot_enc_frames[i];
rc.layer_encoding_bitrate[i] += 8.0 * pkt->data.frame.sz;
// Keep count of rate control stats per layer (for non-key frames).
if (i == cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity] &&
!(pkt->data.frame.flags & VPX_FRAME_IS_KEY)) {
rc.layer_avg_frame_size[i] += 8.0 * pkt->data.frame.sz;
rc.layer_avg_rate_mismatch[i] +=
fabs(8.0 * pkt->data.frame.sz - rc.layer_pfb[i]) /
rc.layer_pfb[i];
++rc.layer_enc_frames[i];
}
}
// Update for short-time encoding bitrate states, for moving window
// of size rc->window, shifted by rc->window / 2.
// Ignore first window segment, due to key frame.
if (rc.window_size == 0) rc.window_size = 15;
if (frame_cnt > rc.window_size) {
sum_bitrate += 0.001 * 8.0 * pkt->data.frame.sz * framerate;
if (frame_cnt % rc.window_size == 0) {
rc.window_count += 1;
rc.avg_st_encoding_bitrate += sum_bitrate / rc.window_size;
rc.variance_st_encoding_bitrate +=
(sum_bitrate / rc.window_size) *
(sum_bitrate / rc.window_size);
sum_bitrate = 0.0;
}
}
// Second shifted window.
if (frame_cnt > rc.window_size + rc.window_size / 2) {
sum_bitrate2 += 0.001 * 8.0 * pkt->data.frame.sz * framerate;
if (frame_cnt > 2 * rc.window_size &&
frame_cnt % rc.window_size == 0) {
rc.window_count += 1;
rc.avg_st_encoding_bitrate += sum_bitrate2 / rc.window_size;
rc.variance_st_encoding_bitrate +=
(sum_bitrate2 / rc.window_size) *
(sum_bitrate2 / rc.window_size);
sum_bitrate2 = 0.0;
}
}
//decode
if( layer_id.temporal_layer_id == 0 ){
vpx_codec_control(&codec_dec, VP9E_SET_SVC_LAYER_ID, &layer_id);
vpx_codec_err_t res = vpx_codec_decode(&codec_dec, pkt->data.frame.buf, pkt->data.frame.sz, NULL, 0);
if( res )
die_codec(&codec_dec, "Failed to decode frame.");
vpx_codec_iter_t iter = NULL;
img_dec = vpx_codec_get_frame(&codec_dec, &iter);
if( img_dec == NULL )
die_codec(&codec_dec, "No frames were decoded.");
if( vpx_codec_get_frame(&codec_dec, &iter) != NULL )
die_codec(&codec_dec, "More than on frame decoded.");
printf( "decoded frame\n" );
}
break;
default: break;
}
}
++frame_cnt;
pts += frame_duration;
}
close_input_file(&input_ctx);
printout_rate_control_summary(&rc, &cfg, frame_cnt);
printf("\n");
printf("Frame cnt and encoding time/FPS stats for encoding: %d %f %f \n",
frame_cnt, 1000 * (float)cx_time / (double)(frame_cnt * 1000000),
1000000 * (double)frame_cnt / (double)cx_time);
if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec");
// Try to rewrite the output file headers with the actual frame count.
for (i = 0; i < cfg.ts_number_layers; ++i) vpx_video_writer_close(outfile[i]);
if (input_ctx.file_type != FILE_TYPE_Y4M) {
vpx_img_free(&raw);
}
#if ROI_MAP
free(roi.roi_map);
#endif
return EXIT_SUCCESS;
}
I want to repeatedly request one specific url by maximum performance. I copied below source from github, but I think it isn't optimized for my case, so I have to tune it.
Which Option is best in my case?
block vs non-block
sync vs async
I think non-multiplexing is right, so I've to change select() function to the other one. Is this right?
char response[RESPONSE_SIZE + 1];
char *p = response, *q;
char *end = response + RESPONSE_SIZE;
char *body = 0;
enum {
length, chunked, connection
};
int encoding = 0;
int remaining = 0;
while (1) {
fd_set reads;
FD_ZERO(&reads);
FD_SET(server, &reads);
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 200;
if (FD_ISSET(server, &reads)) {
int bytes_received = SSL_read(ssl, p, end - p);
p += bytes_received;
*p = 0;
if (!body && (body = strstr(response, "\r\n\r\n"))) {
*body = 0;
body += 4;
printf("Received Headers:\n%s\n", response);
q = strstr(response, "\nContent-Length: ");
if (q) {
encoding = length;
q = strchr(q, ' ');
q += 1;
remaining = strtol(q, 0, 10);
} else {
q = strstr(response, "\nTransfer-Encoding: chunked");
if (q) {
encoding = chunked;
remaining = 0;
} else {
encoding = connection;
}
}
printf("\nReceived Body:\n");
}
if (body) {
if (encoding == length) {
if (p - body >= remaining) {
printf("%.*s", remaining, body);
break;
}
} else if (encoding == chunked) {
do {
if (remaining == 0) {
if ((q = strstr(body, "\r\n"))) {
remaining = strtol(body, 0, 16);
if (!remaining) goto finish;
body = q + 2;
} else {
break;
}
}
if (p - body >= remaining) {
printf("%.*s", remaining, body);
body += remaining + 2;
remaining = 0;
}
} while (!remaining);
}
} //if (body)
} //if FDSET
} //end while(1)
finish:
buffer[0] = '\0';
printf("\nClosing socket...\n");
I wrote my implementation of vector ( dynamicly growing array) for integer type. And I was faced with a problem when using memmove and memcpy functions for data reallocation goals. Memmmove and memcpy functions work as not expected. So i replaced it with for and now it works properly. But what is the why memove works this way ?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct vector {
int v_size;
int v_length;
int* v_data;
} vector;
typedef vector *vect;
vect
new_vector(int size) {
vect tmp = (vector*)malloc(sizeof(vector));
tmp->v_size = size;
tmp->v_length = 0;
tmp->v_data = (int*)malloc(sizeof(int) * size);
return tmp;
}
void
add_velem(vect tmp, int elem) {
if(tmp->v_length != tmp->v_size) {
tmp->v_data[tmp->v_length] = elem;
tmp->v_length += 1;
} else {
tmp->v_size = tmp->v_size * 2;
tmp->v_length += 1;
int *new_vector = (int*)malloc(sizeof(int) * tmp->v_size);
memmove(new_vector, tmp->v_data, tmp->v_length); // GOT INPUT LIKE THIS:
// 500, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
// ALOT OF ZERO
/*
for(int i = 0; i < tmp->v_length; i++) {
new_vector[i] = tmp->v_data[i];
}*/ // BUT GOT RIGHT INPUT WHEN USING FOR. WHAT IS THE REASON?
free(tmp->v_data);
tmp->v_data = new_vector;
tmp->v_data[tmp->v_length - 1] = elem;
}
return;
}
int
get_vlength(vect tmp) {
return tmp->v_length;
}
int
get_vsize(vect tmp) {
return tmp->v_size;
}
int
get_velem(vect tmp, int elem) {
if(tmp->v_data == NULL) {
fprintf(stderr, "Index out of range!\n");
}else if(elem >= tmp->v_length) {
fprintf(stderr, "Index is out of range!\n");
return -1;
}
return tmp->v_data[elem];
}
void
delete_vector(vect tmp) {
free(tmp->v_data);
tmp->v_data = NULL;
free(tmp);
tmp = NULL;
}
int
main(void) {
vect example = new_vector(10);
printf("lenth of vector is %d\n", get_vlength(example));
add_velem(example, 500);
printf("element %d is pushed into vector\n", 500);
printf("size of vector is %d and\nlength of vector is %d\n", get_vsize(example), get_vlength(example));
int velem = get_velem(example, 0);
printf("elem 0 of vector is %d\n", velem);
for(int i = 1; i < 30; i++) {
add_velem(example, i);
}
printf("length of vector is %d now\n", get_vlength(example));
for(int i = 0; i < get_vlength(example); i++) {
printf("%d, ", get_velem(example, i));
}
delete_vector(example);
return 0;
}
I posted this problem a couple of hours ago, but unfortunately, the details was not clear. i've added the code and some explanation.
i have a string like this to send through socket: "000f45546874684498765" as you see the first 3 numbers are zero, when the C compiler comes to this 000 it thinks these zeros are the finishing of the string. any suggestion?
proc_socketgps(s32 TaskId)
while (1)
{
Ql_Sleep(socket_timer);
if (is_socket_success == TRUE)
{
APP_DEBUG("start socket connect\r\n");
APP_DEBUG("m_tcp_state :%d\r\n", m_tcp_state);
APP_DEBUG("STATE_SOC_SEND :%d\r\n", STATE_SOC_SEND);
APP_DEBUG("m_socketid :%d\r\n", m_socketid);
proc_handle("\x00\x11\x22", sizeof("\x00\x11\x22"));
}
static void proc_handle(unsigned char *pData, s32 len)
char *p = NULL;
s32 iret;
u8 srvport[10];
//command: Set_APN_Param=<APN>,<username>,<password>
p = Ql_strstr(pData, "Set_APN_Param=");
if (p)
{
Ql_memset(m_apn, 0, 10);
if (Analyse_Command(pData, 1, '>', m_apn))
{
APP_DEBUG("<--APN Parameter Error.-->\r\n");
return;
}
Ql_memset(m_userid, 0, 10);
if (Analyse_Command(pData, 2, '>', m_userid))
{
APP_DEBUG("<--APN Username Parameter Error.-->\r\n");
return;
}
Ql_memset(m_passwd, 0, 10);
if (Analyse_Command(pData, 3, '>', m_passwd))
{
APP_DEBUG("<--APN Password Parameter Error.-->\r\n");
return;
}
APP_DEBUG("<--Set APN Parameter Successfully<%s>,<%s>,<%s>.-->\r\n", m_apn, m_userid, m_passwd);
return;
}
//command: Set_Srv_Param=<srv ip>,<srv port>
p = Ql_strstr(pData, "Set_Srv_Param=");
if (p)
{
Ql_memset(m_SrvADDR, 0, SRVADDR_BUFFER_LEN);
if (Analyse_Command(pData, 1, '>', m_SrvADDR))
{
APP_DEBUG("<--Server Address Parameter Error.-->\r\n");
return;
}
Ql_memset(srvport, 0, 10);
if (Analyse_Command(pData, 2, '>', srvport))
{
APP_DEBUG("<--Server Port Parameter Error.-->\r\n");
return;
}
m_SrvPort = Ql_atoi(srvport);
APP_DEBUG("<--Set TCP Server Parameter Successfully<%s>,<%d>.-->\r\n", m_SrvADDR, m_SrvPort);
m_tcp_state = STATE_NW_GET_SIMSTATE;
APP_DEBUG("<--Restart the TCP connection process.-->\r\n");
return;
}
//if not command,send it to server
m_pCurrentPos = m_send_buf;
Ql_strcpy(m_pCurrentPos + m_remain_len, pData);
m_remain_len = Ql_strlen(m_pCurrentPos);
if (!Ql_strlen(m_send_buf)) //no data need to send
break;
m_tcp_state = STATE_SOC_SENDING;
do
{
ret = Ql_SOC_Send(m_socketid, m_pCurrentPos, m_remain_len);
APP_DEBUG("Message Data :%s", m_pCurrentPos);
APP_DEBUG("<--Send data,socketid=%d,number of bytes sent=%d-->\r\n", m_socketid, ret);
if (ret == m_remain_len) //send compelete
{
m_remain_len = 0;
m_pCurrentPos = NULL;
m_nSentLen += ret;
m_tcp_state = STATE_SOC_ACK;
break;
}
else if ((ret <= 0) && (ret == SOC_WOULDBLOCK))
{
//waiting CallBack_socket_write, then send data;
break;
}
else if (ret <= 0)
{
APP_DEBUG("<--Send data failure,ret=%d.-->\r\n", ret);
APP_DEBUG("<-- Close socket.-->\r\n");
Ql_SOC_Close(m_socketid); //error , Ql_SOC_Close
m_socketid = -1;
m_remain_len = 0;
m_pCurrentPos = NULL;
if (ret == SOC_BEARER_FAIL)
{
m_tcp_state = STATE_GPRS_DEACTIVATE;
}
else
{
m_tcp_state = STATE_GPRS_GET_DNSADDRESS;
}
break;
}
else if (ret < m_remain_len) //continue send, do not send all data
{
m_remain_len -= ret;
m_pCurrentPos += ret;
m_nSentLen += ret;
}
} while (1);
break;
the code has been added to the question. firs socket gets open and gets connected to the server. this function >> proc_handle("\x00\x11\x22", sizeof("\x00\x11\x22")); sends hexadecimal string, however i think c consider this part "\x00" as end of the string ! and the data won't be sent ! I already tested that if I remove "\x00" from the row above it works like a charm !
Could someone help me with this one. I'm making BFS algorithm in C programming language, with help of dynamic lists.
This is my code.
// ConsoleApplication3.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <malloc.h>
#define n 6
typedef struct field
{
int x;
int y;
int dist;
struct field *next;
}Field;
// Get row and column number of 4 neighbours
int rows[] = { -1, 0, 0, 1 };
int cols[] = { 0, -1, 1, 0 };
Field *addToEnd(Field *lst, Field field)
{
Field *newField = (Field*)malloc(sizeof Field);
newField = &field;
newField->next = NULL;
if (!lst)
return newField;
else
{
Field *current;
for (current = lst; current->next; current = current->next);
current->next = newField;
return lst;
}
}
// Check if field is/isn't out of range
bool isValid(int row, int col)
{
return (row >= 0) && (row < n) && (col >= 0) && (col < n);
}
int BFS(int mat[][n], Field source, Field destination)
{
bool visited[n][n];
memset(visited, false, sizeof visited);
// Mark the source field as visited
visited[source.x][source.y] = true;
// Create dynamic list
Field *lst = NULL;
source.dist = 0;
// Adding the source field to the list
lst = addToEnd(lst, source);
while (lst)
{
// Getting first element in the list
Field current = *lst;
// If destination is reached then end function
if (current.x == destination.x && current.y == destination.y)
return current.dist;
// Delete first element of the list
Field *toDelete;
toDelete = lst;
lst = lst->next;
free(toDelete);
for (int i = 0; i < 4; i++)
{
int row = current.x + rows[i];
int col = current.y + cols[i];
// If adjacent field is valid, has path and isn't visited add it to the list
if (isValid(row, col) && mat[row][col] == 0 && !visited[row][col])
{
visited[row][col] = true;
Field adjField = { row, col, current.dist + 1 };
lst = addToEnd(lst, adjField);
}
}
}
// Return -1 if destination can't be reached
return -1;
}
int main()
{
int mat[n][n] =
{
{ 0, 0, 0, 0, 0, 0 },
{ 0, 1, 1, 1, 1, 0 },
{ 0, 1, 0, 0, 0, 0 },
{ 0, 0, 0, 1, 1, 0 },
{ 0, 1, 0, 0, 0, 0 },
{ 0, 0, 0, 1, 1, 0 }
};
Field start = { 1, 0 }, end = { 5, 5 };
int number = BFS(mat, start, end);
if (number != -1)
printf("%d\n", number);
else
printf("Destination can't be reached\n");
return 0;
}
Everything except part of code which need to delete first element of list is working. The problem is with free function.
https://i.stack.imgur.com/QpK1j.png
https://i.stack.imgur.com/HXp8d.png
Does anyone have an idea what could be possible wrong with this and how can I fix it?