Newer
Older
if(ppkt1->pkt->pts != AV_NOPTS_VALUE)
break;
ppkt1->pkt->dts -= delta;
ppkt1= ppkt1->next;
}
if(ppkt1)
continue;
st->cur_dts -= delta;
}
}
}
#endif
av_free(duration_error);
for(i=0;i<MAX_STREAMS;i++){
av_freep(&(probe_data[i].buf));
}
Fabrice Bellard
committed
return ret;
/*******************************************************/
int av_read_play(AVFormatContext *s)
{
Björn Axelsson
committed
if (s->iformat->read_play)
return s->iformat->read_play(s);
if (s->pb && s->pb->read_play)
return av_url_read_fplay(s->pb);
return AVERROR(ENOSYS);
}
int av_read_pause(AVFormatContext *s)
{
Björn Axelsson
committed
if (s->iformat->read_pause)
return s->iformat->read_pause(s);
if (s->pb && s->pb->read_pause)
return av_url_read_fpause(s->pb);
return AVERROR(ENOSYS);
AVStream *st;
/* free previous packet */
if (s->cur_st && s->cur_st->parser)
av_free_packet(&s->cur_pkt);
Fabrice Bellard
committed
if (s->iformat->read_close)
s->iformat->read_close(s);
/* free all data in a stream component */
st = s->streams[i];
if (st->parser) {
av_parser_close(st->parser);
av_free(st->index_entries);
av_free(st->codec->extradata);
Michael Niedermayer
committed
av_free(st->codec);
Nico Sabbi
committed
for(i=s->nb_programs-1; i>=0; i--) {
av_freep(&s->programs[i]->provider_name);
av_freep(&s->programs[i]->name);
av_freep(&s->programs[i]->stream_index);
Nico Sabbi
committed
av_freep(&s->programs[i]);
}
flush_packet_queue(s);
if (s->iformat->flags & AVFMT_NOFILE) {
must_open_file = 0;
}
if (must_open_file) {
url_fclose(s->pb);
Philip Gladstone
committed
av_freep(&s->priv_data);
Fabrice Bellard
committed
AVStream *av_new_stream(AVFormatContext *s, int id)
{
AVStream *st;
int i;
Fabrice Bellard
committed
if (s->nb_streams >= MAX_STREAMS)
return NULL;
st = av_mallocz(sizeof(AVStream));
if (!st)
return NULL;
Michael Niedermayer
committed
st->codec= avcodec_alloc_context();
if (s->iformat) {
/* no default bitrate if decoding */
Michael Niedermayer
committed
st->codec->bit_rate = 0;
Fabrice Bellard
committed
st->index = s->nb_streams;
st->id = id;
Fabrice Bellard
committed
st->start_time = AV_NOPTS_VALUE;
st->duration = AV_NOPTS_VALUE;
st->cur_dts = AV_NOPTS_VALUE;
st->first_dts = AV_NOPTS_VALUE;
/* default pts settings is MPEG like */
av_set_pts_info(st, 33, 1, 90000);
for(i=0; i<MAX_REORDER_DELAY+1; i++)
st->pts_buffer[i]= AV_NOPTS_VALUE;
Fabrice Bellard
committed
s->streams[s->nb_streams++] = st;
return st;
}
Nico Sabbi
committed
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
AVProgram *av_new_program(AVFormatContext *ac, int id)
{
AVProgram *program=NULL;
int i;
#ifdef DEBUG_SI
av_log(ac, AV_LOG_DEBUG, "new_program: id=0x%04x\n", id);
#endif
for(i=0; i<ac->nb_programs; i++)
if(ac->programs[i]->id == id)
program = ac->programs[i];
if(!program){
program = av_mallocz(sizeof(AVProgram));
if (!program)
return NULL;
dynarray_add(&ac->programs, &ac->nb_programs, program);
program->discard = AVDISCARD_NONE;
}
program->id = id;
return program;
}
void av_set_program_name(AVProgram *program, char *provider_name, char *name)
{
assert(!provider_name == !name);
if(name){
av_free(program->provider_name);
av_free(program-> name);
program->provider_name = av_strdup(provider_name);
program-> name = av_strdup( name);
}
}
Fabrice Bellard
committed
/************************************************************/
/* output media file */
int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap)
{
int ret;
if (s->oformat->priv_data_size > 0) {
s->priv_data = av_mallocz(s->oformat->priv_data_size);
if (!s->priv_data)
return AVERROR(ENOMEM);
} else
s->priv_data = NULL;
if (s->oformat->set_parameters) {
ret = s->oformat->set_parameters(s, ap);
if (ret < 0)
return ret;
}
return 0;
}
Fabrice Bellard
committed
int av_write_header(AVFormatContext *s)
{
int ret, i;
AVStream *st;
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
// some sanity checks
for(i=0;i<s->nb_streams;i++) {
st = s->streams[i];
switch (st->codec->codec_type) {
case CODEC_TYPE_AUDIO:
if(st->codec->sample_rate<=0){
av_log(s, AV_LOG_ERROR, "sample rate not set\n");
return -1;
}
break;
case CODEC_TYPE_VIDEO:
if(st->codec->time_base.num<=0 || st->codec->time_base.den<=0){ //FIXME audio too?
av_log(s, AV_LOG_ERROR, "time base not set\n");
return -1;
}
if(st->codec->width<=0 || st->codec->height<=0){
av_log(s, AV_LOG_ERROR, "dimensions not set\n");
return -1;
}
break;
}
Michael Niedermayer
committed
if(s->oformat->codec_tag){
if(st->codec->codec_tag){
//FIXME
//check that tag + id is in the table
//if neither is in the table -> ok
//if tag is in the table with another id -> FAIL
//if id is in the table with another tag -> FAIL unless strict < ?
}else
st->codec->codec_tag= av_codec_get_tag(s->oformat->codec_tag, st->codec->codec_id);
}
if (!s->priv_data && s->oformat->priv_data_size > 0) {
s->priv_data = av_mallocz(s->oformat->priv_data_size);
if (!s->priv_data)
return AVERROR(ENOMEM);
if(s->oformat->write_header){
ret = s->oformat->write_header(s);
if (ret < 0)
return ret;
}
/* init PTS generation */
for(i=0;i<s->nb_streams;i++) {
Wolfram Gloger
committed
int64_t den = AV_NOPTS_VALUE;
Michael Niedermayer
committed
switch (st->codec->codec_type) {
Wolfram Gloger
committed
den = (int64_t)st->time_base.num * st->codec->sample_rate;
break;
case CODEC_TYPE_VIDEO:
Wolfram Gloger
committed
den = (int64_t)st->time_base.num * st->codec->time_base.den;
break;
default:
break;
}
Wolfram Gloger
committed
if (den != AV_NOPTS_VALUE) {
if (den <= 0)
return AVERROR_INVALIDDATA;
av_frac_init(&st->pts, 0, 0, den);
}
Fabrice Bellard
committed
}
//FIXME merge with compute_pkt_fields
Michael Niedermayer
committed
static int compute_pkt_fields2(AVStream *st, AVPacket *pkt){
int delay = FFMAX(st->codec->has_b_frames, !!st->codec->max_b_frames);
int num, den, frame_size, i;
// av_log(st->codec, AV_LOG_DEBUG, "av_write_frame: pts:%"PRId64" dts:%"PRId64" cur_dts:%"PRId64" b:%d size:%d st:%d\n", pkt->pts, pkt->dts, st->cur_dts, delay, pkt->size, pkt->stream_index);
/* if(pkt->pts == AV_NOPTS_VALUE && pkt->dts == AV_NOPTS_VALUE)
return -1;*/
if (pkt->duration == 0) {
compute_frame_duration(&num, &den, st, NULL, pkt);
if (den && num) {
pkt->duration = av_rescale(1, num * (int64_t)st->time_base.den, den * (int64_t)st->time_base.num);
}
}
//XXX/FIXME this is a temporary hack until all encoders output pts
if((pkt->pts == 0 || pkt->pts == AV_NOPTS_VALUE) && pkt->dts == AV_NOPTS_VALUE && !delay){
pkt->dts=
// pkt->pts= st->cur_dts;
pkt->pts= st->pts.val;
}
if(pkt->pts != AV_NOPTS_VALUE && pkt->dts == AV_NOPTS_VALUE){
st->pts_buffer[0]= pkt->pts;
for(i=1; i<delay+1 && st->pts_buffer[i] == AV_NOPTS_VALUE; i++)
st->pts_buffer[i]= (i-delay-1) * pkt->duration;
for(i=0; i<delay && st->pts_buffer[i] > st->pts_buffer[i+1]; i++)
FFSWAP(int64_t, st->pts_buffer[i], st->pts_buffer[i+1]);
pkt->dts= st->pts_buffer[0];
Michael Niedermayer
committed
if(st->cur_dts && st->cur_dts != AV_NOPTS_VALUE && st->cur_dts >= pkt->dts){
av_log(NULL, AV_LOG_ERROR, "error, non monotone timestamps %"PRId64" >= %"PRId64"\n", st->cur_dts, pkt->dts);
Michael Niedermayer
committed
return -1;
}
if(pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts < pkt->dts){
av_log(NULL, AV_LOG_ERROR, "error, pts < dts\n");
Michael Niedermayer
committed
return -1;
}
// av_log(NULL, AV_LOG_DEBUG, "av_write_frame: pts2:%"PRId64" dts2:%"PRId64"\n", pkt->pts, pkt->dts);
st->cur_dts= pkt->dts;
st->pts.val= pkt->dts;
Michael Niedermayer
committed
switch (st->codec->codec_type) {
Michael Niedermayer
committed
frame_size = get_audio_frame_size(st->codec, pkt->size);
/* HACK/FIXME, we skip the initial 0-size packets as they are most likely equal to the encoder delay,
but it would be better if we had the real timestamps from the encoder */
if (frame_size >= 0 && (pkt->size || st->pts.num!=st->pts.den>>1 || st->pts.val)) {
av_frac_add(&st->pts, (int64_t)st->time_base.den * frame_size);
Fabrice Bellard
committed
}
break;
case CODEC_TYPE_VIDEO:
Michael Niedermayer
committed
av_frac_add(&st->pts, (int64_t)st->time_base.den * st->codec->time_base.num);
break;
default:
break;
}
Michael Niedermayer
committed
return 0;
}
static void truncate_ts(AVStream *st, AVPacket *pkt){
int64_t pts_mask = (2LL << (st->pts_wrap_bits-1)) - 1;
// if(pkt->dts < 0)
// pkt->dts= 0; //this happens for low_delay=0 and b frames, FIXME, needs further invstigation about what we should do here
if (pkt->pts != AV_NOPTS_VALUE)
Andy Parkins
committed
pkt->pts &= pts_mask;
if (pkt->dts != AV_NOPTS_VALUE)
Andy Parkins
committed
pkt->dts &= pts_mask;
}
int av_write_frame(AVFormatContext *s, AVPacket *pkt)
{
Michael Niedermayer
committed
ret=compute_pkt_fields2(s->streams[pkt->stream_index], pkt);
Michael Niedermayer
committed
if(ret<0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
Michael Niedermayer
committed
return ret;
truncate_ts(s->streams[pkt->stream_index], pkt);
ret= s->oformat->write_packet(s, pkt);
if(!ret)
ret= url_ferror(s->pb);
int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush){
Michael Niedermayer
committed
AVPacketList *pktl, **next_point, *this_pktl;
int stream_count=0;
int streams[MAX_STREAMS];
if(pkt){
AVStream *st= s->streams[ pkt->stream_index];
// assert(pkt->destruct != av_destruct_packet); //FIXME
Michael Niedermayer
committed
this_pktl = av_mallocz(sizeof(AVPacketList));
this_pktl->pkt= *pkt;
if(pkt->destruct == av_destruct_packet)
pkt->destruct= NULL; // non shared -> must keep original from being freed
else
av_dup_packet(&this_pktl->pkt); //shared -> must dup
Michael Niedermayer
committed
next_point = &s->packet_buffer;
while(*next_point){
AVStream *st2= s->streams[ (*next_point)->pkt.stream_index];
int64_t left= st2->time_base.num * (int64_t)st ->time_base.den;
int64_t right= st ->time_base.num * (int64_t)st2->time_base.den;
if((*next_point)->pkt.dts * left > pkt->dts * right) //FIXME this can overflow
break;
next_point= &(*next_point)->next;
}
this_pktl->next= *next_point;
*next_point= this_pktl;
}
Michael Niedermayer
committed
memset(streams, 0, sizeof(streams));
pktl= s->packet_buffer;
while(pktl){
//av_log(s, AV_LOG_DEBUG, "show st:%d dts:%"PRId64"\n", pktl->pkt.stream_index, pktl->pkt.dts);
Michael Niedermayer
committed
if(streams[ pktl->pkt.stream_index ] == 0)
stream_count++;
streams[ pktl->pkt.stream_index ]++;
pktl= pktl->next;
}
Michael Niedermayer
committed
if(s->nb_streams == stream_count || (flush && stream_count)){
pktl= s->packet_buffer;
*out= pktl->pkt;
s->packet_buffer= pktl->next;
Michael Niedermayer
committed
av_freep(&pktl);
return 1;
}else{
av_init_packet(out);
return 0;
}
}
/**
* Interleaves a AVPacket correctly so it can be muxed.
* @param out the interleaved packet will be output here
* @param in the input packet
* @param flush 1 if no further packets are available as input and all
* remaining packets should be output
* @return 1 if a packet was output, 0 if no packet could be output,
Michael Niedermayer
committed
* < 0 if an error occured
*/
static int av_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *in, int flush){
if(s->oformat->interleave_packet)
return s->oformat->interleave_packet(s, out, in, flush);
else
return av_interleave_packet_per_dts(s, out, in, flush);
}
int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt){
AVStream *st= s->streams[ pkt->stream_index];
//FIXME/XXX/HACK drop zero sized packets
Michael Niedermayer
committed
if(st->codec->codec_type == CODEC_TYPE_AUDIO && pkt->size==0)
Michael Niedermayer
committed
//av_log(NULL, AV_LOG_DEBUG, "av_interleaved_write_frame %d %"PRId64" %"PRId64"\n", pkt->size, pkt->dts, pkt->pts);
Michael Niedermayer
committed
if(compute_pkt_fields2(st, pkt) < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
Michael Niedermayer
committed
return -1;
if(pkt->dts == AV_NOPTS_VALUE)
return -1;
Michael Niedermayer
committed
for(;;){
AVPacket opkt;
int ret= av_interleave_packet(s, &opkt, pkt, 0);
if(ret<=0) //FIXME cleanup needed for ret<0 ?
return ret;
Michael Niedermayer
committed
truncate_ts(s->streams[opkt.stream_index], &opkt);
ret= s->oformat->write_packet(s, &opkt);
Michael Niedermayer
committed
av_free_packet(&opkt);
pkt= NULL;
if(ret<0)
return ret;
if(url_ferror(s->pb))
return url_ferror(s->pb);
Fabrice Bellard
committed
}
int av_write_trailer(AVFormatContext *s)
{
int ret, i;
Michael Niedermayer
committed
for(;;){
AVPacket pkt;
ret= av_interleave_packet(s, &pkt, NULL, 1);
if(ret<0) //FIXME cleanup needed for ret<0 ?
goto fail;
Michael Niedermayer
committed
if(!ret)
break;
Michael Niedermayer
committed
truncate_ts(s->streams[pkt.stream_index], &pkt);
ret= s->oformat->write_packet(s, &pkt);
Michael Niedermayer
committed
av_free_packet(&pkt);
goto fail;
if(url_ferror(s->pb))
if(s->oformat->write_trailer)
ret = s->oformat->write_trailer(s);
ret=url_ferror(s->pb);
for(i=0;i<s->nb_streams;i++)
av_freep(&s->streams[i]->priv_data);
Fabrice Bellard
committed
av_freep(&s->priv_data);
return ret;
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
void av_program_add_stream_index(AVFormatContext *ac, int progid, unsigned int idx)
{
int i, j;
AVProgram *program=NULL;
void *tmp;
for(i=0; i<ac->nb_programs; i++){
if(ac->programs[i]->id != progid)
continue;
program = ac->programs[i];
for(j=0; j<program->nb_stream_indexes; j++)
if(program->stream_index[j] == idx)
return;
tmp = av_realloc(program->stream_index, sizeof(unsigned int)*(program->nb_stream_indexes+1));
if(!tmp)
return;
program->stream_index = tmp;
program->stream_index[program->nb_stream_indexes++] = idx;
return;
}
}
Baptiste Coudurier
committed
static void dump_stream_format(AVFormatContext *ic, int i, int index, int is_output)
Nico Sabbi
committed
{
Baptiste Coudurier
committed
char buf[256];
Nico Sabbi
committed
int flags = (is_output ? ic->oformat->flags : ic->iformat->flags);
AVStream *st = ic->streams[i];
int g = ff_gcd(st->time_base.num, st->time_base.den);
avcodec_string(buf, sizeof(buf), st->codec, is_output);
av_log(NULL, AV_LOG_INFO, " Stream #%d.%d", index, i);
/* the pid is an important information, so we display it */
/* XXX: add a generic system */
if (flags & AVFMT_SHOW_IDS)
av_log(NULL, AV_LOG_INFO, "[0x%x]", st->id);
if (strlen(st->language) > 0)
av_log(NULL, AV_LOG_INFO, "(%s)", st->language);
av_log(NULL, AV_LOG_DEBUG, ", %d/%d", st->time_base.num/g, st->time_base.den/g);
av_log(NULL, AV_LOG_INFO, ": %s", buf);
if(st->codec->codec_type == CODEC_TYPE_VIDEO){
if(st->r_frame_rate.den && st->r_frame_rate.num)
av_log(NULL, AV_LOG_INFO, ", %5.2f tb(r)", av_q2d(st->r_frame_rate));
Nico Sabbi
committed
/* else if(st->time_base.den && st->time_base.num)
av_log(NULL, AV_LOG_INFO, ", %5.2f tb(m)", 1/av_q2d(st->time_base));*/
Nico Sabbi
committed
else
av_log(NULL, AV_LOG_INFO, ", %5.2f tb(c)", 1/av_q2d(st->codec->time_base));
Nico Sabbi
committed
}
av_log(NULL, AV_LOG_INFO, "\n");
}
av_log(NULL, AV_LOG_INFO, "%s #%d, %s, %s '%s':\n",
index,
is_output ? ic->oformat->name : ic->iformat->name,
Fabrice Bellard
committed
if (!is_output) {
av_log(NULL, AV_LOG_INFO, " Duration: ");
Fabrice Bellard
committed
if (ic->duration != AV_NOPTS_VALUE) {
int hours, mins, secs, us;
secs = ic->duration / AV_TIME_BASE;
us = ic->duration % AV_TIME_BASE;
mins = secs / 60;
secs %= 60;
hours = mins / 60;
mins %= 60;
av_log(NULL, AV_LOG_INFO, "%02d:%02d:%02d.%01d", hours, mins, secs,
Fabrice Bellard
committed
(10 * us) / AV_TIME_BASE);
} else {
av_log(NULL, AV_LOG_INFO, "N/A");
Fabrice Bellard
committed
}
Wolfram Gloger
committed
if (ic->start_time != AV_NOPTS_VALUE) {
int secs, us;
av_log(NULL, AV_LOG_INFO, ", start: ");
Wolfram Gloger
committed
secs = ic->start_time / AV_TIME_BASE;
us = ic->start_time % AV_TIME_BASE;
av_log(NULL, AV_LOG_INFO, "%d.%06d",
Wolfram Gloger
committed
secs, (int)av_rescale(us, 1000000, AV_TIME_BASE));
}
av_log(NULL, AV_LOG_INFO, ", bitrate: ");
Fabrice Bellard
committed
if (ic->bit_rate) {
av_log(NULL, AV_LOG_INFO,"%d kb/s", ic->bit_rate / 1000);
Fabrice Bellard
committed
} else {
av_log(NULL, AV_LOG_INFO, "N/A");
Fabrice Bellard
committed
}
av_log(NULL, AV_LOG_INFO, "\n");
Fabrice Bellard
committed
}
if(ic->nb_programs) {
int j, k;
for(j=0; j<ic->nb_programs; j++) {
av_log(NULL, AV_LOG_INFO, " Program %d %s\n", ic->programs[j]->id,
ic->programs[j]->name ? ic->programs[j]->name : "");
for(k=0; k<ic->programs[j]->nb_stream_indexes; k++)
Baptiste Coudurier
committed
dump_stream_format(ic, ic->programs[j]->stream_index[k], index, is_output);
}
} else
Nico Sabbi
committed
for(i=0;i<ic->nb_streams;i++)
Baptiste Coudurier
committed
dump_stream_format(ic, i, index, is_output);
}
int parse_image_size(int *width_ptr, int *height_ptr, const char *str)
{
Stefano Sabatini
committed
return av_parse_video_frame_size(width_ptr, height_ptr, str);
Stefano Sabatini
committed
int parse_frame_rate(int *frame_rate_num, int *frame_rate_den, const char *arg)
Stefano Sabatini
committed
AVRational frame_rate;
int ret = av_parse_video_frame_rate(&frame_rate, arg);
*frame_rate_num= frame_rate.num;
*frame_rate_den= frame_rate.den;
return ret;
/**
* gets the current time in micro seconds.
*/
int64_t av_gettime(void)
{
struct timeval tv;
gettimeofday(&tv,NULL);
return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
}
int64_t parse_date(const char *datestr, int duration)
Philip Gladstone
committed
struct tm dt;
Philip Gladstone
committed
int i;
static const char *date_fmt[] = {
"%Y-%m-%d",
"%Y%m%d",
};
static const char *time_fmt[] = {
"%H:%M:%S",
"%H%M%S",
};
const char *q;
Philip Gladstone
committed
char lastch;
#undef time
Philip Gladstone
committed
time_t now = time(0);
len = strlen(datestr);
if (len > 0)
lastch = datestr[len - 1];
else
lastch = '\0';
Philip Gladstone
committed
is_utc = (lastch == 'z' || lastch == 'Z');
Philip Gladstone
committed
memset(&dt, 0, sizeof(dt));
/* parse the year-month-day part */
Philip Gladstone
committed
for (i = 0; i < sizeof(date_fmt) / sizeof(date_fmt[0]); i++) {
Fabrice Bellard
committed
q = small_strptime(p, date_fmt[i], &dt);
Philip Gladstone
committed
if (q) {
break;
}
}
/* if the year-month-day part is missing, then take the
* current year-month-day time */
Philip Gladstone
committed
if (!q) {
if (is_utc) {
dt = *gmtime(&now);
} else {
dt = *localtime(&now);
}
dt.tm_hour = dt.tm_min = dt.tm_sec = 0;
Philip Gladstone
committed
p = q;
Philip Gladstone
committed
if (*p == 'T' || *p == 't' || *p == ' ')
p++;
/* parse the hour-minute-second part */
for (i = 0; i < sizeof(time_fmt) / sizeof(time_fmt[0]); i++) {
Fabrice Bellard
committed
q = small_strptime(p, time_fmt[i], &dt);
if (q) {
break;
}
}
} else {
/* parse datestr as a duration */
if (p[0] == '-') {
negative = 1;
++p;
}
/* parse datestr as HH:MM:SS */
Fabrice Bellard
committed
q = small_strptime(p, time_fmt[0], &dt);
/* parse datestr as S+ */
if (q == p)
/* the parsing didn't succeed */
return INT64_MIN;
Philip Gladstone
committed
}
}
/* Now we have all the fields that we can get */
if (!q) {
return INT64_MIN;
Philip Gladstone
committed
if (duration) {
Philip Gladstone
committed
t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
Philip Gladstone
committed
} else {
Philip Gladstone
committed
dt.tm_isdst = -1; /* unknown */
if (is_utc) {
t = mktimegm(&dt);
} else {
t = mktime(&dt);
}
Philip Gladstone
committed
Philip Gladstone
committed
t *= 1000000;
/* parse the .m... part */
Philip Gladstone
committed
if (*q == '.') {
Philip Gladstone
committed
q++;
for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
Philip Gladstone
committed
break;
val += n * (*q - '0');
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
}
int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
{
const char *p;
char tag[128], *q;
p = info;
if (*p == '?')
p++;
for(;;) {
q = tag;
while (*p != '\0' && *p != '=' && *p != '&') {
if ((q - tag) < sizeof(tag) - 1)
*q++ = *p;
p++;
}
*q = '\0';
q = arg;
if (*p == '=') {
p++;
while (*p != '&' && *p != '\0') {
Philip Gladstone
committed
if ((q - arg) < arg_size - 1) {
if (*p == '+')
*q++ = ' ';
else
*q++ = *p;
}
Michel Bardiaux
committed
int av_get_frame_filename(char *buf, int buf_size,
const char *path, int number)
Panagiotis Issaris
committed
char *q, buf1[20], c;
int nd, len, percentd_found;
q = buf;
p = path;
percentd_found = 0;
for(;;) {
c = *p++;
if (c == '\0')
break;
if (c == '%') {
Philip Gladstone
committed
do {
nd = 0;
while (isdigit(*p)) {
nd = nd * 10 + *p++ - '0';
}
c = *p++;
} while (isdigit(c));
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
switch(c) {
case '%':
goto addchar;
case 'd':
if (percentd_found)
goto fail;
percentd_found = 1;
snprintf(buf1, sizeof(buf1), "%0*d", nd, number);
len = strlen(buf1);
if ((q - buf + len) > buf_size - 1)
goto fail;
memcpy(q, buf1, len);
q += len;
break;
default:
goto fail;
}
} else {
addchar:
if ((q - buf) < buf_size - 1)
*q++ = c;
}
}
if (!percentd_found)
goto fail;
*q = '\0';
return 0;
fail:
*q = '\0';
return -1;
}
Panagiotis Issaris
committed
static void hex_dump_internal(void *avcl, FILE *f, int level, uint8_t *buf, int size)
Fabrice Bellard
committed
{
int len, i, j, c;
Panagiotis Issaris
committed
#define PRINT(...) do { if (!f) av_log(avcl, level, __VA_ARGS__); else fprintf(f, __VA_ARGS__); } while(0)
Fabrice Bellard
committed
for(i=0;i<size;i+=16) {
len = size - i;
if (len > 16)
len = 16;
Panagiotis Issaris
committed
PRINT("%08x ", i);
Fabrice Bellard
committed
for(j=0;j<16;j++) {
if (j < len)
Panagiotis Issaris
committed
PRINT(" %02x", buf[i+j]);
Fabrice Bellard
committed
else
Panagiotis Issaris
committed
PRINT(" ");
Fabrice Bellard
committed
}
Panagiotis Issaris
committed
PRINT(" ");
Fabrice Bellard
committed
for(j=0;j<len;j++) {
c = buf[i+j];
if (c < ' ' || c > '~')
c = '.';
Panagiotis Issaris
committed
PRINT("%c", c);
Fabrice Bellard
committed
}
Panagiotis Issaris
committed
PRINT("\n");
Fabrice Bellard
committed
}
Panagiotis Issaris
committed
#undef PRINT
}
void av_hex_dump(FILE *f, uint8_t *buf, int size)
{
hex_dump_internal(NULL, f, 0, buf, size);
}
void av_hex_dump_log(void *avcl, int level, uint8_t *buf, int size)
{
hex_dump_internal(avcl, NULL, level, buf, size);
Fabrice Bellard
committed
}
Panagiotis Issaris
committed
static void pkt_dump_internal(void *avcl, FILE *f, int level, AVPacket *pkt, int dump_payload)
Panagiotis Issaris
committed
#define PRINT(...) do { if (!f) av_log(avcl, level, __VA_ARGS__); else fprintf(f, __VA_ARGS__); } while(0)
PRINT("stream #%d:\n", pkt->stream_index);
PRINT(" keyframe=%d\n", ((pkt->flags & PKT_FLAG_KEY) != 0));
PRINT(" duration=%0.3f\n", (double)pkt->duration / AV_TIME_BASE);
/* DTS is _always_ valid after av_read_frame() */
Panagiotis Issaris
committed
PRINT(" dts=");
if (pkt->dts == AV_NOPTS_VALUE)
Panagiotis Issaris
committed
PRINT("N/A");
Panagiotis Issaris
committed
PRINT("%0.3f", (double)pkt->dts / AV_TIME_BASE);
/* PTS may be not known if B frames are present */
Panagiotis Issaris
committed
PRINT(" pts=");
if (pkt->pts == AV_NOPTS_VALUE)
Panagiotis Issaris
committed
PRINT("N/A");
Panagiotis Issaris
committed
PRINT("%0.3f", (double)pkt->pts / AV_TIME_BASE);
PRINT("\n");
PRINT(" size=%d\n", pkt->size);
#undef PRINT
if (dump_payload)
av_hex_dump(f, pkt->data, pkt->size);
}
Panagiotis Issaris
committed
void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload)
{
pkt_dump_internal(NULL, f, 0, pkt, dump_payload);
}
void av_pkt_dump_log(void *avcl, int level, AVPacket *pkt, int dump_payload)
{
pkt_dump_internal(avcl, NULL, level, pkt, dump_payload);
}
Petr Doubek
committed
char *authorization, int authorization_size,
char *hostname, int hostname_size,
int *port_ptr,
char *path, int path_size,
const char *url)
{
Ronald S. Bultje
committed
const char *p, *ls, *at, *col, *brk, *q;
if (port_ptr) *port_ptr = -1;
if (proto_size > 0) proto[0] = 0;
if (authorization_size > 0) authorization[0] = 0;
if (hostname_size > 0) hostname[0] = 0;
if (path_size > 0) path[0] = 0;
/* parse protocol */
if ((p = strchr(url, ':'))) {
av_strlcpy(proto, url, FFMIN(proto_size, p + 1 - url));
p++; /* skip ':' */
if (*p == '/') p++;
if (*p == '/') p++;
/* no protocol means plain filename */
av_strlcpy(path, url, path_size);
return;
}
Petr Doubek
committed
/* separate path from hostname */
Ronald S. Bultje
committed
if ((ls = strchr(p, '/'))) {
if ((q = strchr(ls, '?')))
av_strlcpy(path, ls, FFMIN(path_size, q - ls + 1));
else
av_strlcpy(path, ls, path_size);
} else if (!(ls = strchr(p, '?')))
ls = &p[strlen(p)]; // XXX
/* the rest is hostname, use that to parse auth/port */
if (ls != p) {
/* authorization (user[:pass]@hostname) */
if ((at = strchr(p, '@')) && at < ls) {
av_strlcpy(authorization, p,
FFMIN(authorization_size, at + 1 - p));
p = at + 1; /* skip '@' */
if (*p == '[' && (brk = strchr(p, ']')) && brk < ls) {
/* [host]:port */
av_strlcpy(hostname, p + 1,
FFMIN(hostname_size, brk - p));
if (brk[1] == ':' && port_ptr)
*port_ptr = atoi(brk + 2);
} else if ((col = strchr(p, ':')) && col < ls) {
av_strlcpy(hostname, p,
FFMIN(col + 1 - p, hostname_size));
if (port_ptr) *port_ptr = atoi(col + 1);
} else
av_strlcpy(hostname, p,
FFMIN(ls + 1 - p, hostname_size));
void av_set_pts_info(AVStream *s, int pts_wrap_bits,
int pts_num, int pts_den)
{
s->pts_wrap_bits = pts_wrap_bits;
s->time_base.num = pts_num;
s->time_base.den = pts_den;
}
/* fraction handling */
/**
Daniel Kristjansson
committed
* f = val + (num / den) + 0.5.
*
* 'num' is normalized so that it is such as 0 <= num < den.
*
* @param f fractional number
* @param val integer value
* @param num must be >= 0
static void av_frac_init(AVFrac *f, int64_t val, int64_t num, int64_t den)
{
num += (den >> 1);
if (num >= den) {
val += num / den;
num = num % den;
}
f->val = val;
f->num = num;
f->den = den;
}
/**
Daniel Kristjansson
committed
* Fractionnal addition to f: f = f + (incr / f->den).
*
* @param f fractional number
* @param incr increment, can be positive or negative
*/
static void av_frac_add(AVFrac *f, int64_t incr)