/*
- * various utility functions for use within FFmpeg
+ * various utility functions for use within Libav
* Copyright (c) 2000, 2001, 2002 Fabrice Bellard
*
- * This file is part of FFmpeg.
+ * This file is part of Libav.
*
- * FFmpeg is free software; you can redistribute it and/or
+ * Libav 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,
+ * Libav 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
+ * License along with Libav; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
+
+/* #define DEBUG */
+
#include "avformat.h"
+#include "avio_internal.h"
#include "internal.h"
#include "libavcodec/internal.h"
#include "libavutil/opt.h"
#include "libavutil/avstring.h"
#include "riff.h"
#include "audiointerleave.h"
+#include "url.h"
#include <sys/time.h>
#include <time.h>
#include <strings.h>
/**
* @file
- * various utility functions for use within FFmpeg
+ * various utility functions for use within Libav
*/
unsigned avformat_version(void)
const char *avformat_configuration(void)
{
- return FFMPEG_CONFIGURATION;
+ return LIBAV_CONFIGURATION;
}
const char *avformat_license(void)
{
#define LICENSE_PREFIX "libavformat license: "
- return LICENSE_PREFIX FFMPEG_LICENSE + sizeof(LICENSE_PREFIX) - 1;
+ return LICENSE_PREFIX LIBAV_LICENSE + sizeof(LICENSE_PREFIX) - 1;
}
/* fraction handling */
#if CONFIG_IMAGE2_MUXER
if (!short_name && filename &&
av_filename_number_test(filename) &&
- av_guess_image2_codec(filename) != CODEC_ID_NONE) {
+ ff_guess_image2_codec(filename) != CODEC_ID_NONE) {
return av_guess_format("image2", NULL, NULL);
}
#endif
#if CONFIG_IMAGE2_MUXER
if(!strcmp(fmt->name, "image2") || !strcmp(fmt->name, "image2pipe")){
- codec_id= av_guess_image2_codec(filename);
+ codec_id= ff_guess_image2_codec(filename);
}
#endif
if(codec_id == CODEC_ID_NONE)
}
#endif
-int av_get_packet(ByteIOContext *s, AVPacket *pkt, int size)
+int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
{
int ret= av_new_packet(pkt, size);
if(ret<0)
return ret;
- pkt->pos= url_ftell(s);
+ pkt->pos= avio_tell(s);
- ret= get_buffer(s, pkt->data, size);
+ ret= avio_read(s, pkt->data, size);
if(ret<=0)
av_free_packet(pkt);
else
return ret;
}
-int av_append_packet(ByteIOContext *s, AVPacket *pkt, int size)
+int av_append_packet(AVIOContext *s, AVPacket *pkt, int size)
{
int ret;
int old_size;
ret = av_grow_packet(pkt, size);
if (ret < 0)
return ret;
- ret = get_buffer(s, pkt->data + old_size, size);
+ ret = avio_read(s, pkt->data + old_size, size);
av_shrink_packet(pkt, old_size + FFMAX(ret, 0));
return ret;
}
{
AVProbeData lpd = *pd;
AVInputFormat *fmt1 = NULL, *fmt;
- int score;
+ int score, id3 = 0;
if (lpd.buf_size > 10 && ff_id3v2_match(lpd.buf, ID3v2_DEFAULT_MAGIC)) {
int id3len = ff_id3v2_tag_len(lpd.buf);
lpd.buf += id3len;
lpd.buf_size -= id3len;
}
+ id3 = 1;
}
fmt = NULL;
}else if (score == *score_max)
fmt = NULL;
}
+
+ /* a hack for files with huge id3v2 tags -- try to guess by file extension. */
+ if (!fmt && id3 && *score_max < AVPROBE_SCORE_MAX/4) {
+ while ((fmt = av_iformat_next(fmt)))
+ if (fmt->extensions && av_match_ext(lpd.filename, fmt->extensions)) {
+ *score_max = AVPROBE_SCORE_MAX/4;
+ break;
+ }
+ }
+
return fmt;
}
* Open a media file from an IO stream. 'fmt' must be specified.
*/
int av_open_input_stream(AVFormatContext **ic_ptr,
- ByteIOContext *pb, const char *filename,
+ AVIOContext *pb, const char *filename,
AVInputFormat *fmt, AVFormatParameters *ap)
{
int err;
ic->priv_data = NULL;
}
- // e.g. AVFMT_NOFILE formats will not have a ByteIOContext
+ // e.g. AVFMT_NOFILE formats will not have a AVIOContext
if (ic->pb)
ff_id3v2_read(ic, ID3v2_DEFAULT_MAGIC);
}
if (pb && !ic->data_offset)
- ic->data_offset = url_ftell(ic->pb);
+ ic->data_offset = avio_tell(ic->pb);
#if FF_API_OLD_METADATA
ff_metadata_demux_compat(ic);
#define PROBE_BUF_MIN 2048
#define PROBE_BUF_MAX (1<<20)
-int av_probe_input_buffer(ByteIOContext *pb, AVInputFormat **fmt,
+int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt,
const char *filename, void *logctx,
unsigned int offset, unsigned int max_probe_size)
{
/* read probe data */
buf = av_realloc(buf, probe_size + AVPROBE_PADDING_SIZE);
- if ((ret = get_buffer(pb, buf + buf_offset, probe_size - buf_offset)) < 0) {
+ if ((ret = avio_read(pb, buf + buf_offset, probe_size - buf_offset)) < 0) {
/* fail if error was not end of file, otherwise, lower score */
if (ret != AVERROR_EOF) {
av_free(buf);
}
/* rewind. reuse probe buffer to avoid seeking */
- if ((ret = ff_rewind_with_probe_data(pb, buf, pd.buf_size)) < 0)
+ if ((ret = ffio_rewind_with_probe_data(pb, buf, pd.buf_size)) < 0)
av_free(buf);
return ret;
{
int err;
AVProbeData probe_data, *pd = &probe_data;
- ByteIOContext *pb = NULL;
+ AVIOContext *pb = NULL;
void *logctx= ap && ap->prealloced_context ? *ic_ptr : NULL;
pd->filename = "";
hack needed to handle RTSP/TCP */
if (!fmt || !(fmt->flags & AVFMT_NOFILE)) {
/* if no file needed do not try to open one */
- if ((err=url_fopen(&pb, filename, URL_RDONLY)) < 0) {
+ if ((err=avio_open(&pb, filename, AVIO_RDONLY)) < 0) {
goto fail;
}
if (buf_size > 0) {
- url_setbufsize(pb, buf_size);
+ ffio_set_buf_size(pb, buf_size);
}
if (!fmt && (err = av_probe_input_buffer(pb, &fmt, filename, logctx, 0, logctx ? (*ic_ptr)->probesize : 0)) < 0) {
goto fail;
fail:
av_freep(&pd->buf);
if (pb)
- url_fclose(pb);
+ avio_close(pb);
if (ap && ap->prealloced_context)
av_free(*ic_ptr);
*ic_ptr = NULL;
return -1;
/* do the seek */
- if ((ret = url_fseek(s->pb, pos, SEEK_SET)) < 0)
+ if ((ret = avio_seek(s->pb, pos, SEEK_SET)) < 0)
return ret;
av_update_cur_dts(s, st, ts);
if(ts_max == AV_NOPTS_VALUE){
int step= 1024;
- filesize = url_fsize(s->pb);
+ filesize = avio_size(s->pb);
pos_max = filesize - 1;
do{
pos_max -= step;
#endif
pos_min = s->data_offset;
- pos_max = url_fsize(s->pb) - 1;
+ pos_max = avio_size(s->pb) - 1;
if (pos < pos_min) pos= pos_min;
else if(pos > pos_max) pos= pos_max;
- url_fseek(s->pb, pos, SEEK_SET);
+ avio_seek(s->pb, pos, SEEK_SET);
#if 0
av_update_cur_dts(s, st, ts);
if(st->nb_index_entries){
assert(st->index_entries);
ie= &st->index_entries[st->nb_index_entries-1];
- if ((ret = url_fseek(s->pb, ie->pos, SEEK_SET)) < 0)
+ if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0)
return ret;
av_update_cur_dts(s, st, ie->timestamp);
}else{
- if ((ret = url_fseek(s->pb, s->data_offset, SEEK_SET)) < 0)
+ if ((ret = avio_seek(s->pb, s->data_offset, SEEK_SET)) < 0)
return ret;
}
for(i=0;; i++) {
return 0;
}
ie = &st->index_entries[index];
- if ((ret = url_fseek(s->pb, ie->pos, SEEK_SET)) < 0)
+ if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0)
return ret;
av_update_cur_dts(s, st, ie->timestamp);
if (offset < 0)
offset = 0;
- url_fseek(ic->pb, offset, SEEK_SET);
+ avio_seek(ic->pb, offset, SEEK_SET);
read_size = 0;
for(;;) {
if (read_size >= DURATION_MAX_READ_SIZE<<(FFMAX(retry-1,0)))
fill_all_stream_timings(ic);
- url_fseek(ic->pb, old_offset, SEEK_SET);
+ avio_seek(ic->pb, old_offset, SEEK_SET);
for (i=0; i<ic->nb_streams; i++) {
st= ic->streams[i];
st->cur_dts= st->first_dts;
if (ic->iformat->flags & AVFMT_NOFILE) {
file_size = 0;
} else {
- file_size = url_fsize(ic->pb);
+ file_size = avio_size(ic->pb);
if (file_size < 0)
file_size = 0;
}
if ((!strcmp(ic->iformat->name, "mpeg") ||
!strcmp(ic->iformat->name, "mpegts")) &&
- file_size && !url_is_streamed(ic->pb)) {
+ file_size && ic->pb->seekable) {
/* get accurate estimate from the PTSes */
av_estimate_timings_from_pts(ic, old_offset);
} else if (av_has_duration(ic)) {
static void compute_chapters_end(AVFormatContext *s)
{
- unsigned int i;
+ unsigned int i, j;
+ int64_t max_time = s->duration + (s->start_time == AV_NOPTS_VALUE) ? 0 : s->start_time;
- for (i=0; i+1<s->nb_chapters; i++)
+ for (i = 0; i < s->nb_chapters; i++)
if (s->chapters[i]->end == AV_NOPTS_VALUE) {
- assert(s->chapters[i]->start <= s->chapters[i+1]->start);
- assert(!av_cmp_q(s->chapters[i]->time_base, s->chapters[i+1]->time_base));
- s->chapters[i]->end = s->chapters[i+1]->start;
+ AVChapter *ch = s->chapters[i];
+ int64_t end = max_time ? av_rescale_q(max_time, AV_TIME_BASE_Q, ch->time_base)
+ : INT64_MAX;
+
+ for (j = 0; j < s->nb_chapters; j++) {
+ AVChapter *ch1 = s->chapters[j];
+ int64_t next_start = av_rescale_q(ch1->start, ch1->time_base, ch->time_base);
+ if (j != i && next_start > ch->start && next_start < end)
+ end = next_start;
+ }
+ ch->end = (end == INT64_MAX) ? ch->start : end;
}
-
- if (s->nb_chapters && s->chapters[i]->end == AV_NOPTS_VALUE) {
- assert(s->start_time != AV_NOPTS_VALUE);
- assert(s->duration > 0);
- s->chapters[i]->end = av_rescale_q(s->start_time + s->duration,
- AV_TIME_BASE_Q,
- s->chapters[i]->time_base);
- }
}
static int get_std_framerate(int i){
int i, count, ret, read_size, j;
AVStream *st;
AVPacket pkt1, *pkt;
- int64_t old_offset = url_ftell(ic->pb);
+ int64_t old_offset = avio_tell(ic->pb);
for(i=0;i<ic->nb_streams;i++) {
AVCodec *codec;
read_size = 0;
for(;;) {
if(url_interrupt_cb()){
- ret= AVERROR(EINTR);
+ ret= AVERROR_EXIT;
av_log(ic, AV_LOG_DEBUG, "interrupted\n");
break;
}
}else if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
if(!st->codec->bits_per_coded_sample)
st->codec->bits_per_coded_sample= av_get_bits_per_sample(st->codec->codec_id);
+ // set stream disposition based on audio service type
+ switch (st->codec->audio_service_type) {
+ case AV_AUDIO_SERVICE_TYPE_EFFECTS:
+ st->disposition = AV_DISPOSITION_CLEAN_EFFECTS; break;
+ case AV_AUDIO_SERVICE_TYPE_VISUALLY_IMPAIRED:
+ st->disposition = AV_DISPOSITION_VISUAL_IMPAIRED; break;
+ case AV_AUDIO_SERVICE_TYPE_HEARING_IMPAIRED:
+ st->disposition = AV_DISPOSITION_HEARING_IMPAIRED; break;
+ case AV_AUDIO_SERVICE_TYPE_COMMENTARY:
+ st->disposition = AV_DISPOSITION_COMMENT; break;
+ case AV_AUDIO_SERVICE_TYPE_KARAOKE:
+ st->disposition = AV_DISPOSITION_KARAOKE; break;
+ }
}
}
continue;
if (wanted_stream_nb >= 0 && stream_number++ != wanted_stream_nb)
continue;
+ if (st->disposition & (AV_DISPOSITION_HEARING_IMPAIRED|AV_DISPOSITION_VISUAL_IMPAIRED))
+ continue;
if (decoder_ret) {
decoder = avcodec_find_decoder(ic->streams[i]->codec->codec_id);
if (!decoder) {
if (best_count >= st->codec_info_nb_frames)
continue;
best_count = st->codec_info_nb_frames;
- ret = i;
+ ret = program ? program[i] : i;
best_decoder = decoder;
if (program && i == nb_streams - 1 && ret < 0) {
program = NULL;
if (s->iformat->read_play)
return s->iformat->read_play(s);
if (s->pb)
- return av_url_read_fpause(s->pb, 0);
+ return avio_pause(s->pb, 0);
return AVERROR(ENOSYS);
}
if (s->iformat->read_pause)
return s->iformat->read_pause(s);
if (s->pb)
- return av_url_read_fpause(s->pb, 1);
+ return avio_pause(s->pb, 1);
return AVERROR(ENOSYS);
}
void av_close_input_file(AVFormatContext *s)
{
- ByteIOContext *pb = s->iformat->flags & AVFMT_NOFILE ? NULL : s->pb;
+ AVIOContext *pb = s->iformat->flags & AVFMT_NOFILE ? NULL : s->pb;
av_close_input_stream(s);
if (pb)
- url_fclose(pb);
+ avio_close(pb);
}
AVStream *av_new_stream(AVFormatContext *s, int id)
int delay = FFMAX(st->codec->has_b_frames, !!st->codec->max_b_frames);
int num, den, frame_size, i;
-// av_log(s, 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);
+ av_dlog(s, "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;*/
return ret;
ret= s->oformat->write_packet(s, pkt);
- if(!ret)
- ret= url_ferror(s->pb);
return ret;
}
AVStream *st2= s->streams[ next->stream_index];
int64_t a= st2->time_base.num * (int64_t)st ->time_base.den;
int64_t b= st ->time_base.num * (int64_t)st2->time_base.den;
- return av_rescale_rnd(pkt->dts, b, a, AV_ROUND_DOWN) < next->dts;
+ int64_t dts1 = av_rescale_rnd(pkt->dts, b, a, AV_ROUND_DOWN);
+ if (dts1 == next->dts)
+ return pkt->stream_index < next->stream_index;
+ return dts1 < next->dts;
}
int av_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush){
int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt){
AVStream *st= s->streams[ pkt->stream_index];
+ int ret;
//FIXME/XXX/HACK drop zero sized packets
if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO && pkt->size==0)
return 0;
-//av_log(NULL, AV_LOG_DEBUG, "av_interleaved_write_frame %d %"PRId64" %"PRId64"\n", pkt->size, pkt->dts, pkt->pts);
- if(compute_pkt_fields2(s, st, pkt) < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
- return -1;
+ av_dlog(s, "av_interleaved_write_frame size:%d dts:%"PRId64" pts:%"PRId64"\n",
+ pkt->size, pkt->dts, pkt->pts);
+ if((ret = compute_pkt_fields2(s, st, pkt)) < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
+ return ret;
if(pkt->dts == AV_NOPTS_VALUE && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
- return -1;
+ return AVERROR(EINVAL);
for(;;){
AVPacket opkt;
if(ret<0)
return ret;
- if(url_ferror(s->pb))
- return url_ferror(s->pb);
}
}
if(ret<0)
goto fail;
- if(url_ferror(s->pb))
- goto fail;
}
if(s->oformat->write_trailer)
ret = s->oformat->write_trailer(s);
fail:
- if(ret == 0)
- ret=url_ferror(s->pb);
for(i=0;i<s->nb_streams;i++) {
av_freep(&s->streams[i]->priv_data);
av_freep(&s->streams[i]->index_entries);
if(st->codec->time_base.den && st->codec->time_base.num)
print_fps(1/av_q2d(st->codec->time_base), "tbc");
}
+ if (st->disposition & AV_DISPOSITION_DEFAULT)
+ av_log(NULL, AV_LOG_INFO, " (default)");
+ if (st->disposition & AV_DISPOSITION_DUB)
+ av_log(NULL, AV_LOG_INFO, " (dub)");
+ if (st->disposition & AV_DISPOSITION_ORIGINAL)
+ av_log(NULL, AV_LOG_INFO, " (original)");
+ if (st->disposition & AV_DISPOSITION_COMMENT)
+ av_log(NULL, AV_LOG_INFO, " (comment)");
+ if (st->disposition & AV_DISPOSITION_LYRICS)
+ av_log(NULL, AV_LOG_INFO, " (lyrics)");
+ if (st->disposition & AV_DISPOSITION_KARAOKE)
+ av_log(NULL, AV_LOG_INFO, " (karaoke)");
+ if (st->disposition & AV_DISPOSITION_FORCED)
+ av_log(NULL, AV_LOG_INFO, " (forced)");
+ if (st->disposition & AV_DISPOSITION_HEARING_IMPAIRED)
+ av_log(NULL, AV_LOG_INFO, " (hearing impaired)");
+ if (st->disposition & AV_DISPOSITION_VISUAL_IMPAIRED)
+ av_log(NULL, AV_LOG_INFO, " (visual impaired)");
+ if (st->disposition & AV_DISPOSITION_CLEAN_EFFECTS)
+ av_log(NULL, AV_LOG_INFO, " (clean effects)");
av_log(NULL, AV_LOG_INFO, "\n");
dump_metadata(NULL, st->metadata, " ");
}
+#if FF_API_DUMP_FORMAT
void dump_format(AVFormatContext *ic,
int index,
const char *url,
int is_output)
{
+ av_dump_format(ic, index, url, is_output);
+}
+#endif
+
+void av_dump_format(AVFormatContext *ic,
+ int index,
+ const char *url,
+ int is_output)
+{
int i;
uint8_t *printed = av_mallocz(ic->nb_streams);
if (ic->nb_streams && !printed)
}
#if FF_API_PARSE_FRAME_PARAM
-#include "libavcore/parseutils.h"
+#include "libavutil/parseutils.h"
int parse_image_size(int *width_ptr, int *height_ptr, const char *str)
{
return (av_gettime() / 1000) * 1000 + NTP_OFFSET_US;
}
-int64_t parse_date(const char *datestr, int duration)
-{
- const char *p;
- int64_t t;
- struct tm dt;
- int i;
- static const char * const date_fmt[] = {
- "%Y-%m-%d",
- "%Y%m%d",
- };
- static const char * const time_fmt[] = {
- "%H:%M:%S",
- "%H%M%S",
- };
- const char *q;
- int is_utc, len;
- char lastch;
- int negative = 0;
-
-#undef time
- time_t now = time(0);
-
- len = strlen(datestr);
- if (len > 0)
- lastch = datestr[len - 1];
- else
- lastch = '\0';
- is_utc = (lastch == 'z' || lastch == 'Z');
-
- memset(&dt, 0, sizeof(dt));
-
- p = datestr;
- q = NULL;
- if (!duration) {
- if (!strncasecmp(datestr, "now", len))
- return (int64_t) now * 1000000;
-
- /* parse the year-month-day part */
- for (i = 0; i < FF_ARRAY_ELEMS(date_fmt); i++) {
- q = small_strptime(p, date_fmt[i], &dt);
- if (q) {
- break;
- }
- }
-
- /* if the year-month-day part is missing, then take the
- * current year-month-day time */
- if (!q) {
- if (is_utc) {
- dt = *gmtime(&now);
- } else {
- dt = *localtime(&now);
- }
- dt.tm_hour = dt.tm_min = dt.tm_sec = 0;
- } else {
- p = q;
- }
-
- if (*p == 'T' || *p == 't' || *p == ' ')
- p++;
-
- /* parse the hour-minute-second part */
- for (i = 0; i < FF_ARRAY_ELEMS(time_fmt); i++) {
- 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 */
- q = small_strptime(p, time_fmt[0], &dt);
- if (!q) {
- /* parse datestr as S+ */
- dt.tm_sec = strtol(p, (char **)&q, 10);
- if (q == p)
- /* the parsing didn't succeed */
- return INT64_MIN;
- dt.tm_min = 0;
- dt.tm_hour = 0;
- }
- }
-
- /* Now we have all the fields that we can get */
- if (!q) {
- return INT64_MIN;
- }
+#if FF_API_PARSE_DATE
+#include "libavutil/parseutils.h"
- if (duration) {
- t = dt.tm_hour * 3600 + dt.tm_min * 60 + dt.tm_sec;
- } else {
- dt.tm_isdst = -1; /* unknown */
- if (is_utc) {
- t = mktimegm(&dt);
- } else {
- t = mktime(&dt);
- }
- }
-
- t *= 1000000;
-
- /* parse the .m... part */
- if (*q == '.') {
- int val, n;
- q++;
- for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
- if (!isdigit(*q))
- break;
- val += n * (*q - '0');
- }
- t += val;
- }
- return negative ? -t : t;
+int64_t parse_date(const char *timestr, int duration)
+{
+ int64_t timeval;
+ av_parse_time(&timeval, timestr, duration);
+ return timeval;
}
+#endif
+
+#if FF_API_FIND_INFO_TAG
+#include "libavutil/parseutils.h"
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') {
- if ((q - arg) < arg_size - 1) {
- if (*p == '+')
- *q++ = ' ';
- else
- *q++ = *p;
- }
- p++;
- }
- }
- *q = '\0';
- if (!strcmp(tag, tag1))
- return 1;
- if (*p != '&')
- break;
- p++;
- }
- return 0;
+ return av_find_info_tag(arg, arg_size, tag1, info);
}
+#endif
int av_get_frame_filename(char *buf, int buf_size,
const char *path, int number)
hex_dump_internal(avcl, NULL, level, buf, size);
}
- //FIXME needs to know the time_base
-static void pkt_dump_internal(void *avcl, FILE *f, int level, AVPacket *pkt, int dump_payload)
+static void pkt_dump_internal(void *avcl, FILE *f, int level, AVPacket *pkt, int dump_payload, AVRational time_base)
{
#undef fprintf
#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 & AV_PKT_FLAG_KEY) != 0));
- PRINT(" duration=%0.3f\n", (double)pkt->duration / AV_TIME_BASE);
+ PRINT(" duration=%0.3f\n", pkt->duration * av_q2d(time_base));
/* DTS is _always_ valid after av_read_frame() */
PRINT(" dts=");
if (pkt->dts == AV_NOPTS_VALUE)
PRINT("N/A");
else
- PRINT("%0.3f", (double)pkt->dts / AV_TIME_BASE);
+ PRINT("%0.3f", pkt->dts * av_q2d(time_base));
/* PTS may not be known if B-frames are present. */
PRINT(" pts=");
if (pkt->pts == AV_NOPTS_VALUE)
PRINT("N/A");
else
- PRINT("%0.3f", (double)pkt->pts / AV_TIME_BASE);
+ PRINT("%0.3f", pkt->pts * av_q2d(time_base));
PRINT("\n");
PRINT(" size=%d\n", pkt->size);
#undef PRINT
av_hex_dump(f, pkt->data, pkt->size);
}
+#if FF_API_PKT_DUMP
void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload)
{
- pkt_dump_internal(NULL, f, 0, pkt, dump_payload);
+ AVRational tb = { 1, AV_TIME_BASE };
+ pkt_dump_internal(NULL, f, 0, pkt, dump_payload, tb);
}
+#endif
+void av_pkt_dump2(FILE *f, AVPacket *pkt, int dump_payload, AVStream *st)
+{
+ pkt_dump_internal(NULL, f, 0, pkt, dump_payload, st->time_base);
+}
+
+#if FF_API_PKT_DUMP
void av_pkt_dump_log(void *avcl, int level, AVPacket *pkt, int dump_payload)
{
- pkt_dump_internal(avcl, NULL, level, pkt, dump_payload);
+ AVRational tb = { 1, AV_TIME_BASE };
+ pkt_dump_internal(avcl, NULL, level, pkt, dump_payload, tb);
+}
+#endif
+
+void av_pkt_dump_log2(void *avcl, int level, AVPacket *pkt, int dump_payload,
+ AVStream *st)
+{
+ pkt_dump_internal(avcl, NULL, level, pkt, dump_payload, st->time_base);
}
#if FF_API_URL_SPLIT
}
return -1;
}
+
+void ff_make_absolute_url(char *buf, int size, const char *base,
+ const char *rel)
+{
+ char *sep;
+ /* Absolute path, relative to the current server */
+ if (base && strstr(base, "://") && rel[0] == '/') {
+ if (base != buf)
+ av_strlcpy(buf, base, size);
+ sep = strstr(buf, "://");
+ if (sep) {
+ sep += 3;
+ sep = strchr(sep, '/');
+ if (sep)
+ *sep = '\0';
+ }
+ av_strlcat(buf, rel, size);
+ return;
+ }
+ /* If rel actually is an absolute url, just copy it */
+ if (!base || strstr(rel, "://") || rel[0] == '/') {
+ av_strlcpy(buf, rel, size);
+ return;
+ }
+ if (base != buf)
+ av_strlcpy(buf, base, size);
+ /* Remove the file name from the base url */
+ sep = strrchr(buf, '/');
+ if (sep)
+ sep[1] = '\0';
+ else
+ buf[0] = '\0';
+ while (av_strstart(rel, "../", NULL) && sep) {
+ /* Remove the path delimiter at the end */
+ sep[0] = '\0';
+ sep = strrchr(buf, '/');
+ /* If the next directory name to pop off is "..", break here */
+ if (!strcmp(sep ? &sep[1] : buf, "..")) {
+ /* Readd the slash we just removed */
+ av_strlcat(buf, "/", size);
+ break;
+ }
+ /* Cut off the directory name */
+ if (sep)
+ sep[1] = '\0';
+ else
+ buf[0] = '\0';
+ rel += 3;
+ }
+ av_strlcat(buf, rel, size);
+}