* commit 'b5849f77095439e994b11c25e6063d443b36c228': (21 commits) ac3enc: merge AC3MDCTContext with AC3EncodeContext. ac3enc: prefer passing AC3EncodeContext rather than AVCodecContext ac3enc: fix memleak mpeg1video: add CODEC_CAP_SLICE_THREADS. lavf: fix segfault in av_open_input_stream() mpegtsenc: set Random Access indicator on keyframe start packets lavf: Cleanup try_decode_frame() logic. Replace some gotos that lead to single return statements by direct return. build: move tests/seek_test.c to libavformat and reuse generic build rules mxfenc: include needed header for ff_iso8601_to_unix_time() prototype Add a check for strptime(). lavf: factor out conversion of ISO8601 string to unix time wav: parse 'bext' metadata wav: keep parsing until EOF if the input is seekable and we know the size of the data tag wav: Refactor the tag checking into a switch statement wav: make sure neither data_size nor sample_count is negative. wav: refactor the 'fmt ' tag search and parsing. wav: add an option for writing BEXT chunk ffmpeg: get rid of a pointless limit on number of streams. ffmpeg: remove an unused define. ... Merged-by: Michael Niedermayer <michaelni@gmx.at>tags/n0.9
@@ -32,7 +32,6 @@ tests/audiogen | |||
tests/base64 | |||
tests/data | |||
tests/rotozoom | |||
tests/seek_test | |||
tests/tiny_psnr | |||
tests/videogen | |||
tests/vsynth1 | |||
@@ -5,6 +5,7 @@ version next: | |||
- openal input device added | |||
- boxblur filter added | |||
- BWF muxer | |||
version 0.8: | |||
@@ -1110,6 +1110,7 @@ HAVE_LIST=" | |||
poll_h | |||
setrlimit | |||
strerror_r | |||
strptime | |||
strtok_r | |||
struct_addrinfo | |||
struct_ipv6_mreq | |||
@@ -2812,6 +2813,7 @@ check_func mmap | |||
check_func ${malloc_prefix}posix_memalign && enable posix_memalign | |||
check_func setrlimit | |||
check_func strerror_r | |||
check_func strptime | |||
check_func strtok_r | |||
check_func_headers conio.h kbhit | |||
check_func_headers io.h setmode | |||
@@ -66,6 +66,7 @@ library: | |||
@tab Used in Z and Z95 games. | |||
@item Brute Force & Ignorance @tab @tab X | |||
@tab Used in the game Flash Traffic: City of Angels. | |||
@item BWF @tab X @tab X | |||
@item Interplay C93 @tab @tab X | |||
@tab Used in the game Cyberia from Interplay. | |||
@item Delphine Software International CIN @tab @tab X | |||
@@ -115,7 +115,6 @@ static const OptionDef options[]; | |||
#define MAX_FILES 100 | |||
#define MAX_STREAMS 1024 /* arbitrary sanity check value */ | |||
static const char *last_asked_format = NULL; | |||
static double *ts_scale; | |||
static int nb_ts_scale; | |||
@@ -1575,7 +1574,7 @@ static int output_packet(InputStream *ist, int ist_index, | |||
ret = avcodec_decode_audio3(ist->st->codec, samples, &decoded_data_size, | |||
&avpkt); | |||
if (ret < 0) | |||
goto fail_decode; | |||
return ret; | |||
avpkt.data += ret; | |||
avpkt.size -= ret; | |||
data_size = ret; | |||
@@ -1602,7 +1601,7 @@ static int output_packet(InputStream *ist, int ist_index, | |||
&picture, &got_output, &avpkt); | |||
quality = same_quality ? picture.quality : 0; | |||
if (ret < 0) | |||
goto fail_decode; | |||
return ret; | |||
if (!got_output) { | |||
/* no picture yet */ | |||
goto discard_packet; | |||
@@ -1622,7 +1621,7 @@ static int output_packet(InputStream *ist, int ist_index, | |||
ret = avcodec_decode_subtitle2(ist->st->codec, | |||
&subtitle, &got_output, &avpkt); | |||
if (ret < 0) | |||
goto fail_decode; | |||
return ret; | |||
if (!got_output) { | |||
goto discard_packet; | |||
} | |||
@@ -1630,7 +1629,7 @@ static int output_packet(InputStream *ist, int ist_index, | |||
avpkt.size = 0; | |||
break; | |||
default: | |||
goto fail_decode; | |||
return -1; | |||
} | |||
} else { | |||
switch(ist->st->codec->codec_type) { | |||
@@ -1910,8 +1909,6 @@ static int output_packet(InputStream *ist, int ist_index, | |||
} | |||
return 0; | |||
fail_decode: | |||
return -1; | |||
} | |||
static void print_sdp(AVFormatContext **avc, int n) | |||
@@ -3197,9 +3194,6 @@ static int opt_input_ts_scale(const char *opt, const char *arg) | |||
p++; | |||
scale= strtod(p, &p); | |||
if(stream >= MAX_STREAMS) | |||
ffmpeg_exit(1); | |||
ts_scale = grow_array(ts_scale, sizeof(*ts_scale), &nb_ts_scale, stream + 1); | |||
ts_scale[stream] = scale; | |||
return 0; | |||
@@ -3851,7 +3845,7 @@ static int opt_streamid(const char *opt, const char *arg) | |||
ffmpeg_exit(1); | |||
} | |||
*p++ = '\0'; | |||
idx = parse_number_or_die(opt, idx_str, OPT_INT, 0, MAX_STREAMS-1); | |||
idx = parse_number_or_die(opt, idx_str, OPT_INT, 0, INT_MAX); | |||
streamid_map = grow_array(streamid_map, sizeof(*streamid_map), &nb_streamid_map, idx+1); | |||
streamid_map[idx] = parse_number_or_die(opt, p, OPT_INT, 0, INT_MAX); | |||
return 0; | |||
@@ -1690,10 +1690,10 @@ static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c | |||
if ((ret = avfilter_graph_create_filter(&filt_src, &input_filter, "src", | |||
NULL, is, graph)) < 0) | |||
goto the_end; | |||
return ret; | |||
if ((ret = avfilter_graph_create_filter(&filt_out, avfilter_get_by_name("buffersink"), "out", | |||
NULL, pix_fmts, graph)) < 0) | |||
goto the_end; | |||
return ret; | |||
if(vfilters) { | |||
AVFilterInOut *outputs = avfilter_inout_alloc(); | |||
@@ -1710,18 +1710,18 @@ static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c | |||
inputs->next = NULL; | |||
if ((ret = avfilter_graph_parse(graph, vfilters, &inputs, &outputs, NULL)) < 0) | |||
goto the_end; | |||
return ret; | |||
av_freep(&vfilters); | |||
} else { | |||
if ((ret = avfilter_link(filt_src, 0, filt_out, 0)) < 0) | |||
goto the_end; | |||
return ret; | |||
} | |||
if ((ret = avfilter_graph_config(graph, NULL)) < 0) | |||
goto the_end; | |||
return ret; | |||
is->out_video_filter = filt_out; | |||
the_end: | |||
return ret; | |||
} | |||
@@ -1829,7 +1829,7 @@ static int subtitle_thread(void *arg) | |||
SDL_UnlockMutex(is->subpq_mutex); | |||
if (is->subtitleq.abort_request) | |||
goto the_end; | |||
return 0; | |||
sp = &is->subpq[is->subpq_windex]; | |||
@@ -1866,7 +1866,6 @@ static int subtitle_thread(void *arg) | |||
} | |||
av_free_packet(pkt); | |||
} | |||
the_end: | |||
return 0; | |||
} | |||
@@ -3508,7 +3508,7 @@ static int add_av_stream(FFStream *feed, AVStream *st) | |||
case AVMEDIA_TYPE_AUDIO: | |||
if (av1->channels == av->channels && | |||
av1->sample_rate == av->sample_rate) | |||
goto found; | |||
return i; | |||
break; | |||
case AVMEDIA_TYPE_VIDEO: | |||
if (av1->width == av->width && | |||
@@ -3516,7 +3516,7 @@ static int add_av_stream(FFStream *feed, AVStream *st) | |||
av1->time_base.den == av->time_base.den && | |||
av1->time_base.num == av->time_base.num && | |||
av1->gop_size == av->gop_size) | |||
goto found; | |||
return i; | |||
break; | |||
default: | |||
abort(); | |||
@@ -3528,8 +3528,6 @@ static int add_av_stream(FFStream *feed, AVStream *st) | |||
if (!fst) | |||
return -1; | |||
return feed->nb_streams - 1; | |||
found: | |||
return i; | |||
} | |||
static void remove_stream(FFStream *stream) | |||
@@ -1535,10 +1535,10 @@ void ff_ac3_output_frame(AC3EncodeContext *s, unsigned char *frame) | |||
} | |||
static void dprint_options(AVCodecContext *avctx) | |||
static void dprint_options(AC3EncodeContext *s) | |||
{ | |||
#ifdef DEBUG | |||
AC3EncodeContext *s = avctx->priv_data; | |||
AVCodecContext *avctx = s->avctx; | |||
AC3EncOptions *opt = &s->options; | |||
char strbuf[32]; | |||
@@ -1689,9 +1689,9 @@ static void validate_mix_level(void *log_ctx, const char *opt_name, | |||
* Validate metadata options as set by AVOption system. | |||
* These values can optionally be changed per-frame. | |||
*/ | |||
int ff_ac3_validate_metadata(AVCodecContext *avctx) | |||
int ff_ac3_validate_metadata(AC3EncodeContext *s) | |||
{ | |||
AC3EncodeContext *s = avctx->priv_data; | |||
AVCodecContext *avctx = s->avctx; | |||
AC3EncOptions *opt = &s->options; | |||
/* validate mixing levels */ | |||
@@ -1820,6 +1820,8 @@ av_cold int ff_ac3_encode_close(AVCodecContext *avctx) | |||
av_freep(&s->band_psd_buffer); | |||
av_freep(&s->mask_buffer); | |||
av_freep(&s->qmant_buffer); | |||
av_freep(&s->cpl_coord_exp_buffer); | |||
av_freep(&s->cpl_coord_mant_buffer); | |||
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { | |||
AC3Block *block = &s->blocks[blk]; | |||
av_freep(&block->mdct_coef); | |||
@@ -1830,10 +1832,11 @@ av_cold int ff_ac3_encode_close(AVCodecContext *avctx) | |||
av_freep(&block->band_psd); | |||
av_freep(&block->mask); | |||
av_freep(&block->qmant); | |||
av_freep(&block->cpl_coord_exp); | |||
av_freep(&block->cpl_coord_mant); | |||
} | |||
s->mdct_end(s->mdct); | |||
av_freep(&s->mdct); | |||
s->mdct_end(s); | |||
av_freep(&avctx->coded_frame); | |||
return 0; | |||
@@ -1888,8 +1891,9 @@ static av_cold int set_channel_info(AC3EncodeContext *s, int channels, | |||
} | |||
static av_cold int validate_options(AVCodecContext *avctx, AC3EncodeContext *s) | |||
static av_cold int validate_options(AC3EncodeContext *s) | |||
{ | |||
AVCodecContext *avctx = s->avctx; | |||
int i, ret, max_sr; | |||
/* validate channel layout */ | |||
@@ -1994,7 +1998,7 @@ static av_cold int validate_options(AVCodecContext *avctx, AC3EncodeContext *s) | |||
} | |||
if (!s->eac3) { | |||
ret = ff_ac3_validate_metadata(avctx); | |||
ret = ff_ac3_validate_metadata(s); | |||
if (ret) | |||
return ret; | |||
} | |||
@@ -2081,10 +2085,10 @@ static av_cold void set_bandwidth(AC3EncodeContext *s) | |||
} | |||
static av_cold int allocate_buffers(AVCodecContext *avctx) | |||
static av_cold int allocate_buffers(AC3EncodeContext *s) | |||
{ | |||
AVCodecContext *avctx = s->avctx; | |||
int blk, ch; | |||
AC3EncodeContext *s = avctx->priv_data; | |||
int channels = s->channels + 1; /* includes coupling channel */ | |||
if (s->allocate_sample_buffers(s)) | |||
@@ -2197,7 +2201,7 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx) | |||
ff_ac3_common_init(); | |||
ret = validate_options(avctx, s); | |||
ret = validate_options(s); | |||
if (ret) | |||
return ret; | |||
@@ -2237,12 +2241,11 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx) | |||
bit_alloc_init(s); | |||
FF_ALLOCZ_OR_GOTO(avctx, s->mdct, sizeof(AC3MDCTContext), init_fail); | |||
ret = s->mdct_init(avctx, s->mdct, 9); | |||
ret = s->mdct_init(s); | |||
if (ret) | |||
goto init_fail; | |||
ret = allocate_buffers(avctx); | |||
ret = allocate_buffers(s); | |||
if (ret) | |||
goto init_fail; | |||
@@ -2251,7 +2254,7 @@ av_cold int ff_ac3_encode_init(AVCodecContext *avctx) | |||
dsputil_init(&s->dsp, avctx); | |||
ff_ac3dsp_init(&s->ac3dsp, avctx->flags & CODEC_FLAG_BITEXACT); | |||
dprint_options(avctx); | |||
dprint_options(s); | |||
return 0; | |||
init_fail: | |||
@@ -66,10 +66,6 @@ typedef int64_t CoefSumType; | |||
#endif | |||
typedef struct AC3MDCTContext { | |||
const SampleType *window; ///< MDCT window function | |||
FFTContext fft; ///< FFT context for MDCT calculation | |||
} AC3MDCTContext; | |||
#if 0 | |||
/** | |||
* Encoding Options used by AVOption. | |||
@@ -143,7 +139,8 @@ typedef struct AC3EncodeContext { | |||
PutBitContext pb; ///< bitstream writer context | |||
DSPContext dsp; | |||
AC3DSPContext ac3dsp; ///< AC-3 optimized functions | |||
AC3MDCTContext *mdct; ///< MDCT context | |||
FFTContext mdct; ///< FFT context for MDCT calculation | |||
const SampleType *mdct_window; ///< MDCT window function array | |||
AC3Block blocks[AC3_MAX_BLOCKS]; ///< per-block info | |||
@@ -226,8 +223,8 @@ typedef struct AC3EncodeContext { | |||
int ref_bap_set; ///< indicates if ref_bap pointers have been set | |||
/* fixed vs. float function pointers */ | |||
void (*mdct_end)(AC3MDCTContext *mdct); | |||
int (*mdct_init)(AVCodecContext *avctx, AC3MDCTContext *mdct, int nbits); | |||
void (*mdct_end)(struct AC3EncodeContext *s); | |||
int (*mdct_init)(struct AC3EncodeContext *s); | |||
/* fixed vs. float templated function pointers */ | |||
int (*allocate_sample_buffers)(struct AC3EncodeContext *s); | |||
@@ -241,7 +238,7 @@ int ff_ac3_encode_init(AVCodecContext *avctx); | |||
int ff_ac3_encode_close(AVCodecContext *avctx); | |||
int ff_ac3_validate_metadata(AVCodecContext *avctx); | |||
int ff_ac3_validate_metadata(AC3EncodeContext *s); | |||
void ff_ac3_adjust_frame_size(AC3EncodeContext *s); | |||
@@ -260,13 +257,11 @@ void ff_ac3_output_frame(AC3EncodeContext *s, unsigned char *frame); | |||
/* prototypes for functions in ac3enc_fixed.c and ac3enc_float.c */ | |||
void ff_ac3_fixed_mdct_end(AC3MDCTContext *mdct); | |||
void ff_ac3_float_mdct_end(AC3MDCTContext *mdct); | |||
void ff_ac3_fixed_mdct_end(AC3EncodeContext *s); | |||
void ff_ac3_float_mdct_end(AC3EncodeContext *s); | |||
int ff_ac3_fixed_mdct_init(AVCodecContext *avctx, AC3MDCTContext *mdct, | |||
int nbits); | |||
int ff_ac3_float_mdct_init(AVCodecContext *avctx, AC3MDCTContext *mdct, | |||
int nbits); | |||
int ff_ac3_fixed_mdct_init(AC3EncodeContext *s); | |||
int ff_ac3_float_mdct_init(AC3EncodeContext *s); | |||
/* prototypes for functions in ac3enc_template.c */ | |||
@@ -41,9 +41,9 @@ static AVClass ac3enc_class = { "Fixed-Point AC-3 Encoder", av_default_item_name | |||
/** | |||
* Finalize MDCT and free allocated memory. | |||
*/ | |||
av_cold void AC3_NAME(mdct_end)(AC3MDCTContext *mdct) | |||
av_cold void AC3_NAME(mdct_end)(AC3EncodeContext *s) | |||
{ | |||
ff_mdct_end(&mdct->fft); | |||
ff_mdct_end(&s->mdct); | |||
} | |||
@@ -51,11 +51,10 @@ av_cold void AC3_NAME(mdct_end)(AC3MDCTContext *mdct) | |||
* Initialize MDCT tables. | |||
* @param nbits log2(MDCT size) | |||
*/ | |||
av_cold int AC3_NAME(mdct_init)(AVCodecContext *avctx, AC3MDCTContext *mdct, | |||
int nbits) | |||
av_cold int AC3_NAME(mdct_init)(AC3EncodeContext *s) | |||
{ | |||
int ret = ff_mdct_init(&mdct->fft, nbits, 0, -1.0); | |||
mdct->window = ff_ac3_window; | |||
int ret = ff_mdct_init(&s->mdct, 9, 0, -1.0); | |||
s->mdct_window = ff_ac3_window; | |||
return ret; | |||
} | |||
@@ -45,10 +45,10 @@ static AVClass ac3enc_class = { "AC-3 Encoder", av_default_item_name, | |||
/** | |||
* Finalize MDCT and free allocated memory. | |||
*/ | |||
av_cold void ff_ac3_float_mdct_end(AC3MDCTContext *mdct) | |||
av_cold void ff_ac3_float_mdct_end(AC3EncodeContext *s) | |||
{ | |||
ff_mdct_end(&mdct->fft); | |||
av_freep(&mdct->window); | |||
ff_mdct_end(&s->mdct); | |||
av_freep(&s->mdct_window); | |||
} | |||
@@ -56,26 +56,25 @@ av_cold void ff_ac3_float_mdct_end(AC3MDCTContext *mdct) | |||
* Initialize MDCT tables. | |||
* @param nbits log2(MDCT size) | |||
*/ | |||
av_cold int ff_ac3_float_mdct_init(AVCodecContext *avctx, AC3MDCTContext *mdct, | |||
int nbits) | |||
av_cold int ff_ac3_float_mdct_init(AC3EncodeContext *s) | |||
{ | |||
float *window; | |||
int i, n, n2; | |||
n = 1 << nbits; | |||
n = 1 << 9; | |||
n2 = n >> 1; | |||
window = av_malloc(n * sizeof(*window)); | |||
if (!window) { | |||
av_log(avctx, AV_LOG_ERROR, "Cannot allocate memory.\n"); | |||
av_log(s->avctx, AV_LOG_ERROR, "Cannot allocate memory.\n"); | |||
return AVERROR(ENOMEM); | |||
} | |||
ff_kbd_window_init(window, 5.0, n2); | |||
for (i = 0; i < n2; i++) | |||
window[n-1-i] = window[i]; | |||
mdct->window = window; | |||
s->mdct_window = window; | |||
return ff_mdct_init(&mdct->fft, nbits, 0, -2.0 / n); | |||
return ff_mdct_init(&s->mdct, 9, 0, -2.0 / n); | |||
} | |||
@@ -108,13 +108,13 @@ static void apply_mdct(AC3EncodeContext *s) | |||
const SampleType *input_samples = &s->planar_samples[ch][blk * AC3_BLOCK_SIZE]; | |||
apply_window(&s->dsp, s->windowed_samples, input_samples, | |||
s->mdct->window, AC3_WINDOW_SIZE); | |||
s->mdct_window, AC3_WINDOW_SIZE); | |||
if (s->fixed_point) | |||
block->coeff_shift[ch+1] = normalize_samples(s); | |||
s->mdct->fft.mdct_calcw(&s->mdct->fft, block->mdct_coef[ch+1], | |||
s->windowed_samples); | |||
s->mdct.mdct_calcw(&s->mdct, block->mdct_coef[ch+1], | |||
s->windowed_samples); | |||
} | |||
} | |||
} | |||
@@ -424,7 +424,7 @@ int AC3_NAME(encode_frame)(AVCodecContext *avctx, unsigned char *frame, | |||
int ret; | |||
if (!s->eac3 && s->options.allow_per_frame_metadata) { | |||
ret = ff_ac3_validate_metadata(avctx); | |||
ret = ff_ac3_validate_metadata(s); | |||
if (ret) | |||
return ret; | |||
} | |||
@@ -2577,7 +2577,7 @@ AVCodec ff_mpeg1video_decoder = { | |||
NULL, | |||
mpeg_decode_end, | |||
mpeg_decode_frame, | |||
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY, | |||
CODEC_CAP_DRAW_HORIZ_BAND | CODEC_CAP_DR1 | CODEC_CAP_TRUNCATED | CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS, | |||
.flush= flush, | |||
.max_lowres= 3, | |||
.long_name= NULL_IF_CONFIG_SMALL("MPEG-1 video"), | |||
@@ -341,7 +341,7 @@ OBJS-$(CONFIG_UDP_PROTOCOL) += udp.o | |||
OBJS-$(CONFIG_ALSA_INDEV) += timefilter.o | |||
OBJS-$(CONFIG_JACK_INDEV) += timefilter.o | |||
TESTPROGS = timefilter | |||
TESTPROGS = seek timefilter | |||
TOOLS = pktdumper probetest | |||
include $(SRC_PATH)/subdir.mak |
@@ -343,11 +343,8 @@ static DVMuxContext* dv_init_mux(AVFormatContext* s) | |||
c->start_time = s->timestamp; | |||
else | |||
#endif | |||
if (t = av_dict_get(s->metadata, "creation_time", NULL, 0)) { | |||
struct tm time = {0}; | |||
strptime(t->value, "%Y - %m - %dT%T", &time); | |||
c->start_time = mktime(&time); | |||
} | |||
if (t = av_dict_get(s->metadata, "creation_time", NULL, 0)) | |||
c->start_time = ff_iso8601_to_unix_time(t->value); | |||
for (i=0; i < c->n_ast; i++) { | |||
if (c->ast[i] && !(c->audio_data[i]=av_fifo_alloc(100*AVCODEC_MAX_AUDIO_FRAME_SIZE))) { | |||
@@ -402,12 +402,8 @@ static int gxf_write_umf_material_description(AVFormatContext *s) | |||
timestamp = s->timestamp; | |||
else | |||
#endif | |||
if (t = av_dict_get(s->metadata, "creation_time", NULL, 0)) { | |||
struct tm time = {0}; | |||
strptime(t->value, "%Y - %m - %dT%T", &time); | |||
timestamp = mktime(&time); | |||
} | |||
if (t = av_dict_get(s->metadata, "creation_time", NULL, 0)) | |||
timestamp = ff_iso8601_to_unix_time(t->value); | |||
// XXX drop frame | |||
uint32_t timecode = | |||
@@ -246,4 +246,9 @@ void ff_make_absolute_url(char *buf, int size, const char *base, | |||
enum CodecID ff_guess_image2_codec(const char *filename); | |||
/** | |||
* Convert a date string in ISO8601 format to Unix timestamp. | |||
*/ | |||
int64_t ff_iso8601_to_unix_time(const char *datestr); | |||
#endif /* AVFORMAT_INTERNAL_H */ |
@@ -2279,11 +2279,8 @@ static int mov_write_header(AVFormatContext *s) | |||
mov->time = s->timestamp; | |||
else | |||
#endif | |||
if (t = av_dict_get(s->metadata, "creation_time", NULL, 0)) { | |||
struct tm time = {0}; | |||
strptime(t->value, "%Y - %m - %dT%T", &time); | |||
mov->time = mktime(&time); | |||
} | |||
if (t = av_dict_get(s->metadata, "creation_time", NULL, 0)) | |||
mov->time = ff_iso8601_to_unix_time(t->value); | |||
mov->time += 0x7C25B080; //1970 based -> 1904 based | |||
if (mov->chapter_track) | |||
@@ -70,7 +70,15 @@ static int mpc_read_header(AVFormatContext *s, AVFormatParameters *ap) | |||
av_log(s, AV_LOG_ERROR, "Too many frames, seeking is not possible\n"); | |||
return -1; | |||
} | |||
c->frames = av_malloc(c->fcount * sizeof(MPCFrame)); | |||
if(c->fcount){ | |||
c->frames = av_malloc(c->fcount * sizeof(MPCFrame)); | |||
if(!c->frames){ | |||
av_log(s, AV_LOG_ERROR, "Cannot allocate seektable\n"); | |||
return AVERROR(ENOMEM); | |||
} | |||
}else{ | |||
av_log(s, AV_LOG_WARNING, "Container reports no frames\n"); | |||
} | |||
c->curframe = 0; | |||
c->lastframe = -1; | |||
c->curbits = 8; | |||
@@ -111,7 +119,7 @@ static int mpc_read_packet(AVFormatContext *s, AVPacket *pkt) | |||
int ret, size, size2, curbits, cur = c->curframe; | |||
int64_t tmp, pos; | |||
if (c->curframe >= c->fcount) | |||
if (c->curframe >= c->fcount && c->fcount) | |||
return -1; | |||
if(c->curframe != c->lastframe + 1){ | |||
@@ -133,7 +141,7 @@ static int mpc_read_packet(AVFormatContext *s, AVPacket *pkt) | |||
avio_seek(s->pb, pos, SEEK_SET); | |||
size = ((size2 + curbits + 31) & ~31) >> 3; | |||
if(cur == c->frames_noted){ | |||
if(cur == c->frames_noted && c->fcount){ | |||
c->frames[cur].pos = pos; | |||
c->frames[cur].size = size; | |||
c->frames[cur].skip = curbits - 20; | |||
@@ -146,7 +154,7 @@ static int mpc_read_packet(AVFormatContext *s, AVPacket *pkt) | |||
return AVERROR(EIO); | |||
pkt->data[0] = curbits; | |||
pkt->data[1] = (c->curframe > c->fcount); | |||
pkt->data[1] = (c->curframe > c->fcount) && c->fcount; | |||
pkt->data[2] = 0; | |||
pkt->data[3] = 0; | |||
@@ -204,6 +204,7 @@ typedef struct MpegTSWriteStream { | |||
int first_pts_check; ///< first pts check needed | |||
int64_t payload_pts; | |||
int64_t payload_dts; | |||
int payload_flags; | |||
uint8_t payload[DEFAULT_PES_PAYLOAD_SIZE]; | |||
ADTSContext *adts; | |||
} MpegTSWriteStream; | |||
@@ -621,7 +622,7 @@ static int64_t get_pcr(const MpegTSWrite *ts, AVIOContext *pb) | |||
ts->first_pcr; | |||
} | |||
static uint8_t* write_pcr_bits(uint8_t *buf, int64_t pcr) | |||
static int write_pcr_bits(uint8_t *buf, int64_t pcr) | |||
{ | |||
int64_t pcr_low = pcr % 300, pcr_high = pcr / 300; | |||
@@ -632,7 +633,7 @@ static uint8_t* write_pcr_bits(uint8_t *buf, int64_t pcr) | |||
*buf++ = pcr_high << 7 | pcr_low >> 8 | 0x7e; | |||
*buf++ = pcr_low; | |||
return buf; | |||
return 6; | |||
} | |||
/* Write a single null transport stream packet */ | |||
@@ -668,7 +669,7 @@ static void mpegts_insert_pcr_only(AVFormatContext *s, AVStream *st) | |||
*q++ = 0x10; /* Adaptation flags: PCR present */ | |||
/* PCR coded into 6 bytes */ | |||
q = write_pcr_bits(q, get_pcr(ts, s->pb)); | |||
q += write_pcr_bits(q, get_pcr(ts, s->pb)); | |||
/* stuffing bytes */ | |||
memset(q, 0xFF, TS_PACKET_SIZE - (q - buf)); | |||
@@ -689,6 +690,39 @@ static void write_pts(uint8_t *q, int fourbits, int64_t pts) | |||
*q++ = val; | |||
} | |||
/* Set an adaptation field flag in an MPEG-TS packet*/ | |||
static void set_af_flag(uint8_t *pkt, int flag) | |||
{ | |||
// expect at least one flag to set | |||
assert(flag); | |||
if ((pkt[3] & 0x20) == 0) { | |||
// no AF yet, set adaptation field flag | |||
pkt[3] |= 0x20; | |||
// 1 byte length, no flags | |||
pkt[4] = 1; | |||
pkt[5] = 0; | |||
} | |||
pkt[5] |= flag; | |||
} | |||
/* Extend the adaptation field by size bytes */ | |||
static void extend_af(uint8_t *pkt, int size) | |||
{ | |||
// expect already existing adaptation field | |||
assert(pkt[3] & 0x20); | |||
pkt[4] += size; | |||
} | |||
/* Get a pointer to MPEG-TS payload (right after TS packet header) */ | |||
static uint8_t *get_ts_payload_start(uint8_t *pkt) | |||
{ | |||
if (pkt[3] & 0x20) | |||
return pkt + 5 + pkt[4]; | |||
else | |||
return pkt + 4; | |||
} | |||
/* Add a pes header to the front of payload, and segment into an integer number of | |||
* ts packets. The final ts packet is padded using an over-sized adaptation header | |||
* to exactly fill the last ts packet. | |||
@@ -696,7 +730,7 @@ static void write_pts(uint8_t *q, int fourbits, int64_t pts) | |||
*/ | |||
static void mpegts_write_pes(AVFormatContext *s, AVStream *st, | |||
const uint8_t *payload, int payload_size, | |||
int64_t pts, int64_t dts) | |||
int64_t pts, int64_t dts, int key) | |||
{ | |||
MpegTSWriteStream *ts_st = st->priv_data; | |||
MpegTSWrite *ts = s->priv_data; | |||
@@ -741,8 +775,17 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, | |||
*q++ = val; | |||
*q++ = ts_st->pid; | |||
ts_st->cc = (ts_st->cc + 1) & 0xf; | |||
*q++ = 0x10 | ts_st->cc | (write_pcr ? 0x20 : 0); | |||
*q++ = 0x10 | ts_st->cc; // payload indicator + CC | |||
if (key && is_start && pts != AV_NOPTS_VALUE) { | |||
// set Random Access for key frames | |||
if (ts_st->pid == ts_st->service->pcr_pid) | |||
write_pcr = 1; | |||
set_af_flag(buf, 0x40); | |||
q = get_ts_payload_start(buf); | |||
} | |||
if (write_pcr) { | |||
set_af_flag(buf, 0x10); | |||
q = get_ts_payload_start(buf); | |||
// add 11, pcr references the last byte of program clock reference base | |||
if (ts->mux_rate > 1) | |||
pcr = get_pcr(ts, s->pb); | |||
@@ -750,9 +793,8 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st, | |||
pcr = (dts - delay)*300; | |||
if (dts != AV_NOPTS_VALUE && dts < pcr / 300) | |||
av_log(s, AV_LOG_WARNING, "dts < pcr, TS is invalid\n"); | |||
*q++ = 7; /* AFC length */ | |||
*q++ = 0x10; /* flags: PCR present */ | |||
q = write_pcr_bits(q, pcr); | |||
extend_af(buf, write_pcr_bits(q, pcr)); | |||
q = get_ts_payload_start(buf); | |||
} | |||
if (is_start) { | |||
int pes_extension = 0; | |||
@@ -950,20 +992,22 @@ static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt) | |||
if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO) { | |||
// for video and subtitle, write a single pes packet | |||
mpegts_write_pes(s, st, buf, size, pts, dts); | |||
mpegts_write_pes(s, st, buf, size, pts, dts, pkt->flags & AV_PKT_FLAG_KEY); | |||
av_free(data); | |||
return 0; | |||
} | |||
if (ts_st->payload_index + size > DEFAULT_PES_PAYLOAD_SIZE) { | |||
mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index, | |||
ts_st->payload_pts, ts_st->payload_dts); | |||
ts_st->payload_pts, ts_st->payload_dts, | |||
ts_st->payload_flags & AV_PKT_FLAG_KEY); | |||
ts_st->payload_index = 0; | |||
} | |||
if (!ts_st->payload_index) { | |||
ts_st->payload_pts = pts; | |||
ts_st->payload_dts = dts; | |||
ts_st->payload_flags = pkt->flags; | |||
} | |||
memcpy(ts_st->payload + ts_st->payload_index, buf, size); | |||
@@ -988,7 +1032,8 @@ static int mpegts_write_end(AVFormatContext *s) | |||
ts_st = st->priv_data; | |||
if (ts_st->payload_index > 0) { | |||
mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_index, | |||
ts_st->payload_pts, ts_st->payload_dts); | |||
ts_st->payload_pts, ts_st->payload_dts, | |||
ts_st->payload_flags & AV_PKT_FLAG_KEY); | |||
} | |||
av_freep(&ts_st->adts); | |||
} | |||
@@ -39,6 +39,7 @@ | |||
#include "libavcodec/bytestream.h" | |||
#include "audiointerleave.h" | |||
#include "avformat.h" | |||
#include "internal.h" | |||
#include "mxf.h" | |||
static const int NTSC_samples_per_frame[] = { 1602, 1601, 1602, 1601, 1602, 0 }; | |||
@@ -1519,11 +1520,8 @@ static int mxf_write_header(AVFormatContext *s) | |||
timestamp = s->timestamp; | |||
else | |||
#endif | |||
if (t = av_dict_get(s->metadata, "creation_time", NULL, 0)) { | |||
struct tm time = {0}; | |||
strptime(t->value, "%Y - %m - %dT%T", &time); | |||
timestamp = mktime(&time); | |||
} | |||
if (t = av_dict_get(s->metadata, "creation_time", NULL, 0)) | |||
timestamp = ff_iso8601_to_unix_time(t->value); | |||
if (timestamp) | |||
mxf->timestamp = mxf_parse_timestamp(timestamp); | |||
mxf->duration = -1; | |||
@@ -471,7 +471,8 @@ int av_open_input_stream(AVFormatContext **ic_ptr, | |||
else | |||
ic->pb = pb; | |||
err = avformat_open_input(&ic, filename, fmt, &opts); | |||
if ((err = avformat_open_input(&ic, filename, fmt, &opts)) < 0) | |||
goto fail; | |||
ic->pb = ic->pb ? ic->pb : pb; // don't leak custom pb if it wasn't set above | |||
*ic_ptr = ic; | |||
@@ -2129,7 +2130,8 @@ static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **option | |||
return ret; | |||
} | |||
if(!has_codec_parameters(st->codec) || !has_decode_delay_been_guessed(st)){ | |||
if(!has_codec_parameters(st->codec) || !has_decode_delay_been_guessed(st) || | |||
(!st->codec_info_nb_frames && st->codec->codec->capabilities & CODEC_CAP_CHANNEL_CONF)) { | |||
switch(st->codec->codec_type) { | |||
case AVMEDIA_TYPE_VIDEO: | |||
avcodec_get_frame_defaults(&picture); | |||
@@ -2436,11 +2438,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) | |||
least one frame of codec data, this makes sure the codec initializes | |||
the channel configuration and does not only trust the values from the container. | |||
*/ | |||
if (!has_codec_parameters(st->codec) || | |||
!has_decode_delay_been_guessed(st) || | |||
(st->codec->codec && | |||
st->codec->codec->capabilities & CODEC_CAP_CHANNEL_CONF)) | |||
try_decode_frame(st, pkt, (options && i <= orig_nb_streams )? &options[i] : NULL); | |||
try_decode_frame(st, pkt, (options && i <= orig_nb_streams )? &options[i] : NULL); | |||
st->codec_info_nb_frames++; | |||
count++; | |||
@@ -4012,3 +4010,16 @@ void ff_make_absolute_url(char *buf, int size, const char *base, | |||
} | |||
av_strlcat(buf, rel, size); | |||
} | |||
int64_t ff_iso8601_to_unix_time(const char *datestr) | |||
{ | |||
#if HAVE_STRPTIME | |||
struct tm time = {0}; | |||
strptime(datestr, "%Y - %m - %dT%T", &time); | |||
return mktime(&time); | |||
#else | |||
av_log(NULL, AV_LOG_WARNING, "strptime() unavailable on this system, cannot convert " | |||
"the date string.\n"); | |||
return 0; | |||
#endif | |||
} |
@@ -23,23 +23,85 @@ | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
*/ | |||
#include "libavutil/avassert.h" | |||
#include "libavutil/dict.h" | |||
#include "libavutil/log.h" | |||
#include "libavutil/mathematics.h" | |||
#include "libavutil/opt.h" | |||
#include "avformat.h" | |||
#include "avio_internal.h" | |||
#include "pcm.h" | |||
#include "riff.h" | |||
#include "avio.h" | |||
#include "avio_internal.h" | |||
#include "metadata.h" | |||
typedef struct { | |||
const AVClass *class; | |||
int64_t data; | |||
int64_t data_end; | |||
int64_t minpts; | |||
int64_t maxpts; | |||
int last_duration; | |||
int w64; | |||
int write_bext; | |||
} WAVContext; | |||
#if CONFIG_WAV_MUXER | |||
static inline void bwf_write_bext_string(AVFormatContext *s, const char *key, int maxlen) | |||
{ | |||
AVDictionaryEntry *tag; | |||
int len = 0; | |||
if (tag = av_dict_get(s->metadata, key, NULL, 0)) { | |||
len = strlen(tag->value); | |||
len = FFMIN(len, maxlen); | |||
avio_write(s->pb, tag->value, len); | |||
} | |||
ffio_fill(s->pb, 0, maxlen - len); | |||
} | |||
static void bwf_write_bext_chunk(AVFormatContext *s) | |||
{ | |||
AVDictionaryEntry *tmp_tag; | |||
uint64_t time_reference = 0; | |||
int64_t bext = ff_start_tag(s->pb, "bext"); | |||
bwf_write_bext_string(s, "description", 256); | |||
bwf_write_bext_string(s, "originator", 32); | |||
bwf_write_bext_string(s, "originator_reference", 32); | |||
bwf_write_bext_string(s, "origination_date", 10); | |||
bwf_write_bext_string(s, "origination_time", 8); | |||
if (tmp_tag = av_dict_get(s->metadata, "time_reference", NULL, 0)) | |||
time_reference = strtoll(tmp_tag->value, NULL, 10); | |||
avio_wl64(s->pb, time_reference); | |||
avio_wl16(s->pb, 1); // set version to 1 | |||
if (tmp_tag = av_dict_get(s->metadata, "umid", NULL, 0)) { | |||
unsigned char umidpart_str[17] = {0}; | |||
int i; | |||
uint64_t umidpart; | |||
int len = strlen(tmp_tag->value+2); | |||
for (i = 0; i < len/16; i++) { | |||
memcpy(umidpart_str, tmp_tag->value + 2 + (i*16), 16); | |||
umidpart = strtoll(umidpart_str, NULL, 16); | |||
avio_wb64(s->pb, umidpart); | |||
} | |||
ffio_fill(s->pb, 0, 64 - i*8); | |||
} else | |||
ffio_fill(s->pb, 0, 64); // zero UMID | |||
ffio_fill(s->pb, 0, 190); // Reserved | |||
if (tmp_tag = av_dict_get(s->metadata, "coding_history", NULL, 0)) | |||
avio_put_str(s->pb, tmp_tag->value); | |||
ff_end_tag(s->pb, bext); | |||
} | |||
static int wav_write_header(AVFormatContext *s) | |||
{ | |||
WAVContext *wav = s->priv_data; | |||
@@ -66,6 +128,9 @@ static int wav_write_header(AVFormatContext *s) | |||
ff_end_tag(pb, fact); | |||
} | |||
if (wav->write_bext) | |||
bwf_write_bext_chunk(s); | |||
av_set_pts_info(s->streams[0], 64, 1, s->streams[0]->codec->sample_rate); | |||
wav->maxpts = wav->last_duration = 0; | |||
wav->minpts = INT64_MAX; | |||
@@ -126,6 +191,20 @@ static int wav_write_trailer(AVFormatContext *s) | |||
return 0; | |||
} | |||
#define OFFSET(x) offsetof(WAVContext, x) | |||
#define ENC AV_OPT_FLAG_ENCODING_PARAM | |||
static const AVOption options[] = { | |||
{ "write_bext", "Write BEXT chunk.", OFFSET(write_bext), FF_OPT_TYPE_INT, { 0 }, 0, 1, ENC }, | |||
{ NULL }, | |||
}; | |||
static const AVClass wav_muxer_class = { | |||
.class_name = "WAV muxer", | |||
.item_name = av_default_item_name, | |||
.option = options, | |||
.version = LIBAVUTIL_VERSION_INT, | |||
}; | |||
AVOutputFormat ff_wav_muxer = { | |||
"wav", | |||
NULL_IF_CONFIG_SMALL("WAV format"), | |||
@@ -138,6 +217,7 @@ AVOutputFormat ff_wav_muxer = { | |||
wav_write_packet, | |||
wav_write_trailer, | |||
.codec_tag= (const AVCodecTag* const []){ff_codec_wav_tags, 0}, | |||
.priv_class = &wav_muxer_class, | |||
}; | |||
#endif /* CONFIG_WAV_MUXER */ | |||
@@ -207,11 +287,13 @@ static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream **st) | |||
return 0; | |||
} | |||
static inline int wav_parse_bext_string(AVFormatContext *s, const char *key, int length) | |||
static inline int wav_parse_bext_string(AVFormatContext *s, const char *key, | |||
int length) | |||
{ | |||
char temp[257]; | |||
int ret; | |||
av_assert0(length <= sizeof(temp)); | |||
if ((ret = avio_read(s->pb, temp, length)) < 0) | |||
return ret; | |||
@@ -337,6 +419,7 @@ static int wav_read_header(AVFormatContext *s, | |||
return AVERROR_INVALIDDATA; | |||
} | |||
avio_skip(pb, size - 24); /* skip rest of ds64 chunk */ | |||
} | |||
for (;;) { | |||
@@ -378,7 +461,7 @@ static int wav_read_header(AVFormatContext *s, | |||
goto break_loop; | |||
break; | |||
case MKTAG('f','a','c','t'): | |||
if(!sample_count) | |||
if (!sample_count) | |||
sample_count = avio_rl32(pb); | |||
break; | |||
case MKTAG('b','e','x','t'): | |||
@@ -28,9 +28,6 @@ tests/data/asynth1.sw: tests/audiogen$(HOSTEXESUF) | |||
tests/data/asynth1.sw tests/vsynth%/00.pgm: TAG = GEN | |||
tests/seek_test$(EXESUF): tests/seek_test.o $(FF_DEP_LIBS) | |||
$(LD) $(LDFLAGS) -o $@ $< $(FF_EXTRALIBS) | |||
include $(SRC_PATH)/tests/fate.mak | |||
include $(SRC_PATH)/tests/fate2.mak | |||
@@ -64,7 +61,7 @@ $(filter-out %-aref,$(FATE_ACODEC)): $(AREF) | |||
$(filter-out %-vref,$(FATE_VCODEC)): $(VREF) | |||
$(FATE_LAVF): $(REFS) | |||
$(FATE_LAVFI): $(REFS) tools/lavfi-showfiltfmts$(EXESUF) | |||
$(FATE_SEEK): fate-codec fate-lavf tests/seek_test$(EXESUF) | |||
$(FATE_SEEK): fate-codec fate-lavf libavformat/seek-test$(EXESUF) | |||
$(FATE_ACODEC): CMD = codectest acodec | |||
$(FATE_VSYNTH1): CMD = codectest vsynth1 | |||
@@ -107,7 +104,6 @@ clean:: testclean | |||
testclean: | |||
$(RM) -r tests/vsynth1 tests/vsynth2 tests/data | |||
$(RM) $(CLEANSUFFIXES:%=tests/%) | |||
$(RM) tests/seek_test$(EXESUF) tests/seek_test.o | |||
$(RM) $(TESTTOOLS:%=tests/%$(HOSTEXESUF)) | |||
-include $(wildcard tests/*.d) | |||
@@ -104,7 +104,7 @@ seektest(){ | |||
file=$(echo tests/data/$d/$file) | |||
;; | |||
esac | |||
$target_exec $target_path/tests/seek_test $target_path/$file | |||
$target_exec $target_path/libavformat/seek-test $target_path/$file | |||
} | |||
mkdir -p "$outdir" | |||
@@ -1,3 +1,3 @@ | |||
178f5094fc874112d21b4a8716121d96 *./tests/data/lavf/lavf.ts | |||
151774afed45b19da9b7e83613a1e72b *./tests/data/lavf/lavf.ts | |||
406644 ./tests/data/lavf/lavf.ts | |||
./tests/data/lavf/lavf.ts CRC=0x133216c1 |
@@ -1,133 +0,0 @@ | |||
/* | |||
* Copyright (c) 2003 Fabrice Bellard | |||
* Copyright (c) 2007 Michael Niedermayer | |||
* | |||
* This file is part of FFmpeg. | |||
* | |||
* FFmpeg is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU Lesser General Public | |||
* License as published by the Free Software Foundation; either | |||
* version 2.1 of the License, or (at your option) any later version. | |||
* | |||
* FFmpeg is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |||
* Lesser General Public License for more details. | |||
* | |||
* You should have received a copy of the GNU Lesser General Public | |||
* License along with FFmpeg; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
*/ | |||
#include <stdint.h> | |||
#include <stdlib.h> | |||
#include <stdio.h> | |||
#include <string.h> | |||
#include "libavutil/common.h" | |||
#include "libavutil/mathematics.h" | |||
#include "libavformat/avformat.h" | |||
#undef exit | |||
#undef printf | |||
#undef fprintf | |||
static char buffer[20]; | |||
static const char *ret_str(int v) | |||
{ | |||
switch (v) { | |||
case AVERROR_EOF: return "-EOF"; | |||
case AVERROR(EIO): return "-EIO"; | |||
case AVERROR(ENOMEM): return "-ENOMEM"; | |||
case AVERROR(EINVAL): return "-EINVAL"; | |||
default: | |||
snprintf(buffer, sizeof(buffer), "%2d", v); | |||
return buffer; | |||
} | |||
} | |||
static void ts_str(char buffer[60], int64_t ts, AVRational base) | |||
{ | |||
double tsval; | |||
if (ts == AV_NOPTS_VALUE) { | |||
strcpy(buffer, " NOPTS "); | |||
return; | |||
} | |||
tsval = ts * av_q2d(base); | |||
snprintf(buffer, 60, "%9f", tsval); | |||
} | |||
int main(int argc, char **argv) | |||
{ | |||
const char *filename; | |||
AVFormatContext *ic = NULL; | |||
int i, ret, stream_id; | |||
int64_t timestamp; | |||
AVFormatParameters params, *ap= ¶ms; | |||
memset(ap, 0, sizeof(params)); | |||
ap->channels=1; | |||
ap->sample_rate= 22050; | |||
/* initialize libavcodec, and register all codecs and formats */ | |||
av_register_all(); | |||
if (argc != 2) { | |||
printf("usage: %s input_file\n" | |||
"\n", argv[0]); | |||
exit(1); | |||
} | |||
filename = argv[1]; | |||
ret = av_open_input_file(&ic, filename, NULL, 0, ap); | |||
if (ret < 0) { | |||
fprintf(stderr, "cannot open %s\n", filename); | |||
exit(1); | |||
} | |||
ret = av_find_stream_info(ic); | |||
if (ret < 0) { | |||
fprintf(stderr, "%s: could not find codec parameters\n", filename); | |||
exit(1); | |||
} | |||
for(i=0; ; i++){ | |||
AVPacket pkt; | |||
AVStream *av_uninit(st); | |||
char ts_buf[60]; | |||
memset(&pkt, 0, sizeof(pkt)); | |||
if(ret>=0){ | |||
ret= av_read_frame(ic, &pkt); | |||
if(ret>=0){ | |||
char dts_buf[60]; | |||
st= ic->streams[pkt.stream_index]; | |||
ts_str(dts_buf, pkt.dts, st->time_base); | |||
ts_str(ts_buf, pkt.pts, st->time_base); | |||
printf("ret:%-10s st:%2d flags:%d dts:%s pts:%s pos:%7" PRId64 " size:%6d", ret_str(ret), pkt.stream_index, pkt.flags, dts_buf, ts_buf, pkt.pos, pkt.size); | |||
av_free_packet(&pkt); | |||
} else | |||
printf("ret:%s", ret_str(ret)); // necessary to avoid trailing whitespace | |||
printf("\n"); | |||
} | |||
if(i>25) break; | |||
stream_id= (i>>1)%(ic->nb_streams+1) - 1; | |||
timestamp= (i*19362894167LL) % (4*AV_TIME_BASE) - AV_TIME_BASE; | |||
if(stream_id>=0){ | |||
st= ic->streams[stream_id]; | |||
timestamp= av_rescale_q(timestamp, AV_TIME_BASE_Q, st->time_base); | |||
} | |||
//FIXME fully test the new seek API | |||
if(i&1) ret = avformat_seek_file(ic, stream_id, INT64_MIN, timestamp, timestamp, 0); | |||
else ret = avformat_seek_file(ic, stream_id, timestamp, timestamp, INT64_MAX, 0); | |||
ts_str(ts_buf, timestamp, stream_id < 0 ? AV_TIME_BASE_Q : st->time_base); | |||
printf("ret:%-10s st:%2d flags:%d ts:%s\n", ret_str(ret), stream_id, i&1, ts_buf); | |||
} | |||
av_close_input_file(ic); | |||
return 0; | |||
} |