#include "libavutil/pixdesc.h"
#include "metadata.h"
#include "id3v2.h"
+#include "libavutil/avassert.h"
#include "libavutil/avstring.h"
#include "libavutil/mathematics.h"
#include "libavutil/parseutils.h"
/************************************************************/
/* input media file */
-#if FF_API_FORMAT_PARAMETERS
-static AVDictionary *convert_format_parameters(AVFormatParameters *ap)
-{
- char buf[1024];
- AVDictionary *opts = NULL;
-
- if (!ap)
- return NULL;
-
- AV_NOWARN_DEPRECATED(
- if (ap->time_base.num) {
- snprintf(buf, sizeof(buf), "%d/%d", ap->time_base.den, ap->time_base.num);
- av_dict_set(&opts, "framerate", buf, 0);
- }
- if (ap->sample_rate) {
- snprintf(buf, sizeof(buf), "%d", ap->sample_rate);
- av_dict_set(&opts, "sample_rate", buf, 0);
- }
- if (ap->channels) {
- snprintf(buf, sizeof(buf), "%d", ap->channels);
- av_dict_set(&opts, "channels", buf, 0);
- }
- if (ap->width || ap->height) {
- snprintf(buf, sizeof(buf), "%dx%d", ap->width, ap->height);
- av_dict_set(&opts, "video_size", buf, 0);
- }
- if (ap->pix_fmt != PIX_FMT_NONE) {
- av_dict_set(&opts, "pixel_format", av_get_pix_fmt_name(ap->pix_fmt), 0);
- }
- if (ap->channel) {
- snprintf(buf, sizeof(buf), "%d", ap->channel);
- av_dict_set(&opts, "channel", buf, 0);
- }
- if (ap->standard) {
- av_dict_set(&opts, "standard", ap->standard, 0);
- }
- if (ap->mpeg2ts_compute_pcr) {
- av_dict_set(&opts, "mpeg2ts_compute_pcr", "1", 0);
- }
- if (ap->initial_pause) {
- av_dict_set(&opts, "initial_pause", "1", 0);
- }
- )
- return opts;
-}
-
-/**
- * Open a media file from an IO stream. 'fmt' must be specified.
- */
-int av_open_input_stream(AVFormatContext **ic_ptr,
- AVIOContext *pb, const char *filename,
- AVInputFormat *fmt, AVFormatParameters *ap)
-{
- int err;
- AVDictionary *opts;
- AVFormatContext *ic;
- AVFormatParameters default_ap;
-
- if(!ap){
- ap=&default_ap;
- memset(ap, 0, sizeof(default_ap));
- }
- opts = convert_format_parameters(ap);
-
- AV_NOWARN_DEPRECATED(
- if(!ap->prealloced_context)
- *ic_ptr = ic = avformat_alloc_context();
- else
- ic = *ic_ptr;
- )
- if (!ic) {
- err = AVERROR(ENOMEM);
- goto fail;
- }
- if (pb && fmt && fmt->flags & AVFMT_NOFILE)
- av_log(ic, AV_LOG_WARNING, "Custom AVIOContext makes no sense and "
- "will be ignored with AVFMT_NOFILE format.\n");
- else
- ic->pb = pb;
-
- 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
-
-fail:
- *ic_ptr = ic;
- av_dict_free(&opts);
- return err;
-}
-#endif
-
-int av_demuxer_open(AVFormatContext *ic, AVFormatParameters *ap){
+int av_demuxer_open(AVFormatContext *ic){
int err;
if (ic->iformat->read_header) {
- err = ic->iformat->read_header(ic, ap);
+ err = ic->iformat->read_header(ic);
if (err < 0)
return err;
}
return ret;
}
-#if FF_API_FORMAT_PARAMETERS
-int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,
- AVInputFormat *fmt,
- int buf_size,
- AVFormatParameters *ap)
-{
- int err;
- AVDictionary *opts = convert_format_parameters(ap);
-
- AV_NOWARN_DEPRECATED(
- if (!ap || !ap->prealloced_context)
- *ic_ptr = NULL;
- )
-
- err = avformat_open_input(ic_ptr, filename, fmt, &opts);
-
- av_dict_free(&opts);
- return err;
-}
-#endif
-
/* open input file and probe the format if necessary */
static int init_input(AVFormatContext *s, const char *filename, AVDictionary **options)
{
int ret;
AVProbeData pd = {filename, NULL, 0};
- if(s->iformat && !strlen(filename))
- return 0;
-
if (s->pb) {
s->flags |= AVFMT_FLAG_CUSTOM_IO;
if (!s->iformat)
{
AVFormatContext *s = *ps;
int ret = 0;
- AVFormatParameters ap = { { 0 } };
AVDictionary *tmp = NULL;
if (!s && !(s = avformat_alloc_context()))
ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC);
if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->iformat->read_header)
- if ((ret = s->iformat->read_header(s, &ap)) < 0)
+ if ((ret = s->iformat->read_header(s)) < 0)
goto fail;
if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->pb && !s->data_offset)
compute_frame_duration(&num, &den, st, pc, pkt);
if (den && num) {
pkt->duration = av_rescale_rnd(1, num * (int64_t)st->time_base.den, den * (int64_t)st->time_base.num, AV_ROUND_DOWN);
-
- if(pkt->duration != 0 && s->packet_buffer)
- update_initial_durations(s, st, pkt);
}
}
+ if(pkt->duration != 0 && s->packet_buffer)
+ update_initial_durations(s, st, pkt);
/* correct timestamps with byte offset if demuxers only have timestamps
on packet boundaries */
if (pkt->size) {
got_packet:
pkt->duration = 0;
+ if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+ if (st->codec->sample_rate > 0) {
+ pkt->duration = av_rescale_q_rnd(st->parser->duration,
+ (AVRational){ 1, st->codec->sample_rate },
+ st->time_base,
+ AV_ROUND_DOWN);
+ }
+ } else if (st->codec->time_base.num != 0 &&
+ st->codec->time_base.den != 0) {
+ pkt->duration = av_rescale_q_rnd(st->parser->duration,
+ st->codec->time_base,
+ st->time_base,
+ AV_ROUND_DOWN);
+ }
pkt->stream_index = st->index;
pkt->pts = st->parser->pts;
pkt->dts = st->parser->dts;
return 0;
}
+static int read_from_packet_buffer(AVFormatContext *s, AVPacket *pkt)
+{
+ AVPacketList *pktl = s->packet_buffer;
+ av_assert0(pktl);
+ *pkt = pktl->pkt;
+ s->packet_buffer = pktl->next;
+ av_freep(&pktl);
+ return 0;
+}
+
int av_read_frame(AVFormatContext *s, AVPacket *pkt)
{
- AVPacketList *pktl;
- int eof=0;
- const int genpts= s->flags & AVFMT_FLAG_GENPTS;
+ const int genpts = s->flags & AVFMT_FLAG_GENPTS;
+ int eof = 0;
+
+ if (!genpts)
+ return s->packet_buffer ? read_from_packet_buffer(s, pkt) :
+ read_frame_internal(s, pkt);
+
+ for (;;) {
+ int ret;
+ AVPacketList *pktl = s->packet_buffer;
- for(;;){
- pktl = s->packet_buffer;
if (pktl) {
- AVPacket *next_pkt= &pktl->pkt;
+ AVPacket *next_pkt = &pktl->pkt;
- if(genpts && next_pkt->dts != AV_NOPTS_VALUE){
+ if (next_pkt->dts != AV_NOPTS_VALUE) {
int wrap_bits = s->streams[next_pkt->stream_index]->pts_wrap_bits;
- while(pktl && next_pkt->pts == AV_NOPTS_VALUE){
- if( pktl->pkt.stream_index == next_pkt->stream_index
- && (0 > av_compare_mod(next_pkt->dts, pktl->pkt.dts, 2LL << (wrap_bits - 1)))
- && av_compare_mod(pktl->pkt.pts, pktl->pkt.dts, 2LL << (wrap_bits - 1))) { //not b frame
- next_pkt->pts= pktl->pkt.dts;
+ while (pktl && next_pkt->pts == AV_NOPTS_VALUE) {
+ if (pktl->pkt.stream_index == next_pkt->stream_index &&
+ (av_compare_mod(next_pkt->dts, pktl->pkt.dts, 2LL << (wrap_bits - 1)) < 0) &&
+ av_compare_mod(pktl->pkt.pts, pktl->pkt.dts, 2LL << (wrap_bits - 1))) { //not b frame
+ next_pkt->pts = pktl->pkt.dts;
}
- pktl= pktl->next;
+ pktl = pktl->next;
}
pktl = s->packet_buffer;
}
- if( next_pkt->pts != AV_NOPTS_VALUE
- || next_pkt->dts == AV_NOPTS_VALUE
- || !genpts || eof){
- /* read packet from packet buffer, if there is data */
- *pkt = *next_pkt;
- s->packet_buffer = pktl->next;
- av_free(pktl);
- return 0;
- }
+ /* read packet from packet buffer, if there is data */
+ if (!(next_pkt->pts == AV_NOPTS_VALUE &&
+ next_pkt->dts != AV_NOPTS_VALUE && !eof))
+ return read_from_packet_buffer(s, pkt);
}
- if(genpts){
- int ret= read_frame_internal(s, pkt);
- if(ret<0){
- if(pktl && ret != AVERROR(EAGAIN)){
- eof=1;
- continue;
- }else
- return ret;
- }
- if(av_dup_packet(add_to_pktbuf(&s->packet_buffer, pkt,
- &s->packet_buffer_end)) < 0)
- return AVERROR(ENOMEM);
- }else{
- assert(!s->packet_buffer);
- return read_frame_internal(s, pkt);
+ ret = read_frame_internal(s, pkt);
+ if (ret < 0) {
+ if (pktl && ret != AVERROR(EAGAIN)) {
+ eof = 1;
+ continue;
+ } else
+ return ret;
}
+
+ if (av_dup_packet(add_to_pktbuf(&s->packet_buffer, pkt,
+ &s->packet_buffer_end)) < 0)
+ return AVERROR(ENOMEM);
}
}
}
}
-#if FF_API_SEEK_PUBLIC
-void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp)
-{
- ff_update_cur_dts(s, ref_st, timestamp);
-}
-#endif
-
void ff_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp)
{
int i;
wanted_timestamp, flags);
}
-#if FF_API_SEEK_PUBLIC
-int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags){
- return ff_seek_frame_binary(s, stream_index, target_ts, flags);
-}
-#endif
-
int ff_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags)
{
AVInputFormat *avif= s->iformat;
return 0;
}
-#if FF_API_SEEK_PUBLIC
-int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts,
- int64_t pos_min, int64_t pos_max, int64_t pos_limit,
- int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret,
- int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t ))
-{
- return ff_gen_search(s, stream_index, target_ts, pos_min, pos_max,
- pos_limit, ts_min, ts_max, flags, ts_ret,
- read_timestamp);
-}
-#endif
-
int64_t ff_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts,
int64_t pos_min, int64_t pos_max, int64_t pos_limit,
int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret,
//Fallback to old API if new is not implemented but old is
//Note the old has somewat different sematics
AV_NOWARN_DEPRECATED(
- if(s->iformat->read_seek || 1)
- return av_seek_frame(s, stream_index, ts, flags | (ts - min_ts > (uint64_t)(max_ts - ts) ? AVSEEK_FLAG_BACKWARD : 0));
+ if (s->iformat->read_seek || 1) {
+ int dir = (ts - min_ts > (uint64_t)(max_ts - ts) ? AVSEEK_FLAG_BACKWARD : 0);
+ int ret = av_seek_frame(s, stream_index, ts, flags | dir);
+ if (ret<0 && ts != min_ts && max_ts != ts) {
+ ret = av_seek_frame(s, stream_index, dir ? max_ts : min_ts, flags | dir);
+ if (ret >= 0)
+ ret = av_seek_frame(s, stream_index, ts, flags | (dir^AVSEEK_FLAG_BACKWARD));
+ }
+ return ret;
+ }
)
// try some generic seek like seek_frame_generic() but with new ts semantics
st->info->nb_decoded_frames >= 6;
}
+/* returns 1 or 0 if or if not decoded data was returned, or a negative error */
static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **options)
{
AVCodec *codec;
- int got_picture, ret = 0;
+ int got_picture = 1, ret = 0;
AVFrame picture;
AVPacket pkt = *avpkt;
- if(!st->codec->codec){
- codec = avcodec_find_decoder(st->codec->codec_id);
+ if (!avcodec_is_open(st->codec)) {
+ AVDictionary *thread_opt = NULL;
+
+ codec = st->codec->codec ? st->codec->codec :
+ avcodec_find_decoder(st->codec->codec_id);
+
if (!codec)
return -1;
- ret = avcodec_open2(st->codec, codec, options);
+
+ /* force thread count to 1 since the h264 decoder will not extract SPS
+ * and PPS to extradata during multi-threaded decoding */
+ av_dict_set(options ? options : &thread_opt, "threads", "1", 0);
+ ret = avcodec_open2(st->codec, codec, options ? options : &thread_opt);
+ if (!options)
+ av_dict_free(&thread_opt);
if (ret < 0)
return ret;
}
- while (pkt.size > 0 && ret >= 0 &&
+ while ((pkt.size > 0 || (!pkt.data && got_picture)) &&
+ ret >= 0 &&
(!has_codec_parameters(st->codec) ||
!has_decode_delay_been_guessed(st) ||
(!st->codec_info_nb_frames && st->codec->codec->capabilities & CODEC_CAP_CHANNEL_CONF))) {
st->info->nb_decoded_frames++;
pkt.data += ret;
pkt.size -= ret;
+ ret = got_picture;
}
}
+ if(!pkt.data && !got_picture)
+ return -1;
return ret;
}
int i, count, ret, read_size, j;
AVStream *st;
AVPacket pkt1, *pkt;
- AVDictionary *one_thread_opt = NULL;
int64_t old_offset = avio_tell(ic->pb);
int orig_nb_streams = ic->nb_streams; // new streams might appear, no options for those
-
- /* this function doesn't flush the decoders, so force thread count
- * to 1 to fix behavior when thread count > number of frames in the file */
- av_dict_set(&one_thread_opt, "threads", "1", 0);
+ int flush_codecs = 1;
for(i=0;i<ic->nb_streams;i++) {
AVCodec *codec;
+ AVDictionary *thread_opt = NULL;
st = ic->streams[i];
if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO ||
st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
}
}
- assert(!st->codec->codec);
- codec = avcodec_find_decoder(st->codec->codec_id);
+ codec = st->codec->codec ? st->codec->codec :
+ avcodec_find_decoder(st->codec->codec_id);
- /* this function doesn't flush the decoders, so force thread count
- * to 1 to fix behavior when thread count > number of frames in the file */
- if (options)
- av_dict_set(&options[i], "threads", "1", 0);
+ /* force thread count to 1 since the h264 decoder will not extract SPS
+ * and PPS to extradata during multi-threaded decoding */
+ av_dict_set(options ? &options[i] : &thread_opt, "threads", "1", 0);
/* Ensure that subtitle_header is properly set. */
if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE
&& codec && !st->codec->codec)
- avcodec_open2(st->codec, codec, options ? &options[i] : &one_thread_opt);
+ avcodec_open2(st->codec, codec, options ? &options[i]
+ : &thread_opt);
//try to just open decoders, in case this is enough to get parameters
if(!has_codec_parameters(st->codec)){
if (codec && !st->codec->codec)
avcodec_open2(st->codec, codec, options ? &options[i]
- : &one_thread_opt);
+ : &thread_opt);
}
+ if (!options)
+ av_dict_free(&thread_opt);
}
for (i=0; i<ic->nb_streams; i++) {
/* if we found the info for all the codecs, we can stop */
ret = count;
av_log(ic, AV_LOG_DEBUG, "All info found\n");
+ flush_codecs = 0;
break;
}
}
continue;
if (ret < 0) {
- /* EOF or error */
- ret = -1; /* we could not have all the codec parameters before EOF */
- for(i=0;i<ic->nb_streams;i++) {
- st = ic->streams[i];
- if (!has_codec_parameters(st->codec)){
- char buf[256];
- avcodec_string(buf, sizeof(buf), st->codec, 0);
- av_log(ic, AV_LOG_WARNING, "Could not find codec parameters (%s)\n", buf);
- } else {
- ret = 0;
- }
- }
+ /* EOF or error*/
break;
}
st = ic->streams[pkt->stream_index];
if (st->codec_info_nb_frames>1) {
- int64_t t;
- if (st->time_base.den > 0 && (t=av_rescale_q(st->info->codec_info_duration, st->time_base, AV_TIME_BASE_Q)) >= ic->max_analyze_duration) {
+ int64_t t=0;
+ if (st->time_base.den > 0)
+ t = av_rescale_q(st->info->codec_info_duration, st->time_base, AV_TIME_BASE_Q);
+ if (st->avg_frame_rate.num > 0)
+ t = FFMAX(t, av_rescale_q(st->codec_info_nb_frames, (AVRational){st->avg_frame_rate.den, st->avg_frame_rate.num}, AV_TIME_BASE_Q));
+
+ if (t >= ic->max_analyze_duration) {
av_log(ic, AV_LOG_WARNING, "max_analyze_duration %d reached at %"PRId64"\n", ic->max_analyze_duration, t);
break;
}
}
if(st->parser && st->parser->parser->split && !st->codec->extradata){
int i= st->parser->parser->split(st->codec, pkt->data, pkt->size);
- if(i){
+ if (i > 0 && i < FF_MAX_EXTRADATA_SIZE) {
st->codec->extradata_size= i;
st->codec->extradata= av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
+ if (!st->codec->extradata)
+ return AVERROR(ENOMEM);
memcpy(st->codec->extradata, pkt->data, st->codec->extradata_size);
memset(st->codec->extradata + i, 0, FF_INPUT_BUFFER_PADDING_SIZE);
}
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.
*/
- try_decode_frame(st, pkt, (options && i < orig_nb_streams )? &options[i]
- : &one_thread_opt);
+ try_decode_frame(st, pkt, (options && i < orig_nb_streams ) ? &options[i] : NULL);
st->codec_info_nb_frames++;
count++;
}
+ if (flush_codecs) {
+ AVPacket empty_pkt = { 0 };
+ int err;
+ av_init_packet(&empty_pkt);
+
+ ret = -1; /* we could not have all the codec parameters before EOF */
+ for(i=0;i<ic->nb_streams;i++) {
+ st = ic->streams[i];
+
+ /* flush the decoders */
+ do {
+ err = try_decode_frame(st, &empty_pkt,
+ (options && i < orig_nb_streams) ?
+ &options[i] : NULL);
+ } while (err > 0 && !has_codec_parameters(st->codec));
+
+ if (err < 0) {
+ av_log(ic, AV_LOG_INFO,
+ "decoding for stream %d failed\n", st->index);
+ }
+ if (!has_codec_parameters(st->codec)){
+ char buf[256];
+ avcodec_string(buf, sizeof(buf), st->codec, 0);
+ av_log(ic, AV_LOG_WARNING,
+ "Could not find codec parameters (%s)\n", buf);
+ } else {
+ ret = 0;
+ }
+ }
+ }
+
// close codecs which were opened in try_decode_frame()
for(i=0;i<ic->nb_streams;i++) {
st = ic->streams[i];
- if(st->codec->codec)
- avcodec_close(st->codec);
+ avcodec_close(st->codec);
}
for(i=0;i<ic->nb_streams;i++) {
st = ic->streams[i];
ic->streams[i]->codec->thread_count = 0;
av_freep(&ic->streams[i]->info);
}
- av_dict_free(&one_thread_opt);
return ret;
}
return AVERROR(ENOSYS);
}
-#if FF_API_FORMAT_PARAMETERS
-void av_close_input_stream(AVFormatContext *s)
-{
- flush_packet_queue(s);
- if (s->iformat->read_close)
- s->iformat->read_close(s);
- avformat_free_context(s);
-}
-#endif
-
void avformat_free_context(AVFormatContext *s)
{
int i;
/************************************************************/
/* output media file */
-#if FF_API_FORMAT_PARAMETERS
-int av_set_parameters(AVFormatContext *s, AVFormatParameters *ap)
-{
- if (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->priv_class) {
- *(const AVClass**)s->priv_data= s->oformat->priv_class;
- av_opt_set_defaults(s->priv_data);
- }
- } else
- s->priv_data = NULL;
-
- return 0;
-}
-#endif
-
int avformat_alloc_output_context2(AVFormatContext **avctx, AVOutputFormat *oformat,
const char *format, const char *filename)
{
return 1;
}
-#if FF_API_FORMAT_PARAMETERS
-int av_write_header(AVFormatContext *s)
-{
- return avformat_write_header(s, NULL);
-}
-#endif
-
int avformat_write_header(AVFormatContext *s, AVDictionary **options)
{
int ret = 0, i;
if(av_cmp_q(st->sample_aspect_ratio, st->codec->sample_aspect_ratio)
&& FFABS(av_q2d(st->sample_aspect_ratio) - av_q2d(st->codec->sample_aspect_ratio)) > 0.004*av_q2d(st->sample_aspect_ratio)
){
- av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between encoder and muxer layer\n");
+ av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between muxer "
+ "(%d/%d) and encoder layer (%d/%d)\n",
+ st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
+ st->codec->sample_aspect_ratio.num,
+ st->codec->sample_aspect_ratio.den);
ret = AVERROR(EINVAL);
goto fail;
}
int av_write_frame(AVFormatContext *s, AVPacket *pkt)
{
- int ret = compute_pkt_fields2(s, s->streams[pkt->stream_index], pkt);
+ int ret;
+
+ if (!pkt) {
+ if (s->oformat->flags & AVFMT_ALLOW_FLUSH)
+ return s->oformat->write_packet(s, pkt);
+ return 1;
+ }
+
+ ret = compute_pkt_fields2(s, s->streams[pkt->stream_index], pkt);
if(ret<0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
return ret;
* < 0 if an error occurred
*/
static int 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
+ if (s->oformat->interleave_packet) {
+ int ret = s->oformat->interleave_packet(s, out, in, flush);
+ if (in)
+ av_free_packet(in);
+ return ret;
+ } else
return av_interleave_packet_per_dts(s, out, in, flush);
}
av_log(ctx, AV_LOG_INFO, "%sMetadata:\n", indent);
while((tag=av_dict_get(m, "", tag, AV_DICT_IGNORE_SUFFIX))) {
if(strcmp("language", tag->key)){
- char tmp[256];
- int i;
- av_strlcpy(tmp, tag->value, sizeof(tmp));
- for(i=0; i<strlen(tmp); i++) if(tmp[i]==0xd) tmp[i]=' ';
- av_log(ctx, AV_LOG_INFO, "%s %-16s: %s\n", indent, tag->key, tmp);
+ const char *p = tag->value;
+ av_log(ctx, AV_LOG_INFO, "%s %-16s: ", indent, tag->key);
+ while(*p) {
+ char tmp[256];
+ size_t len = strcspn(p, "\xd\xa");
+ av_strlcpy(tmp, p, FFMIN(sizeof(tmp), len+1));
+ av_log(ctx, AV_LOG_INFO, "%s", tmp);
+ p += len;
+ if (*p == 0xd) av_log(ctx, AV_LOG_INFO, " ");
+ if (*p == 0xa) av_log(ctx, AV_LOG_INFO, "\n%s %-16s: ", indent, "");
+ if (*p) p++;
+ }
+ av_log(ctx, 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,
return (av_gettime() / 1000) * 1000 + NTP_OFFSET_US;
}
-#if FF_API_PARSE_DATE
-#include "libavutil/parseutils.h"
-
-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)
-{
- 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)
{
}
return 0;
}
+
+const struct AVCodecTag *avformat_get_riff_video_tags(void)
+{
+ return ff_codec_bmp_tags;
+}
+const struct AVCodecTag *avformat_get_riff_audio_tags(void)
+{
+ return ff_codec_wav_tags;
+}