mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-03-28 12:32:17 +02:00
split mux/demux related structures - added file probing support - improve media file reading API
Originally committed as revision 545 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
fe9cf0d44e
commit
b9a281db69
libav
210
libav/avformat.h
210
libav/avformat.h
@ -24,10 +24,18 @@ int av_new_packet(AVPacket *pkt, int size);
|
|||||||
void av_free_packet(AVPacket *pkt);
|
void av_free_packet(AVPacket *pkt);
|
||||||
|
|
||||||
/*************************************************/
|
/*************************************************/
|
||||||
/* output formats */
|
/* input/output formats */
|
||||||
|
|
||||||
struct AVFormatContext;
|
struct AVFormatContext;
|
||||||
struct AVFormatInputContext;
|
|
||||||
|
/* this structure contains the data a format has to probe a file */
|
||||||
|
typedef struct AVProbeData {
|
||||||
|
char *filename;
|
||||||
|
unsigned char *buf;
|
||||||
|
int buf_size;
|
||||||
|
} AVProbeData;
|
||||||
|
|
||||||
|
#define AVPROBE_SCORE_MAX 100
|
||||||
|
|
||||||
typedef struct AVFormatParameters {
|
typedef struct AVFormatParameters {
|
||||||
int frame_rate;
|
int frame_rate;
|
||||||
@ -38,12 +46,21 @@ typedef struct AVFormatParameters {
|
|||||||
enum PixelFormat pix_fmt;
|
enum PixelFormat pix_fmt;
|
||||||
} AVFormatParameters;
|
} AVFormatParameters;
|
||||||
|
|
||||||
typedef struct AVFormat {
|
#define AVFMT_NOFILE 0x0001 /* no file should be opened */
|
||||||
|
#define AVFMT_NEEDNUMBER 0x0002 /* needs '%d' in filename */
|
||||||
|
#define AVFMT_NOHEADER 0x0004 /* signal that no header is present
|
||||||
|
(streams are added dynamically) */
|
||||||
|
#define AVFMT_SHOW_IDS 0x0008 /* show format stream IDs numbers */
|
||||||
|
#define AVFMT_RGB24 0x0010 /* force RGB24 output for ppm (hack
|
||||||
|
- need better api) */
|
||||||
|
|
||||||
|
typedef struct AVOutputFormat {
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *long_name;
|
const char *long_name;
|
||||||
const char *mime_type;
|
const char *mime_type;
|
||||||
const char *extensions; /* comma separated extensions */
|
const char *extensions; /* comma separated extensions */
|
||||||
|
/* size of private data so that it can be allocated in the wrapper */
|
||||||
|
int priv_data_size;
|
||||||
/* output support */
|
/* output support */
|
||||||
enum CodecID audio_codec; /* default audio codec */
|
enum CodecID audio_codec; /* default audio codec */
|
||||||
enum CodecID video_codec; /* default video codec */
|
enum CodecID video_codec; /* default video codec */
|
||||||
@ -52,14 +69,28 @@ typedef struct AVFormat {
|
|||||||
int stream_index,
|
int stream_index,
|
||||||
unsigned char *buf, int size, int force_pts);
|
unsigned char *buf, int size, int force_pts);
|
||||||
int (*write_trailer)(struct AVFormatContext *);
|
int (*write_trailer)(struct AVFormatContext *);
|
||||||
|
/* can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER */
|
||||||
|
int flags;
|
||||||
|
/* private fields */
|
||||||
|
struct AVOutputFormat *next;
|
||||||
|
} AVOutputFormat;
|
||||||
|
|
||||||
/* optional input support */
|
typedef struct AVInputFormat {
|
||||||
/* read the format header and initialize the AVFormatInputContext
|
const char *name;
|
||||||
|
const char *long_name;
|
||||||
|
/* size of private data so that it can be allocated in the wrapper */
|
||||||
|
int priv_data_size;
|
||||||
|
/* tell if a given file has a chance of being parsing by this format */
|
||||||
|
int (*read_probe)(AVProbeData *);
|
||||||
|
/* read the format header and initialize the AVFormatContext
|
||||||
structure. Return 0 if OK. 'ap' if non NULL contains
|
structure. Return 0 if OK. 'ap' if non NULL contains
|
||||||
additionnal paramters. Only used in raw format right now */
|
additionnal paramters. Only used in raw format right
|
||||||
|
now. 'av_new_stream' should be called to create new streams. */
|
||||||
int (*read_header)(struct AVFormatContext *,
|
int (*read_header)(struct AVFormatContext *,
|
||||||
AVFormatParameters *ap);
|
AVFormatParameters *ap);
|
||||||
/* read one packet and put it in 'pkt'. pts and flags are also set */
|
/* read one packet and put it in 'pkt'. pts and flags are also
|
||||||
|
set. 'av_new_stream' can be called only if the flag
|
||||||
|
AVFMT_NOHEADER is used. */
|
||||||
int (*read_packet)(struct AVFormatContext *, AVPacket *pkt);
|
int (*read_packet)(struct AVFormatContext *, AVPacket *pkt);
|
||||||
/* close the stream. The AVFormatContext and AVStreams are not
|
/* close the stream. The AVFormatContext and AVStreams are not
|
||||||
freed by this function */
|
freed by this function */
|
||||||
@ -67,24 +98,37 @@ typedef struct AVFormat {
|
|||||||
/* seek at or before a given pts (given in microsecond). The pts
|
/* seek at or before a given pts (given in microsecond). The pts
|
||||||
origin is defined by the stream */
|
origin is defined by the stream */
|
||||||
int (*read_seek)(struct AVFormatContext *, INT64 pts);
|
int (*read_seek)(struct AVFormatContext *, INT64 pts);
|
||||||
|
/* can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_NOHEADER */
|
||||||
int flags;
|
int flags;
|
||||||
#define AVFMT_NOFILE 0x0001 /* no file should be opened */
|
/* if extensions are defined, then no probe is done. You should
|
||||||
#define AVFMT_NEEDNUMBER 0x0002 /* needs '%d' in filename */
|
usually not use extension format guessing because it is not
|
||||||
struct AVFormat *next;
|
reliable enough */
|
||||||
} AVFormat;
|
const char *extensions;
|
||||||
|
/* general purpose read only value that the format can use */
|
||||||
|
int value;
|
||||||
|
/* private fields */
|
||||||
|
struct AVInputFormat *next;
|
||||||
|
} AVInputFormat;
|
||||||
|
|
||||||
typedef struct AVStream {
|
typedef struct AVStream {
|
||||||
int id; /* internal stream id */
|
int index; /* stream index in AVFormatContext */
|
||||||
|
int id; /* format specific stream id */
|
||||||
AVCodecContext codec; /* codec context */
|
AVCodecContext codec; /* codec context */
|
||||||
int r_frame_rate; /* real frame rate of the stream */
|
int r_frame_rate; /* real frame rate of the stream */
|
||||||
void *priv_data;
|
void *priv_data;
|
||||||
|
/* internal data used in av_find_stream_info() */
|
||||||
|
int codec_info_state;
|
||||||
|
int codec_info_nb_repeat_frames;
|
||||||
|
int codec_info_nb_real_frames;
|
||||||
} AVStream;
|
} AVStream;
|
||||||
|
|
||||||
#define MAX_STREAMS 20
|
#define MAX_STREAMS 20
|
||||||
|
|
||||||
/* format I/O context */
|
/* format I/O context */
|
||||||
typedef struct AVFormatContext {
|
typedef struct AVFormatContext {
|
||||||
struct AVFormat *format;
|
/* can only be iformat or oformat, not both at the same time */
|
||||||
|
struct AVInputFormat *iformat;
|
||||||
|
struct AVOutputFormat *oformat;
|
||||||
void *priv_data;
|
void *priv_data;
|
||||||
ByteIOContext pb;
|
ByteIOContext pb;
|
||||||
int nb_streams;
|
int nb_streams;
|
||||||
@ -107,86 +151,76 @@ typedef struct AVPacketList {
|
|||||||
struct AVPacketList *next;
|
struct AVPacketList *next;
|
||||||
} AVPacketList;
|
} AVPacketList;
|
||||||
|
|
||||||
extern AVFormat *first_format;
|
extern AVInputFormat *first_iformat;
|
||||||
|
extern AVOutputFormat *first_oformat;
|
||||||
|
|
||||||
/* rv10enc.c */
|
/* XXX: use automatic init with either ELF sections or C file parser */
|
||||||
extern AVFormat rm_format;
|
/* modules */
|
||||||
|
|
||||||
/* mpegmux.c */
|
/* mpeg.c */
|
||||||
#define AVF_FLAG_VCD 0x00000001 /* VCD compatible MPEG-PS */
|
#define AVF_FLAG_VCD 0x00000001 /* VCD compatible MPEG-PS */
|
||||||
extern AVFormat mpeg_mux_format;
|
int mpegps_init(void);
|
||||||
|
|
||||||
/* asfenc.c */
|
/* mpegts.c */
|
||||||
extern AVFormat asf_format;
|
extern AVInputFormat mpegts_demux;
|
||||||
|
int mpegts_init(void);
|
||||||
|
|
||||||
/* avienc.c */
|
/* rm.c */
|
||||||
extern AVFormat avi_format;
|
int rm_init(void);
|
||||||
|
|
||||||
/* mov.c */
|
|
||||||
extern AVFormat mov_format;
|
|
||||||
extern AVFormat mp4_format;
|
|
||||||
|
|
||||||
/* jpegenc.c */
|
|
||||||
extern AVFormat mpjpeg_format;
|
|
||||||
extern AVFormat jpeg_format;
|
|
||||||
extern AVFormat single_jpeg_format;
|
|
||||||
|
|
||||||
/* swfenc.c */
|
|
||||||
extern AVFormat swf_format;
|
|
||||||
|
|
||||||
/* gif.c */
|
|
||||||
extern AVFormat gif_format;
|
|
||||||
/* au.c */
|
|
||||||
extern AVFormat au_format;
|
|
||||||
|
|
||||||
/* wav.c */
|
|
||||||
extern AVFormat wav_format;
|
|
||||||
|
|
||||||
/* crc.c */
|
/* crc.c */
|
||||||
extern AVFormat crc_format;
|
int crc_init(void);
|
||||||
|
|
||||||
/* img.c */
|
/* img.c */
|
||||||
extern AVFormat pgm_format;
|
int img_init(void);
|
||||||
extern AVFormat ppm_format;
|
|
||||||
extern AVFormat pgmyuv_format;
|
|
||||||
extern AVFormat imgyuv_format;
|
|
||||||
|
|
||||||
extern AVFormat pgmpipe_format;
|
/* asf.c */
|
||||||
extern AVFormat pgmyuvpipe_format;
|
int asf_init(void);
|
||||||
extern AVFormat ppmpipe_format;
|
|
||||||
|
/* avienc.c */
|
||||||
|
int avienc_init(void);
|
||||||
|
|
||||||
|
/* avidec.c */
|
||||||
|
int avidec_init(void);
|
||||||
|
|
||||||
|
/* swf.c */
|
||||||
|
int swf_init(void);
|
||||||
|
|
||||||
|
/* mov.c */
|
||||||
|
int mov_init(void);
|
||||||
|
|
||||||
|
/* jpeg.c */
|
||||||
|
int jpeg_init(void);
|
||||||
|
|
||||||
|
/* gif.c */
|
||||||
|
int gif_init(void);
|
||||||
|
|
||||||
|
/* au.c */
|
||||||
|
int au_init(void);
|
||||||
|
|
||||||
|
/* wav.c */
|
||||||
|
int wav_init(void);
|
||||||
|
|
||||||
/* raw.c */
|
/* raw.c */
|
||||||
extern AVFormat mp2_format;
|
int raw_init(void);
|
||||||
extern AVFormat ac3_format;
|
|
||||||
extern AVFormat h263_format;
|
|
||||||
extern AVFormat mpeg1video_format;
|
|
||||||
extern AVFormat mjpeg_format;
|
|
||||||
extern AVFormat pcm_s16le_format;
|
|
||||||
extern AVFormat pcm_s16be_format;
|
|
||||||
extern AVFormat pcm_u16le_format;
|
|
||||||
extern AVFormat pcm_u16be_format;
|
|
||||||
extern AVFormat pcm_s8_format;
|
|
||||||
extern AVFormat pcm_u8_format;
|
|
||||||
extern AVFormat pcm_mulaw_format;
|
|
||||||
extern AVFormat pcm_alaw_format;
|
|
||||||
extern AVFormat rawvideo_format;
|
|
||||||
|
|
||||||
/* ffm.c */
|
/* ffm.c */
|
||||||
extern AVFormat ffm_format;
|
int ffm_init(void);
|
||||||
|
|
||||||
/* formats.c */
|
|
||||||
|
|
||||||
|
/* utils.c */
|
||||||
#define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24))
|
#define MKTAG(a,b,c,d) (a | (b << 8) | (c << 16) | (d << 24))
|
||||||
#define MKBETAG(a,b,c,d) (d | (c << 8) | (b << 16) | (a << 24))
|
#define MKBETAG(a,b,c,d) (d | (c << 8) | (b << 16) | (a << 24))
|
||||||
|
|
||||||
void register_avformat(AVFormat *format);
|
void av_register_input_format(AVInputFormat *format);
|
||||||
AVFormat *guess_format(const char *short_name, const char *filename, const char *mime_type);
|
void av_register_output_format(AVOutputFormat *format);
|
||||||
|
AVOutputFormat *guess_format(const char *short_name,
|
||||||
|
const char *filename, const char *mime_type);
|
||||||
|
|
||||||
int strstart(const char *str, const char *val, const char **ptr);
|
int strstart(const char *str, const char *val, const char **ptr);
|
||||||
void nstrcpy(char *buf, int buf_size, const char *str);
|
void pstrcpy(char *buf, int buf_size, const char *str);
|
||||||
/* This does what strncpy ought to do. */
|
|
||||||
void strlcpy(char *dst, const char *src, int dst_size);
|
|
||||||
int match_ext(const char *filename, const char *extensions);
|
int match_ext(const char *filename, const char *extensions);
|
||||||
|
void av_hex_dump(UINT8 *buf, int size);
|
||||||
|
|
||||||
void register_all(void);
|
void register_all(void);
|
||||||
|
|
||||||
@ -203,14 +237,29 @@ int fifo_size(FifoBuffer *f, UINT8 *rptr);
|
|||||||
int fifo_read(FifoBuffer *f, UINT8 *buf, int buf_size, UINT8 **rptr_ptr);
|
int fifo_read(FifoBuffer *f, UINT8 *buf, int buf_size, UINT8 **rptr_ptr);
|
||||||
void fifo_write(FifoBuffer *f, UINT8 *buf, int size, UINT8 **wptr_ptr);
|
void fifo_write(FifoBuffer *f, UINT8 *buf, int size, UINT8 **wptr_ptr);
|
||||||
|
|
||||||
AVFormatContext *av_open_input_file(const char *filename,
|
/* media file input */
|
||||||
const char *format_name,
|
AVInputFormat *av_find_input_format(const char *short_name);
|
||||||
int buf_size,
|
int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,
|
||||||
AVFormatParameters *ap);
|
AVInputFormat *fmt,
|
||||||
|
int buf_size,
|
||||||
|
AVFormatParameters *ap);
|
||||||
|
|
||||||
|
#define AVERROR_UNKNOWN (-1) /* unknown error */
|
||||||
|
#define AVERROR_IO (-2) /* i/o error */
|
||||||
|
#define AVERROR_NUMEXPECTED (-3) /* number syntax expected in filename */
|
||||||
|
#define AVERROR_INVALIDDATA (-4) /* invalid data found */
|
||||||
|
#define AVERROR_NOMEM (-5) /* not enough memory */
|
||||||
|
#define AVERROR_NOFMT (-6) /* unknown format */
|
||||||
|
|
||||||
|
int av_find_stream_info(AVFormatContext *ic);
|
||||||
int av_read_packet(AVFormatContext *s, AVPacket *pkt);
|
int av_read_packet(AVFormatContext *s, AVPacket *pkt);
|
||||||
void av_close_input_file(AVFormatContext *s);
|
void av_close_input_file(AVFormatContext *s);
|
||||||
|
AVStream *av_new_stream(AVFormatContext *s, int id);
|
||||||
|
|
||||||
|
/* media file output */
|
||||||
|
int av_write_header(AVFormatContext *s);
|
||||||
int av_write_packet(AVFormatContext *s, AVPacket *pkt, int force_pts);
|
int av_write_packet(AVFormatContext *s, AVPacket *pkt, int force_pts);
|
||||||
|
int av_write_trailer(AVFormatContext *s);
|
||||||
|
|
||||||
void dump_format(AVFormatContext *ic,
|
void dump_format(AVFormatContext *ic,
|
||||||
int index,
|
int index,
|
||||||
@ -230,10 +279,11 @@ int find_info_tag(char *arg, int arg_size, const char *tag1, const char *info);
|
|||||||
|
|
||||||
int get_frame_filename(char *buf, int buf_size,
|
int get_frame_filename(char *buf, int buf_size,
|
||||||
const char *path, int number);
|
const char *path, int number);
|
||||||
|
int filename_number_test(const char *filename);
|
||||||
|
|
||||||
/* grab/output specific */
|
/* grab specific */
|
||||||
extern AVFormat video_grab_device_format;
|
int video_grab_init(void);
|
||||||
extern AVFormat audio_device_format;
|
int audio_init(void);
|
||||||
|
|
||||||
extern const char *v4l_device;
|
extern const char *v4l_device;
|
||||||
extern const char *audio_device;
|
extern const char *audio_device;
|
||||||
|
641
libav/utils.c
641
libav/utils.c
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Various utilities for ffmpeg system
|
* Various utilities for ffmpeg system
|
||||||
* Copyright (c) 2000,2001 Gerard Lantau
|
* Copyright (c) 2000, 2001, 2002 Gerard Lantau
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -29,12 +29,22 @@
|
|||||||
#include <sys/timeb.h>
|
#include <sys/timeb.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
AVFormat *first_format;
|
AVInputFormat *first_iformat;
|
||||||
|
AVOutputFormat *first_oformat;
|
||||||
|
|
||||||
void register_avformat(AVFormat *format)
|
void av_register_input_format(AVInputFormat *format)
|
||||||
{
|
{
|
||||||
AVFormat **p;
|
AVInputFormat **p;
|
||||||
p = &first_format;
|
p = &first_iformat;
|
||||||
|
while (*p != NULL) p = &(*p)->next;
|
||||||
|
*p = format;
|
||||||
|
format->next = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void av_register_output_format(AVOutputFormat *format)
|
||||||
|
{
|
||||||
|
AVOutputFormat **p;
|
||||||
|
p = &first_oformat;
|
||||||
while (*p != NULL) p = &(*p)->next;
|
while (*p != NULL) p = &(*p)->next;
|
||||||
*p = format;
|
*p = format;
|
||||||
format->next = NULL;
|
format->next = NULL;
|
||||||
@ -64,15 +74,16 @@ int match_ext(const char *filename, const char *extensions)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
AVFormat *guess_format(const char *short_name, const char *filename, const char *mime_type)
|
AVOutputFormat *guess_format(const char *short_name, const char *filename,
|
||||||
|
const char *mime_type)
|
||||||
{
|
{
|
||||||
AVFormat *fmt, *fmt_found;
|
AVOutputFormat *fmt, *fmt_found;
|
||||||
int score_max, score;
|
int score_max, score;
|
||||||
|
|
||||||
/* find the proper file type */
|
/* find the proper file type */
|
||||||
fmt_found = NULL;
|
fmt_found = NULL;
|
||||||
score_max = 0;
|
score_max = 0;
|
||||||
fmt = first_format;
|
fmt = first_oformat;
|
||||||
while (fmt != NULL) {
|
while (fmt != NULL) {
|
||||||
score = 0;
|
score = 0;
|
||||||
if (fmt->name && short_name && !strcmp(fmt->name, short_name))
|
if (fmt->name && short_name && !strcmp(fmt->name, short_name))
|
||||||
@ -92,8 +103,26 @@ AVFormat *guess_format(const char *short_name, const char *filename, const char
|
|||||||
return fmt_found;
|
return fmt_found;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return TRUE if val is a prefix of str. If it returns TRUE, ptr is
|
AVInputFormat *av_find_input_format(const char *short_name)
|
||||||
set to the next character in 'str' after the prefix */
|
{
|
||||||
|
AVInputFormat *fmt;
|
||||||
|
for(fmt = first_iformat; fmt != NULL; fmt = fmt->next) {
|
||||||
|
if (!strcmp(fmt->name, short_name))
|
||||||
|
return fmt;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return TRUE if val is a prefix of str. If it returns TRUE, ptr is
|
||||||
|
* set to the next character in 'str' after the prefix.
|
||||||
|
*
|
||||||
|
* @param str input string
|
||||||
|
* @param val prefix to test
|
||||||
|
* @param ptr updated after the prefix in str in there is a match
|
||||||
|
* @return TRUE if there is a match
|
||||||
|
*/
|
||||||
int strstart(const char *str, const char *val, const char **ptr)
|
int strstart(const char *str, const char *val, const char **ptr)
|
||||||
{
|
{
|
||||||
const char *p, *q;
|
const char *p, *q;
|
||||||
@ -110,7 +139,17 @@ int strstart(const char *str, const char *val, const char **ptr)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nstrcpy(char *buf, int buf_size, const char *str)
|
/**
|
||||||
|
* Copy the string str to buf. If str length is bigger than buf_size -
|
||||||
|
* 1 then it is clamped to buf_size - 1.
|
||||||
|
* NOTE: this function does what strncpy should have done to be
|
||||||
|
* useful. NEVER use strncpy.
|
||||||
|
*
|
||||||
|
* @param buf destination buffer
|
||||||
|
* @param buf_size size of destination buffer
|
||||||
|
* @param str source string
|
||||||
|
*/
|
||||||
|
void pstrcpy(char *buf, int buf_size, const char *str)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
char *q = buf;
|
char *q = buf;
|
||||||
@ -124,67 +163,34 @@ void nstrcpy(char *buf, int buf_size, const char *str)
|
|||||||
*q = '\0';
|
*q = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
void strlcpy(char *dst, const char *src, int len)
|
|
||||||
{
|
|
||||||
int slen = strlen(src) + 1;
|
|
||||||
|
|
||||||
if (slen <= len) {
|
|
||||||
memcpy(dst, src, slen);
|
|
||||||
} else {
|
|
||||||
memcpy(dst, src, len - 1);
|
|
||||||
dst[len - 1] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void register_all(void)
|
void register_all(void)
|
||||||
{
|
{
|
||||||
avcodec_init();
|
avcodec_init();
|
||||||
avcodec_register_all();
|
avcodec_register_all();
|
||||||
|
|
||||||
register_avformat(&mp2_format);
|
mpegps_init();
|
||||||
register_avformat(&ac3_format);
|
mpegts_init();
|
||||||
register_avformat(&mpeg_mux_format);
|
crc_init();
|
||||||
register_avformat(&mpeg1video_format);
|
img_init();
|
||||||
register_avformat(&mjpeg_format);
|
raw_init();
|
||||||
register_avformat(&h263_format);
|
rm_init();
|
||||||
register_avformat(&rm_format);
|
asf_init();
|
||||||
register_avformat(&asf_format);
|
avienc_init();
|
||||||
register_avformat(&avi_format);
|
avidec_init();
|
||||||
register_avformat(&mov_format);
|
wav_init();
|
||||||
register_avformat(&mp4_format);
|
swf_init();
|
||||||
register_avformat(&mpjpeg_format);
|
au_init();
|
||||||
register_avformat(&jpeg_format);
|
gif_init();
|
||||||
register_avformat(&single_jpeg_format);
|
mov_init();
|
||||||
register_avformat(&swf_format);
|
jpeg_init();
|
||||||
register_avformat(&gif_format);
|
|
||||||
register_avformat(&au_format);
|
|
||||||
register_avformat(&wav_format);
|
|
||||||
register_avformat(&crc_format);
|
|
||||||
|
|
||||||
register_avformat(&pcm_s16le_format);
|
|
||||||
register_avformat(&pcm_s16be_format);
|
|
||||||
register_avformat(&pcm_u16le_format);
|
|
||||||
register_avformat(&pcm_u16be_format);
|
|
||||||
register_avformat(&pcm_s8_format);
|
|
||||||
register_avformat(&pcm_u8_format);
|
|
||||||
register_avformat(&pcm_mulaw_format);
|
|
||||||
register_avformat(&pcm_alaw_format);
|
|
||||||
register_avformat(&rawvideo_format);
|
|
||||||
#ifndef CONFIG_WIN32
|
#ifndef CONFIG_WIN32
|
||||||
register_avformat(&ffm_format);
|
ffm_init();
|
||||||
#endif
|
#endif
|
||||||
register_avformat(&pgm_format);
|
|
||||||
register_avformat(&ppm_format);
|
|
||||||
register_avformat(&pgmyuv_format);
|
|
||||||
register_avformat(&imgyuv_format);
|
|
||||||
register_avformat(&pgmpipe_format);
|
|
||||||
register_avformat(&pgmyuvpipe_format);
|
|
||||||
register_avformat(&ppmpipe_format);
|
|
||||||
#ifdef CONFIG_GRAB
|
#ifdef CONFIG_GRAB
|
||||||
register_avformat(&video_grab_device_format);
|
video_grab_init();
|
||||||
register_avformat(&audio_device_format);
|
audio_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* file protocols */
|
/* file protocols */
|
||||||
register_protocol(&file_protocol);
|
register_protocol(&file_protocol);
|
||||||
register_protocol(&pipe_protocol);
|
register_protocol(&pipe_protocol);
|
||||||
@ -196,11 +202,18 @@ void register_all(void)
|
|||||||
|
|
||||||
/* memory handling */
|
/* memory handling */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate the payload of a packet and intialized its fields to default values.
|
||||||
|
*
|
||||||
|
* @param pkt packet
|
||||||
|
* @param size wanted payload size
|
||||||
|
* @return 0 if OK. AVERROR_xxx otherwise.
|
||||||
|
*/
|
||||||
int av_new_packet(AVPacket *pkt, int size)
|
int av_new_packet(AVPacket *pkt, int size)
|
||||||
{
|
{
|
||||||
pkt->data = av_malloc(size);
|
pkt->data = av_malloc(size);
|
||||||
if (!pkt->data)
|
if (!pkt->data)
|
||||||
return -ENOMEM;
|
return AVERROR_NOMEM;
|
||||||
pkt->size = size;
|
pkt->size = size;
|
||||||
/* sane state */
|
/* sane state */
|
||||||
pkt->pts = 0;
|
pkt->pts = 0;
|
||||||
@ -209,6 +222,11 @@ int av_new_packet(AVPacket *pkt, int size)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free a packet
|
||||||
|
*
|
||||||
|
* @param pkt packet to free
|
||||||
|
*/
|
||||||
void av_free_packet(AVPacket *pkt)
|
void av_free_packet(AVPacket *pkt)
|
||||||
{
|
{
|
||||||
av_freep(&pkt->data);
|
av_freep(&pkt->data);
|
||||||
@ -293,61 +311,146 @@ void fifo_write(FifoBuffer *f, UINT8 *buf, int size, UINT8 **wptr_ptr)
|
|||||||
*wptr_ptr = wptr;
|
*wptr_ptr = wptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* media file handling.
|
int filename_number_test(const char *filename)
|
||||||
'filename' is the filename to open.
|
{
|
||||||
'format_name' is used to force the file format (NULL if auto guess).
|
char buf[1024];
|
||||||
'buf_size' is the optional buffer size (zero if default is OK).
|
return get_frame_filename(buf, sizeof(buf), filename, 1);
|
||||||
'ap' are additionnal parameters needed when opening the file (NULL if default).
|
}
|
||||||
*/
|
|
||||||
|
/* guess file format */
|
||||||
AVFormatContext *av_open_input_file(const char *filename,
|
static AVInputFormat *probe_input_format(AVProbeData *pd, int is_opened)
|
||||||
const char *format_name,
|
{
|
||||||
int buf_size,
|
AVInputFormat *fmt1, *fmt;
|
||||||
AVFormatParameters *ap)
|
int score, score_max;
|
||||||
|
|
||||||
|
fmt = NULL;
|
||||||
|
score_max = 0;
|
||||||
|
for(fmt1 = first_iformat; fmt1 != NULL; fmt1 = fmt1->next) {
|
||||||
|
if (!is_opened && !(fmt1->flags & AVFMT_NOFILE))
|
||||||
|
continue;
|
||||||
|
score = 0;
|
||||||
|
if (fmt1->extensions) {
|
||||||
|
if (match_ext(pd->filename, fmt1->extensions)) {
|
||||||
|
score = 50;
|
||||||
|
}
|
||||||
|
} else if (fmt1->read_probe) {
|
||||||
|
score = fmt1->read_probe(pd);
|
||||||
|
}
|
||||||
|
if (score > score_max) {
|
||||||
|
score_max = score;
|
||||||
|
fmt = fmt1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fmt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************/
|
||||||
|
/* input media file */
|
||||||
|
|
||||||
|
#define PROBE_BUF_SIZE 2048
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a media file as input. The codec are not opened. Only the file
|
||||||
|
* header (if present) is read.
|
||||||
|
*
|
||||||
|
* @param ic_ptr the opened media file handle is put here
|
||||||
|
* @param filename filename to open.
|
||||||
|
* @param fmt if non NULL, force the file format to use
|
||||||
|
* @param buf_size optional buffer size (zero if default is OK)
|
||||||
|
* @param ap additionnal parameters needed when opening the file (NULL if default)
|
||||||
|
* @return 0 if OK. AVERROR_xxx otherwise.
|
||||||
|
*/
|
||||||
|
int av_open_input_file(AVFormatContext **ic_ptr, const char *filename,
|
||||||
|
AVInputFormat *fmt,
|
||||||
|
int buf_size,
|
||||||
|
AVFormatParameters *ap)
|
||||||
{
|
{
|
||||||
AVFormat *fmt;
|
|
||||||
AVFormatContext *ic = NULL;
|
AVFormatContext *ic = NULL;
|
||||||
int err;
|
int err;
|
||||||
|
char buf[PROBE_BUF_SIZE];
|
||||||
|
AVProbeData probe_data, *pd = &probe_data;
|
||||||
|
|
||||||
ic = av_mallocz(sizeof(AVFormatContext));
|
ic = av_mallocz(sizeof(AVFormatContext));
|
||||||
if (!ic)
|
if (!ic) {
|
||||||
|
err = AVERROR_NOMEM;
|
||||||
goto fail;
|
goto fail;
|
||||||
|
}
|
||||||
|
pstrcpy(ic->filename, sizeof(ic->filename), filename);
|
||||||
|
pd->filename = ic->filename;
|
||||||
|
pd->buf = buf;
|
||||||
|
pd->buf_size = 0;
|
||||||
|
|
||||||
/* find format */
|
if (!fmt) {
|
||||||
if (format_name != NULL) {
|
/* guess format if no file can be opened */
|
||||||
fmt = guess_format(format_name, NULL, NULL);
|
fmt = probe_input_format(pd, 0);
|
||||||
} else {
|
|
||||||
fmt = guess_format(NULL, filename, NULL);
|
|
||||||
}
|
}
|
||||||
if (!fmt || !fmt->read_header) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
ic->format = fmt;
|
|
||||||
|
|
||||||
/* if no file needed do not try to open one */
|
/* if no file needed do not try to open one */
|
||||||
if (!(fmt->flags & AVFMT_NOFILE)) {
|
if (!fmt || !(fmt->flags & AVFMT_NOFILE)) {
|
||||||
if (url_fopen(&ic->pb, filename, URL_RDONLY) < 0)
|
if (url_fopen(&ic->pb, filename, URL_RDONLY) < 0) {
|
||||||
|
err = AVERROR_IO;
|
||||||
goto fail;
|
goto fail;
|
||||||
|
}
|
||||||
if (buf_size > 0) {
|
if (buf_size > 0) {
|
||||||
url_setbufsize(&ic->pb, buf_size);
|
url_setbufsize(&ic->pb, buf_size);
|
||||||
}
|
}
|
||||||
|
/* read probe data */
|
||||||
|
pd->buf_size = get_buffer(&ic->pb, buf, PROBE_BUF_SIZE);
|
||||||
|
url_fseek(&ic->pb, 0, SEEK_SET);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = ic->format->read_header(ic, ap);
|
/* guess file format */
|
||||||
if (err < 0) {
|
if (!fmt) {
|
||||||
if (!(fmt->flags & AVFMT_NOFILE)) {
|
fmt = probe_input_format(pd, 1);
|
||||||
url_fclose(&ic->pb);
|
}
|
||||||
}
|
|
||||||
|
/* if still no format found, error */
|
||||||
|
if (!fmt) {
|
||||||
|
err = AVERROR_NOFMT;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ic;
|
ic->iformat = fmt;
|
||||||
|
|
||||||
|
/* allocate private data */
|
||||||
|
ic->priv_data = av_mallocz(fmt->priv_data_size);
|
||||||
|
if (!ic->priv_data) {
|
||||||
|
err = AVERROR_NOMEM;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check filename in case of an image number is expected */
|
||||||
|
if (ic->iformat->flags & AVFMT_NEEDNUMBER) {
|
||||||
|
if (filename_number_test(ic->filename) < 0) {
|
||||||
|
err = AVERROR_NUMEXPECTED;
|
||||||
|
goto fail1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ic->iformat->read_header(ic, ap);
|
||||||
|
if (err < 0)
|
||||||
|
goto fail1;
|
||||||
|
*ic_ptr = ic;
|
||||||
|
return 0;
|
||||||
|
fail1:
|
||||||
|
if (!(fmt->flags & AVFMT_NOFILE)) {
|
||||||
|
url_fclose(&ic->pb);
|
||||||
|
}
|
||||||
fail:
|
fail:
|
||||||
|
if (ic) {
|
||||||
|
av_free(ic->priv_data);
|
||||||
|
}
|
||||||
av_free(ic);
|
av_free(ic);
|
||||||
return NULL;
|
*ic_ptr = NULL;
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a packet from a media file
|
||||||
|
* @param s media file handle
|
||||||
|
* @param pkt is filled
|
||||||
|
* @return 0 if OK. AVERROR_xxx if error.
|
||||||
|
*/
|
||||||
int av_read_packet(AVFormatContext *s, AVPacket *pkt)
|
int av_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||||
{
|
{
|
||||||
AVPacketList *pktl;
|
AVPacketList *pktl;
|
||||||
@ -360,16 +463,240 @@ int av_read_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
av_free(pktl);
|
av_free(pktl);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return s->format->read_packet(s, pkt);
|
return s->iformat->read_packet(s, pkt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* state for codec information */
|
||||||
|
#define CSTATE_NOTFOUND 0
|
||||||
|
#define CSTATE_DECODING 1
|
||||||
|
#define CSTATE_FOUND 2
|
||||||
|
|
||||||
|
static int has_codec_parameters(AVCodecContext *enc)
|
||||||
|
{
|
||||||
|
int val;
|
||||||
|
switch(enc->codec_type) {
|
||||||
|
case CODEC_TYPE_AUDIO:
|
||||||
|
val = enc->sample_rate;
|
||||||
|
break;
|
||||||
|
case CODEC_TYPE_VIDEO:
|
||||||
|
val = enc->width;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
val = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return (val != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the beginning of a media file to get stream information. This
|
||||||
|
* is useful for file formats with no headers such as MPEG. This
|
||||||
|
* function also compute the real frame rate in case of mpeg2 repeat
|
||||||
|
* frame mode.
|
||||||
|
*
|
||||||
|
* @param ic media file handle
|
||||||
|
* @return >=0 if OK. AVERROR_xxx if error.
|
||||||
|
*/
|
||||||
|
int av_find_stream_info(AVFormatContext *ic)
|
||||||
|
{
|
||||||
|
int i, count, ret, got_picture, size, read_size;
|
||||||
|
AVCodec *codec;
|
||||||
|
AVStream *st;
|
||||||
|
AVPacket *pkt;
|
||||||
|
AVPicture picture;
|
||||||
|
AVPacketList *pktl=NULL, **ppktl;
|
||||||
|
short samples[AVCODEC_MAX_AUDIO_FRAME_SIZE / 2];
|
||||||
|
UINT8 *ptr;
|
||||||
|
int min_read_size, max_read_size;
|
||||||
|
|
||||||
|
/* typical mpeg ts rate is 40 Mbits. DVD rate is about 10
|
||||||
|
Mbits. We read at most 0.1 second of file to find all streams */
|
||||||
|
|
||||||
|
/* XXX: base it on stream bitrate when possible */
|
||||||
|
if (ic->iformat == &mpegts_demux) {
|
||||||
|
/* maximum number of bytes we accept to read to find all the streams
|
||||||
|
in a file */
|
||||||
|
min_read_size = 3000000;
|
||||||
|
} else {
|
||||||
|
min_read_size = 125000;
|
||||||
|
}
|
||||||
|
/* max read size is 2 seconds of video max */
|
||||||
|
max_read_size = min_read_size * 20;
|
||||||
|
|
||||||
|
/* set initial codec state */
|
||||||
|
for(i=0;i<ic->nb_streams;i++) {
|
||||||
|
st = ic->streams[i];
|
||||||
|
if (has_codec_parameters(&st->codec))
|
||||||
|
st->codec_info_state = CSTATE_FOUND;
|
||||||
|
else
|
||||||
|
st->codec_info_state = CSTATE_NOTFOUND;
|
||||||
|
st->codec_info_nb_repeat_frames = 0;
|
||||||
|
st->codec_info_nb_real_frames = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
read_size = 0;
|
||||||
|
ppktl = &ic->packet_buffer;
|
||||||
|
for(;;) {
|
||||||
|
/* check if one codec still needs to be handled */
|
||||||
|
for(i=0;i<ic->nb_streams;i++) {
|
||||||
|
st = ic->streams[i];
|
||||||
|
if (st->codec_info_state != CSTATE_FOUND)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i == ic->nb_streams) {
|
||||||
|
/* NOTE: if the format has no header, then we need to read
|
||||||
|
some packets to get most of the streams, so we cannot
|
||||||
|
stop here */
|
||||||
|
if (!(ic->iformat->flags & AVFMT_NOHEADER) ||
|
||||||
|
read_size >= min_read_size) {
|
||||||
|
/* if we found the info for all the codecs, we can stop */
|
||||||
|
ret = count;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* we did not get all the codec info, but we read too much data */
|
||||||
|
if (read_size >= max_read_size) {
|
||||||
|
ret = count;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pktl = av_mallocz(sizeof(AVPacketList));
|
||||||
|
if (!pktl) {
|
||||||
|
ret = AVERROR_NOMEM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* add the packet in the buffered packet list */
|
||||||
|
*ppktl = pktl;
|
||||||
|
ppktl = &pktl->next;
|
||||||
|
|
||||||
|
/* NOTE: a new stream can be added there if no header in file
|
||||||
|
(AVFMT_NOHEADER) */
|
||||||
|
pkt = &pktl->pkt;
|
||||||
|
if (ic->iformat->read_packet(ic, pkt) < 0) {
|
||||||
|
/* EOF or error */
|
||||||
|
ret = -1; /* we could not have all the codec parameters before EOF */
|
||||||
|
if ((ic->iformat->flags & AVFMT_NOHEADER) &&
|
||||||
|
i == ic->nb_streams)
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
read_size += pkt->size;
|
||||||
|
|
||||||
|
/* open new codecs */
|
||||||
|
for(i=0;i<ic->nb_streams;i++) {
|
||||||
|
st = ic->streams[i];
|
||||||
|
if (st->codec_info_state == CSTATE_NOTFOUND) {
|
||||||
|
/* set to found in case of error */
|
||||||
|
st->codec_info_state = CSTATE_FOUND;
|
||||||
|
codec = avcodec_find_decoder(st->codec.codec_id);
|
||||||
|
if (codec) {
|
||||||
|
ret = avcodec_open(&st->codec, codec);
|
||||||
|
if (ret >= 0)
|
||||||
|
st->codec_info_state = CSTATE_DECODING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
st = ic->streams[pkt->stream_index];
|
||||||
|
if (st->codec_info_state == CSTATE_DECODING) {
|
||||||
|
/* decode the data and update codec parameters */
|
||||||
|
ptr = pkt->data;
|
||||||
|
size = pkt->size;
|
||||||
|
while (size > 0) {
|
||||||
|
switch(st->codec.codec_type) {
|
||||||
|
case CODEC_TYPE_VIDEO:
|
||||||
|
ret = avcodec_decode_video(&st->codec, &picture,
|
||||||
|
&got_picture, ptr, size);
|
||||||
|
break;
|
||||||
|
case CODEC_TYPE_AUDIO:
|
||||||
|
ret = avcodec_decode_audio(&st->codec, samples,
|
||||||
|
&got_picture, ptr, size);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ret < 0) {
|
||||||
|
/* if error, simply ignore because another packet
|
||||||
|
may be OK */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (got_picture) {
|
||||||
|
/* we got the parameters - now we can stop
|
||||||
|
examining this stream */
|
||||||
|
/* XXX: add a codec info so that we can decide if
|
||||||
|
the codec can repeat frames */
|
||||||
|
if (st->codec.codec_id == CODEC_ID_MPEG1VIDEO &&
|
||||||
|
ic->iformat != &mpegts_demux &&
|
||||||
|
st->codec.sub_id == 2) {
|
||||||
|
/* for mpeg2 video, we want to know the real
|
||||||
|
frame rate, so we decode 40 frames. In mpeg
|
||||||
|
TS case we do not do it because it would be
|
||||||
|
too long */
|
||||||
|
st->codec_info_nb_real_frames++;
|
||||||
|
st->codec_info_nb_repeat_frames += st->codec.repeat_pict;
|
||||||
|
#if 0
|
||||||
|
/* XXX: testing */
|
||||||
|
if ((st->codec_info_nb_real_frames % 24) == 23) {
|
||||||
|
st->codec_info_nb_repeat_frames += 2;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* stop after 40 frames */
|
||||||
|
if (st->codec_info_nb_real_frames >= 40) {
|
||||||
|
st->r_frame_rate = (st->codec.frame_rate *
|
||||||
|
st->codec_info_nb_real_frames) /
|
||||||
|
(st->codec_info_nb_real_frames +
|
||||||
|
(st->codec_info_nb_repeat_frames >> 1));
|
||||||
|
goto close_codec;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
close_codec:
|
||||||
|
st->codec_info_state = CSTATE_FOUND;
|
||||||
|
avcodec_close(&st->codec);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ptr += ret;
|
||||||
|
size -= ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* close each codec if there are opened */
|
||||||
|
for(i=0;i<ic->nb_streams;i++) {
|
||||||
|
st = ic->streams[i];
|
||||||
|
if (st->codec_info_state == CSTATE_DECODING)
|
||||||
|
avcodec_close(&st->codec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set real frame rate info */
|
||||||
|
for(i=0;i<ic->nb_streams;i++) {
|
||||||
|
st = ic->streams[i];
|
||||||
|
if (st->codec.codec_type == CODEC_TYPE_VIDEO) {
|
||||||
|
if (!st->r_frame_rate)
|
||||||
|
st->r_frame_rate = st->codec.frame_rate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close a media file (but not its codecs)
|
||||||
|
*
|
||||||
|
* @param s media file handle
|
||||||
|
*/
|
||||||
void av_close_input_file(AVFormatContext *s)
|
void av_close_input_file(AVFormatContext *s)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (s->format->read_close)
|
if (s->iformat->read_close)
|
||||||
s->format->read_close(s);
|
s->iformat->read_close(s);
|
||||||
for(i=0;i<s->nb_streams;i++) {
|
for(i=0;i<s->nb_streams;i++) {
|
||||||
av_free(s->streams[i]);
|
av_free(s->streams[i]);
|
||||||
}
|
}
|
||||||
@ -384,17 +711,81 @@ void av_close_input_file(AVFormatContext *s)
|
|||||||
}
|
}
|
||||||
s->packet_buffer = NULL;
|
s->packet_buffer = NULL;
|
||||||
}
|
}
|
||||||
if (!(s->format->flags & AVFMT_NOFILE)) {
|
if (!(s->iformat->flags & AVFMT_NOFILE)) {
|
||||||
url_fclose(&s->pb);
|
url_fclose(&s->pb);
|
||||||
}
|
}
|
||||||
|
av_free(s->priv_data);
|
||||||
av_free(s);
|
av_free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a new stream to a media file. Can only be called in the
|
||||||
|
* read_header function. If the flag AVFMT_NOHEADER is in the format
|
||||||
|
* description, then new streams can be added in read_packet too.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param s media file handle
|
||||||
|
* @param id file format dependent stream id
|
||||||
|
*/
|
||||||
|
AVStream *av_new_stream(AVFormatContext *s, int id)
|
||||||
|
{
|
||||||
|
AVStream *st;
|
||||||
|
|
||||||
|
if (s->nb_streams >= MAX_STREAMS)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
st = av_mallocz(sizeof(AVStream));
|
||||||
|
if (!st)
|
||||||
|
return NULL;
|
||||||
|
st->index = s->nb_streams;
|
||||||
|
st->id = id;
|
||||||
|
s->streams[s->nb_streams++] = st;
|
||||||
|
return st;
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************/
|
||||||
|
/* output media file */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* allocate the stream private data and write the stream header to an
|
||||||
|
* output media file
|
||||||
|
*
|
||||||
|
* @param s media file handle
|
||||||
|
* @return 0 if OK. AVERROR_xxx if error.
|
||||||
|
*/
|
||||||
|
int av_write_header(AVFormatContext *s)
|
||||||
|
{
|
||||||
|
s->priv_data = av_mallocz(s->oformat->priv_data_size);
|
||||||
|
if (!s->priv_data)
|
||||||
|
return AVERROR_NOMEM;
|
||||||
|
return s->oformat->write_header(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* write a packet to an output media file
|
||||||
|
*
|
||||||
|
* @param s media file handle
|
||||||
|
* @param pkt packet to write
|
||||||
|
* @param force_pts XXX: need to suppress that
|
||||||
|
*/
|
||||||
int av_write_packet(AVFormatContext *s, AVPacket *pkt, int force_pts)
|
int av_write_packet(AVFormatContext *s, AVPacket *pkt, int force_pts)
|
||||||
{
|
{
|
||||||
/* XXX: currently, an emulation because internal API must change */
|
/* XXX: currently, an emulation because internal API must change */
|
||||||
return s->format->write_packet(s, pkt->stream_index, pkt->data, pkt->size, force_pts);
|
return s->oformat->write_packet(s, pkt->stream_index, pkt->data, pkt->size, force_pts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* write the stream trailer to an output media file and and free the
|
||||||
|
* file private data.
|
||||||
|
*
|
||||||
|
* @param s media file handle
|
||||||
|
* @return 0 if OK. AVERROR_xxx if error. */
|
||||||
|
int av_write_trailer(AVFormatContext *s)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
ret = s->oformat->write_trailer(s);
|
||||||
|
av_freep(&s->priv_data);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* "user interface" functions */
|
/* "user interface" functions */
|
||||||
@ -404,17 +795,28 @@ void dump_format(AVFormatContext *ic,
|
|||||||
const char *url,
|
const char *url,
|
||||||
int is_output)
|
int is_output)
|
||||||
{
|
{
|
||||||
int i;
|
int i, flags;
|
||||||
char buf[256];
|
char buf[256];
|
||||||
|
|
||||||
fprintf(stderr, "%s #%d, %s, %s '%s':\n",
|
fprintf(stderr, "%s #%d, %s, %s '%s':\n",
|
||||||
is_output ? "Output" : "Input",
|
is_output ? "Output" : "Input",
|
||||||
index, ic->format->name,
|
index,
|
||||||
|
is_output ? ic->oformat->name : ic->iformat->name,
|
||||||
is_output ? "to" : "from", url);
|
is_output ? "to" : "from", url);
|
||||||
for(i=0;i<ic->nb_streams;i++) {
|
for(i=0;i<ic->nb_streams;i++) {
|
||||||
AVStream *st = ic->streams[i];
|
AVStream *st = ic->streams[i];
|
||||||
avcodec_string(buf, sizeof(buf), &st->codec, is_output);
|
avcodec_string(buf, sizeof(buf), &st->codec, is_output);
|
||||||
fprintf(stderr, " Stream #%d.%d: %s\n", index, i, buf);
|
fprintf(stderr, " Stream #%d.%d", index, i);
|
||||||
|
/* the pid is an important information, so we display it */
|
||||||
|
/* XXX: add a generic system */
|
||||||
|
if (is_output)
|
||||||
|
flags = ic->oformat->flags;
|
||||||
|
else
|
||||||
|
flags = ic->iformat->flags;
|
||||||
|
if (flags & AVFMT_SHOW_IDS) {
|
||||||
|
fprintf(stderr, "[0x%x]", st->id);
|
||||||
|
}
|
||||||
|
fprintf(stderr, ": %s\n", buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -661,3 +1063,36 @@ void ticker_init(Ticker *tick, INT64 inrate, INT64 outrate)
|
|||||||
tick->div = tick->outrate / tick->inrate;
|
tick->div = tick->outrate / tick->inrate;
|
||||||
tick->mod = tick->outrate % tick->inrate;
|
tick->mod = tick->outrate % tick->inrate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Print on stdout a nice hexa dump of a buffer
|
||||||
|
* @param buf buffer
|
||||||
|
* @param size buffer size
|
||||||
|
*/
|
||||||
|
void av_hex_dump(UINT8 *buf, int size)
|
||||||
|
{
|
||||||
|
int len, i, j, c;
|
||||||
|
|
||||||
|
for(i=0;i<size;i+=16) {
|
||||||
|
len = size - i;
|
||||||
|
if (len > 16)
|
||||||
|
len = 16;
|
||||||
|
printf("%08x ", i);
|
||||||
|
for(j=0;j<16;j++) {
|
||||||
|
if (j < len)
|
||||||
|
printf(" %02x", buf[i+j]);
|
||||||
|
else
|
||||||
|
printf(" ");
|
||||||
|
}
|
||||||
|
printf(" ");
|
||||||
|
for(j=0;j<len;j++) {
|
||||||
|
c = buf[i+j];
|
||||||
|
if (c < ' ' || c > '~')
|
||||||
|
c = '.';
|
||||||
|
printf("%c", c);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user