ref: c0979e3295ef4f20da953f4364db1a084c3c4541
dir: /opus-tools-seek/
diff 1d5e00558c79cf9a4266124d393cfbc879df7475 uncommitted --- a/src/opusdec.c +++ b/src/opusdec.c @@ -493,7 +493,7 @@ opus_int64 audio_write(float *pcm, int channels, int frame_size, FILE *fout, SpeexResamplerState *resampler, float *clipmem, shapestate *shapemem, - int file, int rate, opus_int64 link_read, opus_int64 link_out, int fp) + int file, int rate, opus_int64 link_read, opus_int64 link_out, int fp, opus_int64 *seek) { opus_int64 sampout=0; opus_int64 maxout; @@ -521,12 +521,20 @@ pcm, &in_len, buf, &out_len); pcm += channels*(in_len); frame_size -= in_len; + ret = *seek<in_len?*seek:in_len; } else { output=pcm; out_len=frame_size<maxout?(unsigned)frame_size:(unsigned)maxout; frame_size=0; + ret = *seek<out_len?*seek:out_len; } + if (*seek > 0) + { + *seek -= ret; + goto next; + } + if (!file||!fp) { /*Convert to short and save to output file*/ @@ -570,6 +578,7 @@ #endif ret=fwrite(fp?(char *)output:(char *)out, (fp?sizeof(float):sizeof(short))*channels, out_len, fout); +next: sampout+=ret; maxout-=ret; } @@ -656,7 +665,7 @@ static void drain_resampler(FILE *fout, int file_output, SpeexResamplerState *resampler, int channels, int rate, opus_int64 link_read, opus_int64 link_out, float *clipmem, - shapestate *shapemem, opus_int64 *audio_size, int fp) + shapestate *shapemem, opus_int64 *audio_size, int fp, opus_int64 *seek) { float *zeros; int drain; @@ -667,7 +676,7 @@ opus_int64 outsamp; int tmp=MINI(drain, 100); outsamp=audio_write(zeros, channels, tmp, fout, resampler, clipmem, - shapemem, file_output, rate, link_read, link_out, fp); + shapemem, file_output, rate, link_read, link_out, fp, seek); link_out+=outsamp; (*audio_size)+=(fp?sizeof(float):sizeof(short))*outsamp*channels; drain-=tmp; @@ -714,6 +723,7 @@ {0, 0, 0, 0} }; opus_int64 audio_size=0; + opus_int64 seek=-1; opus_int64 last_coded_seconds=-1; float loss_percent=-1; float manual_gain=0; @@ -749,7 +759,7 @@ /*Process options*/ while (1) { - c = getopt_long(argc_utf8, argv_utf8, "hV", + c = getopt_long(argc_utf8, argv_utf8, "hVs:", long_options, &option_index); if (c==-1) break; @@ -801,6 +811,9 @@ case 'h': usage(); goto done; + case 's': + seek = atoi(optarg); + break; case 'V': version(); goto done; @@ -1020,6 +1033,11 @@ op_set_decode_callback(st, (op_decode_cb_func)decode_cb, &cb_ctx); } + if (seek != -1) + { + seek *= rate; + } + /*Main decoding loop*/ while (1) { @@ -1063,7 +1081,7 @@ { drain_resampler(fout, file_output, resampler, channels, rate, link_read, link_out, clipmem, dither?&shapemem:NULL, &audio_size, - fp); + fp, &seek); /*Neither speex_resampler_reset_mem() nor speex_resampler_skip_zeros() clear the number of fractional samples properly, so we just destroy it. It will get re-created @@ -1171,7 +1189,7 @@ } outsamp=audio_write(permuted_output?permuted_output:output, channels, nb_read, fout, resampler, clipmem, dither?&shapemem:0, file_output, - rate, link_read, link_out, fp); + rate, link_read, link_out, fp, &seek); link_out+=outsamp; audio_size+=(fp?sizeof(float):sizeof(short))*outsamp*channels; } @@ -1179,7 +1197,7 @@ if (resampler!=NULL) { drain_resampler(fout, file_output, resampler, channels, rate, - link_read, link_out, clipmem, dither?&shapemem:NULL, &audio_size, fp); + link_read, link_out, clipmem, dither?&shapemem:NULL, &audio_size, fp, &seek); speex_resampler_destroy(resampler); }