mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-02-16 11:47:04 +00:00
Merge remote-tracking branch 'qatar/master'
* qatar/master: (22 commits) wma: Clip WMA1 and WMA2 frame length to 11 bits. movenc: Don't require frame_size to be set for modes other than mov doc: Update APIchanges with info on muxer flushing movenc: Reindent a block tools: Remove some unnecessary #undefs. rv20: prevent calling ff_h263_decode_mba() with unset height/width tools: K&R reformatting cosmetics Ignore generated aviocat and ismindex tools. build: Automatically include architecture-specific library Makefile snippets. indeo5: prevent null pointer dereference on broken files pktdumper: Use usleep instead of sleep cosmetics: Remove some unnecessary block braces. Drop unnecessary prefix from *sink* variable and struct names. Add a tool for creating smooth streaming manifests movdec: Calculate an average bit rate for fragmented streams, too movenc: Write the sample rate instead of time scale in the stsd atom movenc: Add a separate ismv/isma (smooth streaming) muxer movenc: Allow the caller to decide on fragmentation libavformat: Add a flag for muxers that support write_packet(NULL) for flushing movenc: Add support for writing fragmented mov files ... Conflicts: Changelog cmdutils.c cmdutils.h doc/APIchanges ffmpeg.c ffplay.c libavfilter/Makefile libavformat/Makefile libavformat/avformat.h libavformat/movenc.c libavformat/movenc.h libavformat/version.h tools/graph2dot.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
3c5fe5b527
2
.gitignore
vendored
2
.gitignore
vendored
@ -44,8 +44,10 @@ tests/tiny_psnr
|
||||
tests/videogen
|
||||
tests/vsynth1
|
||||
tests/vsynth2
|
||||
tools/aviocat
|
||||
tools/cws2fws
|
||||
tools/graph2dot
|
||||
tools/ismindex
|
||||
tools/lavfi-showfiltfmts
|
||||
tools/pktdumper
|
||||
tools/probetest
|
||||
|
@ -12,6 +12,7 @@ version next:
|
||||
- tinterlace video filter
|
||||
- astreamsync audio filter
|
||||
- amerge audio filter
|
||||
- ISMV (Smooth Streaming) muxer
|
||||
- GSM audio parser
|
||||
- SMJPEG muxer
|
||||
- XWD encoder and decoder
|
||||
|
1
Makefile
1
Makefile
@ -77,6 +77,7 @@ define DOSUBDIR
|
||||
$(foreach V,$(SUBDIR_VARS),$(eval $(call RESET,$(V))))
|
||||
SUBDIR := $(1)/
|
||||
include $(SRC_PATH)/$(1)/Makefile
|
||||
-include $(SRC_PATH)/$(1)/$(ARCH)/Makefile
|
||||
include $(SRC_PATH)/library.mak
|
||||
endef
|
||||
|
||||
|
@ -16,6 +16,12 @@ API changes, most recent first:
|
||||
2012-01-24 - xxxxxxx - lavfi 2.60.100
|
||||
Add avfilter_graph_dump.
|
||||
|
||||
2012-01-25 - lavf 53.22.0
|
||||
f1caf01 Allow doing av_write_frame(ctx, NULL) for flushing possible
|
||||
buffered data within a muxer. Added AVFMT_ALLOW_FLUSH for
|
||||
muxers supporting it (av_write_frame makes sure it is called
|
||||
only for muxers with this flag).
|
||||
|
||||
2012-01-15 - lavc 53.34.0
|
||||
New audio encoding API:
|
||||
b2c75b6 Add CODEC_CAP_VARIABLE_FRAME_SIZE capability for use by audio
|
||||
|
2
ffmpeg.c
2
ffmpeg.c
@ -629,6 +629,7 @@ static int configure_video_filters(InputStream *ist, OutputStream *ost)
|
||||
"src", args, NULL, ost->graph);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
#if FF_API_OLD_VSINK_API
|
||||
ret = avfilter_graph_create_filter(&ost->output_video_filter, avfilter_get_by_name("buffersink"),
|
||||
"out", NULL, pix_fmts, ost->graph);
|
||||
@ -638,6 +639,7 @@ static int configure_video_filters(InputStream *ist, OutputStream *ost)
|
||||
"out", NULL, buffersink_params, ost->graph);
|
||||
#endif
|
||||
av_freep(&buffersink_params);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
last_filter = ost->input_video_filter;
|
||||
|
1
ffplay.c
1
ffplay.c
@ -1745,6 +1745,7 @@ static int configure_video_filters(AVFilterGraph *graph, VideoState *is, const c
|
||||
if ((ret = avfilter_graph_create_filter(&filt_src, &input_filter, "src",
|
||||
NULL, is, graph)) < 0)
|
||||
return ret;
|
||||
|
||||
#if FF_API_OLD_VSINK_API
|
||||
ret = avfilter_graph_create_filter(&filt_out, avfilter_get_by_name("buffersink"), "out",
|
||||
NULL, pix_fmts, graph);
|
||||
|
@ -721,8 +721,6 @@ OBJS-$(CONFIG_MLIB) += mlib/dsputil_mlib.o \
|
||||
# well.
|
||||
OBJS-$(!CONFIG_SMALL) += inverse.o
|
||||
|
||||
-include $(SRC_PATH)/$(SUBDIR)$(ARCH)/Makefile
|
||||
|
||||
SKIPHEADERS += %_tablegen.h \
|
||||
%_tables.h \
|
||||
aac_tablegen_decl.h \
|
||||
|
@ -454,6 +454,10 @@ static int decode_mb_info(IVI5DecContext *ctx, IVIBandDesc *band,
|
||||
ref_mb = tile->ref_mbs;
|
||||
offs = tile->ypos * band->pitch + tile->xpos;
|
||||
|
||||
if (!ref_mb &&
|
||||
((band->qdelta_present && band->inherit_qdelta) || band->inherit_mv))
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
/* scale factor for motion vectors */
|
||||
mv_scale = (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3);
|
||||
mv_x = mv_y = 0;
|
||||
|
@ -1301,28 +1301,26 @@ static int ff_estimate_motion_b(MpegEncContext * s,
|
||||
break;
|
||||
case ME_X1:
|
||||
case ME_EPZS:
|
||||
{
|
||||
P_LEFT[0] = mv_table[mot_xy - 1][0];
|
||||
P_LEFT[1] = mv_table[mot_xy - 1][1];
|
||||
P_LEFT[0] = mv_table[mot_xy - 1][0];
|
||||
P_LEFT[1] = mv_table[mot_xy - 1][1];
|
||||
|
||||
if(P_LEFT[0] > (c->xmax<<shift)) P_LEFT[0] = (c->xmax<<shift);
|
||||
if (P_LEFT[0] > (c->xmax << shift)) P_LEFT[0] = (c->xmax << shift);
|
||||
|
||||
/* special case for first line */
|
||||
if (!s->first_slice_line) {
|
||||
P_TOP[0] = mv_table[mot_xy - mot_stride ][0];
|
||||
P_TOP[1] = mv_table[mot_xy - mot_stride ][1];
|
||||
P_TOPRIGHT[0] = mv_table[mot_xy - mot_stride + 1 ][0];
|
||||
P_TOPRIGHT[1] = mv_table[mot_xy - mot_stride + 1 ][1];
|
||||
if(P_TOP[1] > (c->ymax<<shift)) P_TOP[1]= (c->ymax<<shift);
|
||||
if(P_TOPRIGHT[0] < (c->xmin<<shift)) P_TOPRIGHT[0]= (c->xmin<<shift);
|
||||
if(P_TOPRIGHT[1] > (c->ymax<<shift)) P_TOPRIGHT[1]= (c->ymax<<shift);
|
||||
/* special case for first line */
|
||||
if (!s->first_slice_line) {
|
||||
P_TOP[0] = mv_table[mot_xy - mot_stride ][0];
|
||||
P_TOP[1] = mv_table[mot_xy - mot_stride ][1];
|
||||
P_TOPRIGHT[0] = mv_table[mot_xy - mot_stride + 1][0];
|
||||
P_TOPRIGHT[1] = mv_table[mot_xy - mot_stride + 1][1];
|
||||
if (P_TOP[1] > (c->ymax << shift)) P_TOP[1] = (c->ymax << shift);
|
||||
if (P_TOPRIGHT[0] < (c->xmin << shift)) P_TOPRIGHT[0] = (c->xmin << shift);
|
||||
if (P_TOPRIGHT[1] > (c->ymax << shift)) P_TOPRIGHT[1] = (c->ymax << shift);
|
||||
|
||||
P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
|
||||
P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
|
||||
}
|
||||
c->pred_x= P_LEFT[0];
|
||||
c->pred_y= P_LEFT[1];
|
||||
P_MEDIAN[0] = mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);
|
||||
P_MEDIAN[1] = mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);
|
||||
}
|
||||
c->pred_x = P_LEFT[0];
|
||||
c->pred_y = P_LEFT[1];
|
||||
|
||||
if(mv_table == s->b_forw_mv_table){
|
||||
mv_scale= (s->pb_time<<16) / (s->pp_time<<shift);
|
||||
|
@ -379,7 +379,8 @@ static int rv20_decode_picture_header(MpegEncContext *s)
|
||||
if(s->avctx->debug & FF_DEBUG_PICT_INFO){
|
||||
av_log(s->avctx, AV_LOG_DEBUG, "F %d/%d\n", f, rpr_bits);
|
||||
}
|
||||
}
|
||||
} else if (av_image_check_size(s->width, s->height, 0, s->avctx) < 0)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
mb_pos = ff_h263_decode_mba(s);
|
||||
|
||||
|
@ -85,7 +85,7 @@ int av_cold ff_wma_get_frame_len_bits(int sample_rate, int version,
|
||||
} else if (sample_rate <= 22050 ||
|
||||
(sample_rate <= 32000 && version == 1)) {
|
||||
frame_len_bits = 10;
|
||||
} else if (sample_rate <= 48000) {
|
||||
} else if (sample_rate <= 48000 || version < 3) {
|
||||
frame_len_bits = 11;
|
||||
} else if (sample_rate <= 96000) {
|
||||
frame_len_bits = 12;
|
||||
|
@ -839,7 +839,7 @@ static void draw_edges_mmx(uint8_t *buf, int wrap, int width, int height, int w,
|
||||
}
|
||||
|
||||
if (sides&EDGE_BOTTOM) {
|
||||
for(i = 0; i < w; i += 4) {
|
||||
for(i = 0; i < h; i += 4) {
|
||||
ptr= last_line + (i + 1) * wrap - w;
|
||||
__asm__ volatile(
|
||||
"1: \n\t"
|
||||
|
@ -106,7 +106,6 @@ OBJS-$(CONFIG_TESTSRC_FILTER) += vsrc_testsrc.o
|
||||
OBJS-$(CONFIG_BUFFERSINK_FILTER) += sink_buffer.o
|
||||
OBJS-$(CONFIG_NULLSINK_FILTER) += vsink_nullsink.o
|
||||
|
||||
|
||||
OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/mp_image.o
|
||||
OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/img_format.o
|
||||
OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_2xsai.o
|
||||
@ -164,8 +163,6 @@ OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/vf_yvu9.o
|
||||
OBJS-$(CONFIG_MP_FILTER) += libmpcodecs/pullup.o
|
||||
|
||||
|
||||
-include $(SRC_PATH)/$(SUBDIR)$(ARCH)/Makefile
|
||||
|
||||
DIRS = x86 libmpcodecs
|
||||
|
||||
TESTPROGS = formats
|
||||
|
@ -96,10 +96,8 @@ static void draw_slice(AVFilterLink *inlink, int y, int h, int slice_dir)
|
||||
for (i = 0; i < h>>vsub; i++) {
|
||||
switch (step) {
|
||||
case 1:
|
||||
{
|
||||
for (j = 0; j < (inlink->w >> hsub); j++)
|
||||
outrow[j] = inrow[-j];
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
|
@ -374,4 +374,4 @@ OBJS-$(CONFIG_UDP_PROTOCOL) += udp.o
|
||||
|
||||
SKIPHEADERS-$(CONFIG_NETWORK) += network.h rtsp.h
|
||||
TESTPROGS = seek
|
||||
TOOLS = aviocat pktdumper probetest
|
||||
TOOLS = aviocat ismindex pktdumper probetest
|
||||
|
@ -119,6 +119,7 @@ void av_register_all(void)
|
||||
REGISTER_DEMUXER (INGENIENT, ingenient);
|
||||
REGISTER_DEMUXER (IPMOVIE, ipmovie);
|
||||
REGISTER_MUXER (IPOD, ipod);
|
||||
REGISTER_MUXER (ISMV, ismv);
|
||||
REGISTER_DEMUXER (ISS, iss);
|
||||
REGISTER_DEMUXER (IV8, iv8);
|
||||
REGISTER_MUXDEMUX (IVF, ivf);
|
||||
|
@ -380,6 +380,7 @@ typedef struct AVFormatParameters {
|
||||
#define AVFMT_NOBINSEARCH 0x2000 /**< Format does not allow to fallback to binary search via read_timestamp */
|
||||
#define AVFMT_NOGENSEARCH 0x4000 /**< Format does not allow to fallback to generic search */
|
||||
#define AVFMT_NO_BYTE_SEEK 0x8000 /**< Format does not allow seeking by bytes */
|
||||
#define AVFMT_ALLOW_FLUSH 0x10000 /**< Format allows flushing. If not set, the muxer will not receive a NULL packet in the write_packet function. */
|
||||
#define AVFMT_TS_NONSTRICT 0x8000000 /**< Format does not require strictly
|
||||
increasing timestamps, but they must
|
||||
still be monotonic */
|
||||
@ -406,12 +407,19 @@ typedef struct AVOutputFormat {
|
||||
enum CodecID audio_codec; /**< default audio codec */
|
||||
enum CodecID video_codec; /**< default video codec */
|
||||
int (*write_header)(struct AVFormatContext *);
|
||||
/**
|
||||
* Write a packet. If AVFMT_ALLOW_FLUSH is set in flags,
|
||||
* pkt can be NULL in order to flush data buffered in the muxer.
|
||||
* When flushing, return 0 if there still is more data to flush,
|
||||
* or 1 if everything was flushed and there is no more buffered
|
||||
* data.
|
||||
*/
|
||||
int (*write_packet)(struct AVFormatContext *, AVPacket *pkt);
|
||||
int (*write_trailer)(struct AVFormatContext *);
|
||||
/**
|
||||
* can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_RAWPICTURE,
|
||||
* AVFMT_GLOBALHEADER, AVFMT_NOTIMESTAMPS, AVFMT_VARIABLE_FPS,
|
||||
* AVFMT_NODIMENSIONS, AVFMT_NOSTREAMS
|
||||
* AVFMT_NODIMENSIONS, AVFMT_NOSTREAMS, AVFMT_ALLOW_FLUSH
|
||||
*/
|
||||
int flags;
|
||||
|
||||
@ -1803,8 +1811,12 @@ attribute_deprecated int av_write_header(AVFormatContext *s);
|
||||
*
|
||||
* @param s media file handle
|
||||
* @param pkt The packet, which contains the stream_index, buf/buf_size,
|
||||
dts/pts, ...
|
||||
* @return < 0 on error, = 0 if OK, 1 if end of stream wanted
|
||||
* dts/pts, ...
|
||||
* This can be NULL (at any time, not just at the end), in
|
||||
* order to immediately flush data buffered within the muxer,
|
||||
* for muxers that buffer up data internally before writing it
|
||||
* to the output.
|
||||
* @return < 0 on error, = 0 if OK, 1 if flushed and there is no more data to flush
|
||||
*/
|
||||
int av_write_frame(AVFormatContext *s, AVPacket *pkt);
|
||||
|
||||
|
@ -127,6 +127,7 @@ typedef struct MOVStreamContext {
|
||||
int dts_shift; ///< dts shift when ctts is negative
|
||||
uint32_t palette[256];
|
||||
int has_palette;
|
||||
int64_t data_size;
|
||||
} MOVStreamContext;
|
||||
|
||||
typedef struct MOVContext {
|
||||
|
@ -1643,8 +1643,10 @@ static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
|
||||
init_get_bits(&gb, buf, 8*num_bytes);
|
||||
|
||||
for (i=0; i<entries; i++)
|
||||
for (i = 0; i < entries; i++) {
|
||||
sc->sample_sizes[i] = get_bits_long(&gb, field_size);
|
||||
sc->data_size += sc->sample_sizes[i];
|
||||
}
|
||||
|
||||
av_free(buf);
|
||||
return 0;
|
||||
@ -2347,6 +2349,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
distance++;
|
||||
dts += sample_duration;
|
||||
offset += sample_size;
|
||||
sc->data_size += sample_size;
|
||||
}
|
||||
frag->moof_offset = offset;
|
||||
st->duration = dts + sc->time_offset;
|
||||
@ -2722,6 +2725,16 @@ static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
||||
mov_read_timecode_track(s, s->streams[i]);
|
||||
}
|
||||
|
||||
if (mov->trex_data) {
|
||||
int i;
|
||||
for (i = 0; i < s->nb_streams; i++) {
|
||||
AVStream *st = s->streams[i];
|
||||
MOVStreamContext *sc = st->priv_data;
|
||||
if (st->duration)
|
||||
st->codec->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -38,6 +38,7 @@
|
||||
// ffmpeg -i testinput.avi -f psp -r 14.985 -s 320x240 -b 768 -ar 24000 -ab 32 M4V00001.MP4
|
||||
#define MODE_3G2 0x10
|
||||
#define MODE_IPOD 0x20
|
||||
#define MODE_ISM 0x40
|
||||
|
||||
typedef struct MOVIentry {
|
||||
uint64_t pos;
|
||||
@ -50,7 +51,6 @@ typedef struct MOVIentry {
|
||||
#define MOV_SYNC_SAMPLE 0x0001
|
||||
#define MOV_PARTIAL_SYNC_SAMPLE 0x0002
|
||||
uint32_t flags;
|
||||
uint8_t *data;
|
||||
} MOVIentry;
|
||||
|
||||
typedef struct HintSample {
|
||||
@ -67,6 +67,13 @@ typedef struct {
|
||||
HintSample *samples;
|
||||
} HintSampleQueue;
|
||||
|
||||
typedef struct {
|
||||
int64_t offset;
|
||||
int64_t time;
|
||||
int64_t duration;
|
||||
int64_t tfrf_offset;
|
||||
} MOVFragmentInfo;
|
||||
|
||||
typedef struct MOVIndex {
|
||||
int mode;
|
||||
int entry;
|
||||
@ -87,14 +94,12 @@ typedef struct MOVIndex {
|
||||
|
||||
int vosLen;
|
||||
uint8_t *vosData;
|
||||
int cluster_write_index;
|
||||
MOVIentry *cluster;
|
||||
int audio_vbr;
|
||||
int height; ///< active picture (w/o VBI) height for D-10/IMX
|
||||
uint32_t tref_tag;
|
||||
int tref_id; ///< trackID of the referenced track
|
||||
uint32_t trex_flags;
|
||||
int trex_size;
|
||||
int64_t start_dts;
|
||||
|
||||
int hint_track; ///< the track that hints this track, -1 if no hint track is set
|
||||
int src_track; ///< the track that this hint track describes
|
||||
@ -102,9 +107,21 @@ typedef struct MOVIndex {
|
||||
uint32_t prev_rtp_ts;
|
||||
int64_t cur_rtp_ts_unwrapped;
|
||||
uint32_t max_packet_size;
|
||||
int64_t base_data_offset_pos;
|
||||
|
||||
int64_t default_duration;
|
||||
uint32_t default_sample_flags;
|
||||
uint32_t default_size;
|
||||
|
||||
HintSampleQueue sample_queue;
|
||||
|
||||
AVIOContext *mdat_buf;
|
||||
int64_t moof_size_offset;
|
||||
int64_t data_offset;
|
||||
int64_t frag_start;
|
||||
int64_t tfrf_offset;
|
||||
|
||||
int nb_frag_info;
|
||||
MOVFragmentInfo *frag_info;
|
||||
} MOVTrack;
|
||||
|
||||
typedef struct MOVMuxContext {
|
||||
@ -116,22 +133,28 @@ typedef struct MOVMuxContext {
|
||||
int64_t mdat_pos;
|
||||
uint64_t mdat_size;
|
||||
MOVTrack *tracks;
|
||||
int fragments;
|
||||
int frag_seq_num;
|
||||
|
||||
int flags;
|
||||
int rtp_flags;
|
||||
int reserved_moov_size;
|
||||
int64_t reserved_moov_pos;
|
||||
int max_fragment_duration;
|
||||
int max_fragment_size;
|
||||
|
||||
int iods_skip;
|
||||
int iods_video_profile;
|
||||
int iods_audio_profile;
|
||||
|
||||
int fragments;
|
||||
int max_fragment_duration;
|
||||
int max_fragment_size;
|
||||
int ism_lookahead;
|
||||
} MOVMuxContext;
|
||||
|
||||
#define FF_MOV_FLAG_RTP_HINT 1
|
||||
#define FF_MOV_FLAG_FRAGMENT 2
|
||||
#define FF_MOV_FLAG_EMPTY_MOOV 4
|
||||
#define FF_MOV_FLAG_FRAG_KEYFRAME 8
|
||||
#define FF_MOV_FLAG_SEPARATE_MOOF 16
|
||||
#define FF_MOV_FLAG_FRAG_CUSTOM 32
|
||||
|
||||
int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt);
|
||||
|
||||
|
@ -3336,7 +3336,15 @@ static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt){
|
||||
|
||||
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;
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "libavutil/avutil.h"
|
||||
|
||||
#define LIBAVFORMAT_VERSION_MAJOR 53
|
||||
#define LIBAVFORMAT_VERSION_MINOR 30
|
||||
#define LIBAVFORMAT_VERSION_MINOR 31
|
||||
#define LIBAVFORMAT_VERSION_MICRO 100
|
||||
|
||||
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
|
||||
|
@ -99,7 +99,6 @@ yuv2planeX_altivec(const int16_t *filter, int filterSize,
|
||||
const uint8_t *dither, int offset)
|
||||
{
|
||||
register int i, j;
|
||||
{
|
||||
DECLARE_ALIGNED(16, int, val)[dstW];
|
||||
|
||||
for (i=0; i<dstW; i++)
|
||||
@ -142,7 +141,6 @@ yuv2planeX_altivec(const int16_t *filter, int filterSize,
|
||||
}
|
||||
}
|
||||
altivec_packIntArrayToCharArray(val, dest, dstW);
|
||||
}
|
||||
}
|
||||
|
||||
static void hScale_altivec_real(SwsContext *c, int16_t *dst, int dstW,
|
||||
@ -166,7 +164,6 @@ static void hScale_altivec_real(SwsContext *c, int16_t *dst, int dstW,
|
||||
else
|
||||
switch (filterSize) {
|
||||
case 4:
|
||||
{
|
||||
for (i=0; i<dstW; i++) {
|
||||
register int srcPos = filterPos[i];
|
||||
|
||||
@ -201,11 +198,9 @@ static void hScale_altivec_real(SwsContext *c, int16_t *dst, int dstW,
|
||||
vec_st(val_s, 0, tempo);
|
||||
dst[i] = FFMIN(tempo[3]>>7, (1<<15)-1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 8:
|
||||
{
|
||||
for (i=0; i<dstW; i++) {
|
||||
register int srcPos = filterPos[i];
|
||||
|
||||
@ -228,11 +223,9 @@ static void hScale_altivec_real(SwsContext *c, int16_t *dst, int dstW,
|
||||
vec_st(val_s, 0, tempo);
|
||||
dst[i] = FFMIN(tempo[3]>>7, (1<<15)-1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 16:
|
||||
{
|
||||
for (i=0; i<dstW; i++) {
|
||||
register int srcPos = filterPos[i];
|
||||
|
||||
@ -257,11 +250,9 @@ static void hScale_altivec_real(SwsContext *c, int16_t *dst, int dstW,
|
||||
vec_st(val_s, 0, tempo);
|
||||
dst[i] = FFMIN(tempo[3]>>7, (1<<15)-1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
for (i=0; i<dstW; i++) {
|
||||
register int j;
|
||||
register int srcPos = filterPos[i];
|
||||
@ -321,7 +312,6 @@ static void hScale_altivec_real(SwsContext *c, int16_t *dst, int dstW,
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ff_sws_init_swScale_altivec(SwsContext *c)
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "libavformat/avformat.h"
|
||||
|
||||
static int usage(const char *argv0, int ret)
|
||||
@ -80,13 +81,14 @@ int main(int argc, char **argv)
|
||||
stream_pos += n;
|
||||
if (bps) {
|
||||
avio_flush(output);
|
||||
while ((av_gettime() - start_time)*bps/AV_TIME_BASE < stream_pos)
|
||||
usleep(50*1000);
|
||||
while ((av_gettime() - start_time) * bps / AV_TIME_BASE < stream_pos)
|
||||
usleep(50 * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
avio_flush(output);
|
||||
avio_close(output);
|
||||
|
||||
fail:
|
||||
avio_close(input);
|
||||
avformat_network_deinit();
|
||||
|
@ -26,46 +26,42 @@ int main(int argc, char *argv[])
|
||||
z_stream zstream;
|
||||
struct stat statbuf;
|
||||
|
||||
if (argc < 3)
|
||||
{
|
||||
if (argc < 3) {
|
||||
printf("Usage: %s <infile.swf> <outfile.swf>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fd_in = open(argv[1], O_RDONLY);
|
||||
if (fd_in < 0)
|
||||
{
|
||||
if (fd_in < 0) {
|
||||
perror("Error opening input file");
|
||||
return 1;
|
||||
}
|
||||
|
||||
fd_out = open(argv[2], O_WRONLY|O_CREAT, 00644);
|
||||
if (fd_out < 0)
|
||||
{
|
||||
fd_out = open(argv[2], O_WRONLY | O_CREAT, 00644);
|
||||
if (fd_out < 0) {
|
||||
perror("Error opening output file");
|
||||
close(fd_in);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (read(fd_in, &buf_in, 8) != 8)
|
||||
{
|
||||
if (read(fd_in, &buf_in, 8) != 8) {
|
||||
printf("Header error\n");
|
||||
close(fd_in);
|
||||
close(fd_out);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (buf_in[0] != 'C' || buf_in[1] != 'W' || buf_in[2] != 'S')
|
||||
{
|
||||
if (buf_in[0] != 'C' || buf_in[1] != 'W' || buf_in[2] != 'S') {
|
||||
printf("Not a compressed flash file\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
fstat(fd_in, &statbuf);
|
||||
comp_len = statbuf.st_size;
|
||||
comp_len = statbuf.st_size;
|
||||
uncomp_len = buf_in[4] | (buf_in[5] << 8) | (buf_in[6] << 16) | (buf_in[7] << 24);
|
||||
|
||||
printf("Compressed size: %d Uncompressed size: %d\n", comp_len-4, uncomp_len-4);
|
||||
printf("Compressed size: %d Uncompressed size: %d\n",
|
||||
comp_len - 4, uncomp_len - 4);
|
||||
|
||||
// write out modified header
|
||||
buf_in[0] = 'F';
|
||||
@ -75,36 +71,35 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
zstream.zalloc = NULL;
|
||||
zstream.zfree = NULL;
|
||||
zstream.zfree = NULL;
|
||||
zstream.opaque = NULL;
|
||||
inflateInit(&zstream);
|
||||
|
||||
for (i = 0; i < comp_len-8;)
|
||||
{
|
||||
for (i = 0; i < comp_len - 8;) {
|
||||
int ret, len = read(fd_in, &buf_in, 1024);
|
||||
|
||||
dbgprintf("read %d bytes\n", len);
|
||||
|
||||
last_out = zstream.total_out;
|
||||
|
||||
zstream.next_in = &buf_in[0];
|
||||
zstream.avail_in = len;
|
||||
zstream.next_out = &buf_out[0];
|
||||
zstream.next_in = &buf_in[0];
|
||||
zstream.avail_in = len;
|
||||
zstream.next_out = &buf_out[0];
|
||||
zstream.avail_out = 65536;
|
||||
|
||||
ret = inflate(&zstream, Z_SYNC_FLUSH);
|
||||
if (ret != Z_STREAM_END && ret != Z_OK)
|
||||
{
|
||||
if (ret != Z_STREAM_END && ret != Z_OK) {
|
||||
printf("Error while decompressing: %d\n", ret);
|
||||
inflateEnd(&zstream);
|
||||
return 1;
|
||||
}
|
||||
|
||||
dbgprintf("a_in: %d t_in: %lu a_out: %d t_out: %lu -- %lu out\n",
|
||||
zstream.avail_in, zstream.total_in, zstream.avail_out, zstream.total_out,
|
||||
zstream.total_out-last_out);
|
||||
zstream.avail_in, zstream.total_in, zstream.avail_out,
|
||||
zstream.total_out, zstream.total_out - last_out);
|
||||
|
||||
if (write(fd_out, &buf_out, zstream.total_out - last_out) < zstream.total_out - last_out) {
|
||||
if (write(fd_out, &buf_out, zstream.total_out - last_out) <
|
||||
zstream.total_out - last_out) {
|
||||
perror("Error writing output file");
|
||||
return 1;
|
||||
}
|
||||
@ -115,15 +110,14 @@ int main(int argc, char *argv[])
|
||||
break;
|
||||
}
|
||||
|
||||
if (zstream.total_out != uncomp_len-8)
|
||||
{
|
||||
if (zstream.total_out != uncomp_len - 8) {
|
||||
printf("Size mismatch (%lu != %d), updating header...\n",
|
||||
zstream.total_out, uncomp_len-8);
|
||||
zstream.total_out, uncomp_len - 8);
|
||||
|
||||
buf_in[0] = (zstream.total_out+8) & 0xff;
|
||||
buf_in[1] = ((zstream.total_out+8) >> 8) & 0xff;
|
||||
buf_in[2] = ((zstream.total_out+8) >> 16) & 0xff;
|
||||
buf_in[3] = ((zstream.total_out+8) >> 24) & 0xff;
|
||||
buf_in[0] = (zstream.total_out + 8) & 0xff;
|
||||
buf_in[1] = ((zstream.total_out + 8) >> 8) & 0xff;
|
||||
buf_in[2] = ((zstream.total_out + 8) >> 16) & 0xff;
|
||||
buf_in[3] = ((zstream.total_out + 8) >> 24) & 0xff;
|
||||
|
||||
lseek(fd_out, 4, SEEK_SET);
|
||||
if (write(fd_out, &buf_in, 4) < 4) {
|
||||
|
@ -20,7 +20,6 @@
|
||||
|
||||
#include <unistd.h> /* getopt */
|
||||
|
||||
#undef HAVE_AV_CONFIG_H
|
||||
#include "libavutil/pixdesc.h"
|
||||
#include "libavutil/audioconvert.h"
|
||||
#include "libavfilter/avfiltergraph.h"
|
||||
@ -63,19 +62,25 @@ static void print_digraph(FILE *outfile, AVFilterGraph *graph)
|
||||
char dst_filter_ctx_label[128];
|
||||
const AVFilterContext *dst_filter_ctx = link->dst;
|
||||
|
||||
snprintf(dst_filter_ctx_label, sizeof(dst_filter_ctx_label), "%s (%s)",
|
||||
snprintf(dst_filter_ctx_label, sizeof(dst_filter_ctx_label),
|
||||
"%s (%s)",
|
||||
dst_filter_ctx->name,
|
||||
dst_filter_ctx->filter->name);
|
||||
|
||||
fprintf(outfile, "\"%s\" -> \"%s\"", filter_ctx_label, dst_filter_ctx_label);
|
||||
fprintf(outfile, "\"%s\" -> \"%s\"",
|
||||
filter_ctx_label, dst_filter_ctx_label);
|
||||
if (link->type == AVMEDIA_TYPE_VIDEO) {
|
||||
fprintf(outfile, " [ label= \"fmt:%s w:%d h:%d tb:%d/%d\" ]",
|
||||
fprintf(outfile,
|
||||
" [ label= \"fmt:%s w:%d h:%d tb:%d/%d\" ]",
|
||||
av_pix_fmt_descriptors[link->format].name,
|
||||
link->w, link->h, link->time_base.num, link->time_base.den);
|
||||
link->w, link->h, link->time_base.num,
|
||||
link->time_base.den);
|
||||
} else if (link->type == AVMEDIA_TYPE_AUDIO) {
|
||||
char buf[255];
|
||||
av_get_channel_layout_string(buf, sizeof(buf), -1, link->channel_layout);
|
||||
fprintf(outfile, " [ label= \"fmt:%s sr:%"PRId64" cl:%s tb:%d/%d\" ]",
|
||||
av_get_channel_layout_string(buf, sizeof(buf), -1,
|
||||
link->channel_layout);
|
||||
fprintf(outfile,
|
||||
" [ label= \"fmt:%s sr:%"PRId64" cl:%s tb:%d/%d\" ]",
|
||||
av_get_sample_fmt_name(link->format),
|
||||
link->sample_rate, buf,
|
||||
link->time_base.num, link->time_base.den);
|
||||
@ -90,17 +95,17 @@ static void print_digraph(FILE *outfile, AVFilterGraph *graph)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *outfilename = NULL;
|
||||
const char *infilename = NULL;
|
||||
FILE *outfile = NULL;
|
||||
FILE *infile = NULL;
|
||||
char *graph_string = NULL;
|
||||
const char *infilename = NULL;
|
||||
FILE *outfile = NULL;
|
||||
FILE *infile = NULL;
|
||||
char *graph_string = NULL;
|
||||
AVFilterGraph *graph = av_mallocz(sizeof(AVFilterGraph));
|
||||
char c;
|
||||
|
||||
av_log_set_level(AV_LOG_DEBUG);
|
||||
|
||||
while ((c = getopt(argc, argv, "hi:o:")) != -1) {
|
||||
switch(c) {
|
||||
switch (c) {
|
||||
case 'h':
|
||||
usage();
|
||||
return 0;
|
||||
@ -119,7 +124,8 @@ int main(int argc, char **argv)
|
||||
infilename = "/dev/stdin";
|
||||
infile = fopen(infilename, "r");
|
||||
if (!infile) {
|
||||
fprintf(stderr, "Impossible to open input file '%s': %s\n", infilename, strerror(errno));
|
||||
fprintf(stderr, "Impossible to open input file '%s': %s\n",
|
||||
infilename, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -127,7 +133,8 @@ int main(int argc, char **argv)
|
||||
outfilename = "/dev/stdout";
|
||||
outfile = fopen(outfilename, "w");
|
||||
if (!outfile) {
|
||||
fprintf(stderr, "Impossible to open output file '%s': %s\n", outfilename, strerror(errno));
|
||||
fprintf(stderr, "Impossible to open output file '%s': %s\n",
|
||||
outfilename, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -142,7 +149,7 @@ int main(int argc, char **argv)
|
||||
struct line *new_line = av_malloc(sizeof(struct line));
|
||||
count += strlen(last_line->data);
|
||||
last_line->next = new_line;
|
||||
last_line = new_line;
|
||||
last_line = new_line;
|
||||
}
|
||||
last_line->next = NULL;
|
||||
|
||||
|
521
tools/ismindex.c
Normal file
521
tools/ismindex.c
Normal file
@ -0,0 +1,521 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Martin Storsjo
|
||||
*
|
||||
* This file is part of Libav.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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 Libav; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* To create a simple file for smooth streaming:
|
||||
* avconv <normal input/transcoding options> -movflags frag_keyframe foo.ismv
|
||||
* ismindex -n foo foo.ismv
|
||||
* This step creates foo.ism and foo.ismc that is required by IIS for
|
||||
* serving it.
|
||||
*
|
||||
* To pre-split files for serving as static files by a web server without
|
||||
* any extra server support, create the ismv file as above, and split it:
|
||||
* ismindex -split foo.ismv
|
||||
* This step creates a file Manifest and directories QualityLevel(...),
|
||||
* that can be read directly by a smooth streaming player.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "libavformat/avformat.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
#include "libavutil/mathematics.h"
|
||||
|
||||
static int usage(const char *argv0, int ret)
|
||||
{
|
||||
fprintf(stderr, "%s [-split] [-n basename] file1 [file2] ...\n", argv0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct MoofOffset {
|
||||
int64_t time;
|
||||
int64_t offset;
|
||||
int duration;
|
||||
};
|
||||
|
||||
struct VideoFile {
|
||||
const char *name;
|
||||
int64_t duration;
|
||||
int bitrate;
|
||||
int track_id;
|
||||
int is_audio, is_video;
|
||||
int width, height;
|
||||
int chunks;
|
||||
int sample_rate, channels;
|
||||
uint8_t *codec_private;
|
||||
int codec_private_size;
|
||||
struct MoofOffset *offsets;
|
||||
int timescale;
|
||||
const char *fourcc;
|
||||
int blocksize;
|
||||
int tag;
|
||||
};
|
||||
|
||||
struct VideoFiles {
|
||||
int nb_files;
|
||||
int64_t duration;
|
||||
struct VideoFile **files;
|
||||
int video_file, audio_file;
|
||||
int nb_video_files, nb_audio_files;
|
||||
};
|
||||
|
||||
static int copy_tag(AVIOContext *in, AVIOContext *out, int32_t tag_name)
|
||||
{
|
||||
int32_t size, tag;
|
||||
|
||||
size = avio_rb32(in);
|
||||
tag = avio_rb32(in);
|
||||
avio_wb32(out, size);
|
||||
avio_wb32(out, tag);
|
||||
if (tag != tag_name)
|
||||
return -1;
|
||||
size -= 8;
|
||||
while (size > 0) {
|
||||
char buf[1024];
|
||||
int len = FFMIN(sizeof(buf), size);
|
||||
if (avio_read(in, buf, len) != len)
|
||||
break;
|
||||
avio_write(out, buf, len);
|
||||
size -= len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int write_fragment(const char *filename, AVIOContext *in)
|
||||
{
|
||||
AVIOContext *out = NULL;
|
||||
int ret;
|
||||
|
||||
if ((ret = avio_open2(&out, filename, AVIO_FLAG_WRITE, NULL, NULL)) < 0)
|
||||
return ret;
|
||||
copy_tag(in, out, MKBETAG('m', 'o', 'o', 'f'));
|
||||
copy_tag(in, out, MKBETAG('m', 'd', 'a', 't'));
|
||||
|
||||
avio_flush(out);
|
||||
avio_close(out);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int write_fragments(struct VideoFiles *files, int start_index,
|
||||
AVIOContext *in)
|
||||
{
|
||||
char dirname[100], filename[500];
|
||||
int i, j;
|
||||
|
||||
for (i = start_index; i < files->nb_files; i++) {
|
||||
struct VideoFile *vf = files->files[i];
|
||||
const char *type = vf->is_video ? "video" : "audio";
|
||||
snprintf(dirname, sizeof(dirname), "QualityLevels(%d)", vf->bitrate);
|
||||
mkdir(dirname, 0777);
|
||||
for (j = 0; j < vf->chunks; j++) {
|
||||
snprintf(filename, sizeof(filename), "%s/Fragments(%s=%"PRId64")",
|
||||
dirname, type, vf->offsets[j].time);
|
||||
avio_seek(in, vf->offsets[j].offset, SEEK_SET);
|
||||
write_fragment(filename, in);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int read_tfra(struct VideoFiles *files, int start_index, AVIOContext *f)
|
||||
{
|
||||
int ret = AVERROR_EOF, track_id;
|
||||
int version, fieldlength, i, j;
|
||||
int64_t pos = avio_tell(f);
|
||||
uint32_t size = avio_rb32(f);
|
||||
struct VideoFile *vf = NULL;
|
||||
|
||||
if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a'))
|
||||
goto fail;
|
||||
version = avio_r8(f);
|
||||
avio_rb24(f);
|
||||
track_id = avio_rb32(f); /* track id */
|
||||
for (i = start_index; i < files->nb_files && !vf; i++)
|
||||
if (files->files[i]->track_id == track_id)
|
||||
vf = files->files[i];
|
||||
if (!vf) {
|
||||
/* Ok, continue parsing the next atom */
|
||||
ret = 0;
|
||||
goto fail;
|
||||
}
|
||||
fieldlength = avio_rb32(f);
|
||||
vf->chunks = avio_rb32(f);
|
||||
vf->offsets = av_mallocz(sizeof(*vf->offsets) * vf->chunks);
|
||||
if (!vf->offsets) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
for (i = 0; i < vf->chunks; i++) {
|
||||
if (version == 1) {
|
||||
vf->offsets[i].time = avio_rb64(f);
|
||||
vf->offsets[i].offset = avio_rb64(f);
|
||||
} else {
|
||||
vf->offsets[i].time = avio_rb32(f);
|
||||
vf->offsets[i].offset = avio_rb32(f);
|
||||
}
|
||||
for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
|
||||
avio_r8(f);
|
||||
for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
|
||||
avio_r8(f);
|
||||
for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
|
||||
avio_r8(f);
|
||||
if (i > 0)
|
||||
vf->offsets[i - 1].duration = vf->offsets[i].time -
|
||||
vf->offsets[i - 1].time;
|
||||
}
|
||||
if (vf->chunks > 0)
|
||||
vf->offsets[vf->chunks - 1].duration = vf->duration -
|
||||
vf->offsets[vf->chunks - 1].time;
|
||||
ret = 0;
|
||||
|
||||
fail:
|
||||
avio_seek(f, pos + size, SEEK_SET);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int read_mfra(struct VideoFiles *files, int start_index,
|
||||
const char *file, int split)
|
||||
{
|
||||
int err = 0;
|
||||
AVIOContext *f = NULL;
|
||||
int32_t mfra_size;
|
||||
|
||||
if ((err = avio_open2(&f, file, AVIO_FLAG_READ, NULL, NULL)) < 0)
|
||||
goto fail;
|
||||
avio_seek(f, avio_size(f) - 4, SEEK_SET);
|
||||
mfra_size = avio_rb32(f);
|
||||
avio_seek(f, -mfra_size, SEEK_CUR);
|
||||
if (avio_rb32(f) != mfra_size)
|
||||
goto fail;
|
||||
if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a'))
|
||||
goto fail;
|
||||
while (!read_tfra(files, start_index, f)) {
|
||||
/* Empty */
|
||||
}
|
||||
|
||||
if (split)
|
||||
write_fragments(files, start_index, f);
|
||||
|
||||
fail:
|
||||
if (f)
|
||||
avio_close(f);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int get_private_data(struct VideoFile *vf, AVCodecContext *codec)
|
||||
{
|
||||
vf->codec_private_size = codec->extradata_size;
|
||||
vf->codec_private = av_mallocz(codec->extradata_size);
|
||||
if (!vf->codec_private)
|
||||
return AVERROR(ENOMEM);
|
||||
memcpy(vf->codec_private, codec->extradata, codec->extradata_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_video_private_data(struct VideoFile *vf, AVCodecContext *codec)
|
||||
{
|
||||
AVIOContext *io = NULL;
|
||||
uint16_t sps_size, pps_size;
|
||||
int err = AVERROR(EINVAL);
|
||||
|
||||
if (codec->codec_id == CODEC_ID_VC1)
|
||||
return get_private_data(vf, codec);
|
||||
|
||||
avio_open_dyn_buf(&io);
|
||||
if (codec->extradata_size < 11 || codec->extradata[0] != 1)
|
||||
goto fail;
|
||||
sps_size = AV_RB16(&codec->extradata[6]);
|
||||
if (11 + sps_size > codec->extradata_size)
|
||||
goto fail;
|
||||
avio_wb32(io, 0x00000001);
|
||||
avio_write(io, &codec->extradata[8], sps_size);
|
||||
pps_size = AV_RB16(&codec->extradata[9 + sps_size]);
|
||||
if (11 + sps_size + pps_size > codec->extradata_size)
|
||||
goto fail;
|
||||
avio_wb32(io, 0x00000001);
|
||||
avio_write(io, &codec->extradata[11 + sps_size], pps_size);
|
||||
err = 0;
|
||||
|
||||
fail:
|
||||
vf->codec_private_size = avio_close_dyn_buf(io, &vf->codec_private);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int handle_file(struct VideoFiles *files, const char *file, int split)
|
||||
{
|
||||
AVFormatContext *ctx = NULL;
|
||||
int err = 0, i, orig_files = files->nb_files;
|
||||
char errbuf[50], *ptr;
|
||||
struct VideoFile *vf;
|
||||
|
||||
err = avformat_open_input(&ctx, file, NULL, NULL);
|
||||
if (err < 0) {
|
||||
av_strerror(err, errbuf, sizeof(errbuf));
|
||||
fprintf(stderr, "Unable to open %s: %s\n", file, errbuf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
err = avformat_find_stream_info(ctx, NULL);
|
||||
if (err < 0) {
|
||||
av_strerror(err, errbuf, sizeof(errbuf));
|
||||
fprintf(stderr, "Unable to identify %s: %s\n", file, errbuf);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (ctx->nb_streams < 1) {
|
||||
fprintf(stderr, "No streams found in %s\n", file);
|
||||
goto fail;
|
||||
}
|
||||
if (!files->duration)
|
||||
files->duration = ctx->duration;
|
||||
|
||||
for (i = 0; i < ctx->nb_streams; i++) {
|
||||
AVStream *st = ctx->streams[i];
|
||||
vf = av_mallocz(sizeof(*vf));
|
||||
files->files = av_realloc(files->files,
|
||||
sizeof(*files->files) * (files->nb_files + 1));
|
||||
files->files[files->nb_files] = vf;
|
||||
|
||||
vf->name = file;
|
||||
if ((ptr = strrchr(file, '/')) != NULL)
|
||||
vf->name = ptr + 1;
|
||||
|
||||
vf->bitrate = st->codec->bit_rate;
|
||||
vf->track_id = st->id;
|
||||
vf->timescale = st->time_base.den;
|
||||
vf->duration = av_rescale_rnd(ctx->duration, vf->timescale,
|
||||
AV_TIME_BASE, AV_ROUND_UP);
|
||||
vf->is_audio = st->codec->codec_type == AVMEDIA_TYPE_AUDIO;
|
||||
vf->is_video = st->codec->codec_type == AVMEDIA_TYPE_VIDEO;
|
||||
|
||||
if (!vf->is_audio && !vf->is_video) {
|
||||
fprintf(stderr,
|
||||
"Track %d in %s is neither video nor audio, skipping\n",
|
||||
vf->track_id, file);
|
||||
av_freep(&files->files[files->nb_files]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (vf->is_audio) {
|
||||
if (files->audio_file < 0)
|
||||
files->audio_file = files->nb_files;
|
||||
files->nb_audio_files++;
|
||||
vf->channels = st->codec->channels;
|
||||
vf->sample_rate = st->codec->sample_rate;
|
||||
if (st->codec->codec_id == CODEC_ID_AAC) {
|
||||
vf->fourcc = "AACL";
|
||||
vf->tag = 255;
|
||||
vf->blocksize = 4;
|
||||
} else if (st->codec->codec_id == CODEC_ID_WMAPRO) {
|
||||
vf->fourcc = "WMAP";
|
||||
vf->tag = st->codec->codec_tag;
|
||||
vf->blocksize = st->codec->block_align;
|
||||
}
|
||||
get_private_data(vf, st->codec);
|
||||
}
|
||||
if (vf->is_video) {
|
||||
if (files->video_file < 0)
|
||||
files->video_file = files->nb_files;
|
||||
files->nb_video_files++;
|
||||
vf->width = st->codec->width;
|
||||
vf->height = st->codec->height;
|
||||
if (st->codec->codec_id == CODEC_ID_H264)
|
||||
vf->fourcc = "H264";
|
||||
else if (st->codec->codec_id == CODEC_ID_VC1)
|
||||
vf->fourcc = "WVC1";
|
||||
get_video_private_data(vf, st->codec);
|
||||
}
|
||||
|
||||
files->nb_files++;
|
||||
}
|
||||
|
||||
avformat_close_input(&ctx);
|
||||
|
||||
read_mfra(files, orig_files, file, split);
|
||||
|
||||
fail:
|
||||
if (ctx)
|
||||
avformat_close_input(&ctx);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void output_server_manifest(struct VideoFiles *files,
|
||||
const char *basename)
|
||||
{
|
||||
char filename[1000];
|
||||
FILE *out;
|
||||
int i;
|
||||
|
||||
snprintf(filename, sizeof(filename), "%s.ism", basename);
|
||||
out = fopen(filename, "w");
|
||||
if (!out) {
|
||||
perror(filename);
|
||||
return;
|
||||
}
|
||||
fprintf(out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
|
||||
fprintf(out, "<smil xmlns=\"http://www.w3.org/2001/SMIL20/Language\">\n");
|
||||
fprintf(out, "\t<head>\n");
|
||||
fprintf(out, "\t\t<meta name=\"clientManifestRelativePath\" "
|
||||
"content=\"%s.ismc\" />\n", basename);
|
||||
fprintf(out, "\t</head>\n");
|
||||
fprintf(out, "\t<body>\n");
|
||||
fprintf(out, "\t\t<switch>\n");
|
||||
for (i = 0; i < files->nb_files; i++) {
|
||||
struct VideoFile *vf = files->files[i];
|
||||
const char *type = vf->is_video ? "video" : "audio";
|
||||
fprintf(out, "\t\t\t<%s src=\"%s\" systemBitrate=\"%d\">\n",
|
||||
type, vf->name, vf->bitrate);
|
||||
fprintf(out, "\t\t\t\t<param name=\"trackID\" value=\"%d\" "
|
||||
"valueType=\"data\" />\n", vf->track_id);
|
||||
fprintf(out, "\t\t\t</%s>\n", type);
|
||||
}
|
||||
fprintf(out, "\t\t</switch>\n");
|
||||
fprintf(out, "\t</body>\n");
|
||||
fprintf(out, "</smil>\n");
|
||||
fclose(out);
|
||||
}
|
||||
|
||||
static void output_client_manifest(struct VideoFiles *files,
|
||||
const char *basename, int split)
|
||||
{
|
||||
char filename[1000];
|
||||
FILE *out;
|
||||
int i, j;
|
||||
|
||||
if (split)
|
||||
snprintf(filename, sizeof(filename), "Manifest");
|
||||
else
|
||||
snprintf(filename, sizeof(filename), "%s.ismc", basename);
|
||||
out = fopen(filename, "w");
|
||||
if (!out) {
|
||||
perror(filename);
|
||||
return;
|
||||
}
|
||||
fprintf(out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n");
|
||||
fprintf(out, "<SmoothStreamingMedia MajorVersion=\"2\" MinorVersion=\"0\" "
|
||||
"Duration=\"%"PRId64 "\">\n", files->duration * 10);
|
||||
if (files->video_file >= 0) {
|
||||
struct VideoFile *vf = files->files[files->video_file];
|
||||
int index = 0;
|
||||
fprintf(out,
|
||||
"\t<StreamIndex Type=\"video\" QualityLevels=\"%d\" "
|
||||
"Chunks=\"%d\" "
|
||||
"Url=\"QualityLevels({bitrate})/Fragments(video={start time})\">\n",
|
||||
files->nb_video_files, vf->chunks);
|
||||
for (i = 0; i < files->nb_files; i++) {
|
||||
vf = files->files[i];
|
||||
if (!vf->is_video)
|
||||
continue;
|
||||
fprintf(out,
|
||||
"\t\t<QualityLevel Index=\"%d\" Bitrate=\"%d\" "
|
||||
"FourCC=\"%s\" MaxWidth=\"%d\" MaxHeight=\"%d\" "
|
||||
"CodecPrivateData=\"",
|
||||
index, vf->bitrate, vf->fourcc, vf->width, vf->height);
|
||||
for (j = 0; j < vf->codec_private_size; j++)
|
||||
fprintf(out, "%02X", vf->codec_private[j]);
|
||||
fprintf(out, "\" />\n");
|
||||
index++;
|
||||
}
|
||||
vf = files->files[files->video_file];
|
||||
for (i = 0; i < vf->chunks; i++)
|
||||
fprintf(out, "\t\t<c n=\"%d\" d=\"%d\" />\n", i,
|
||||
vf->offsets[i].duration);
|
||||
fprintf(out, "\t</StreamIndex>\n");
|
||||
}
|
||||
if (files->audio_file >= 0) {
|
||||
struct VideoFile *vf = files->files[files->audio_file];
|
||||
int index = 0;
|
||||
fprintf(out,
|
||||
"\t<StreamIndex Type=\"audio\" QualityLevels=\"%d\" "
|
||||
"Chunks=\"%d\" "
|
||||
"Url=\"QualityLevels({bitrate})/Fragments(audio={start time})\">\n",
|
||||
files->nb_audio_files, vf->chunks);
|
||||
for (i = 0; i < files->nb_files; i++) {
|
||||
vf = files->files[i];
|
||||
if (!vf->is_audio)
|
||||
continue;
|
||||
fprintf(out,
|
||||
"\t\t<QualityLevel Index=\"%d\" Bitrate=\"%d\" "
|
||||
"FourCC=\"%s\" SamplingRate=\"%d\" Channels=\"%d\" "
|
||||
"BitsPerSample=\"16\" PacketSize=\"%d\" "
|
||||
"AudioTag=\"%d\" CodecPrivateData=\"",
|
||||
index, vf->bitrate, vf->fourcc, vf->sample_rate,
|
||||
vf->channels, vf->blocksize, vf->tag);
|
||||
for (j = 0; j < vf->codec_private_size; j++)
|
||||
fprintf(out, "%02X", vf->codec_private[j]);
|
||||
fprintf(out, "\" />\n");
|
||||
index++;
|
||||
}
|
||||
vf = files->files[files->audio_file];
|
||||
for (i = 0; i < vf->chunks; i++)
|
||||
fprintf(out, "\t\t<c n=\"%d\" d=\"%d\" />\n",
|
||||
i, vf->offsets[i].duration);
|
||||
fprintf(out, "\t</StreamIndex>\n");
|
||||
}
|
||||
fprintf(out, "</SmoothStreamingMedia>\n");
|
||||
fclose(out);
|
||||
}
|
||||
|
||||
static void clean_files(struct VideoFiles *files)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < files->nb_files; i++) {
|
||||
av_freep(&files->files[i]->codec_private);
|
||||
av_freep(&files->files[i]->offsets);
|
||||
av_freep(&files->files[i]);
|
||||
}
|
||||
av_freep(&files->files);
|
||||
files->nb_files = 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char *basename = NULL;
|
||||
int split = 0, i;
|
||||
struct VideoFiles vf = { 0, .video_file = -1, .audio_file = -1 };
|
||||
|
||||
av_register_all();
|
||||
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (!strcmp(argv[i], "-n")) {
|
||||
basename = argv[i + 1];
|
||||
i++;
|
||||
} else if (!strcmp(argv[i], "-split")) {
|
||||
split = 1;
|
||||
} else if (argv[i][0] == '-') {
|
||||
return usage(argv[0], 1);
|
||||
} else {
|
||||
handle_file(&vf, argv[i], split);
|
||||
}
|
||||
}
|
||||
if (!vf.nb_files || (!basename && !split))
|
||||
return usage(argv[0], 1);
|
||||
|
||||
if (!split)
|
||||
output_server_manifest(&vf, basename);
|
||||
output_client_manifest(&vf, basename, split);
|
||||
|
||||
clean_files(&vf);
|
||||
|
||||
return 0;
|
||||
}
|
@ -97,11 +97,13 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
if (avfilter_open(&filter_ctx, filter, NULL) < 0) {
|
||||
fprintf(stderr, "Inpossible to open filter with name '%s'\n", filter_name);
|
||||
fprintf(stderr, "Inpossible to open filter with name '%s'\n",
|
||||
filter_name);
|
||||
return 1;
|
||||
}
|
||||
if (avfilter_init_filter(filter_ctx, filter_args, NULL) < 0) {
|
||||
fprintf(stderr, "Impossible to init filter '%s' with arguments '%s'\n", filter_name, filter_args);
|
||||
fprintf(stderr, "Impossible to init filter '%s' with arguments '%s'\n",
|
||||
filter_name, filter_args);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -24,11 +24,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "libavformat/avformat.h"
|
||||
|
||||
#define PKTFILESUFF "_%08"PRId64"_%02d_%010"PRId64"_%06d_%c.bin"
|
||||
|
||||
#undef strcat
|
||||
#define PKTFILESUFF "_%08" PRId64 "_%02d_%010" PRId64 "_%06d_%c.bin"
|
||||
|
||||
static int usage(int ret)
|
||||
{
|
||||
@ -46,10 +45,10 @@ int main(int argc, char **argv)
|
||||
char pktfilename[PATH_MAX];
|
||||
AVFormatContext *fctx = NULL;
|
||||
AVPacket pkt;
|
||||
int64_t pktnum = 0;
|
||||
int64_t pktnum = 0;
|
||||
int64_t maxpkts = 0;
|
||||
int donotquit = 0;
|
||||
int nowrite = 0;
|
||||
int donotquit = 0;
|
||||
int nowrite = 0;
|
||||
int err;
|
||||
|
||||
if ((argc > 1) && !strncmp(argv[1], "-", 1)) {
|
||||
@ -64,16 +63,16 @@ int main(int argc, char **argv)
|
||||
return usage(1);
|
||||
if (argc > 2)
|
||||
maxpkts = atoi(argv[2]);
|
||||
strncpy(fntemplate, argv[1], PATH_MAX-1);
|
||||
strncpy(fntemplate, argv[1], PATH_MAX - 1);
|
||||
if (strrchr(argv[1], '/'))
|
||||
strncpy(fntemplate, strrchr(argv[1], '/')+1, PATH_MAX-1);
|
||||
strncpy(fntemplate, strrchr(argv[1], '/') + 1, PATH_MAX - 1);
|
||||
if (strrchr(fntemplate, '.'))
|
||||
*strrchr(fntemplate, '.') = '\0';
|
||||
if (strchr(fntemplate, '%')) {
|
||||
fprintf(stderr, "can't use filenames containing '%%'\n");
|
||||
return usage(1);
|
||||
}
|
||||
if (strlen(fntemplate) + sizeof(PKTFILESUFF) >= PATH_MAX-1) {
|
||||
if (strlen(fntemplate) + sizeof(PKTFILESUFF) >= PATH_MAX - 1) {
|
||||
fprintf(stderr, "filename too long\n");
|
||||
return usage(1);
|
||||
}
|
||||
@ -99,11 +98,14 @@ int main(int argc, char **argv)
|
||||
|
||||
while ((err = av_read_frame(fctx, &pkt)) >= 0) {
|
||||
int fd;
|
||||
snprintf(pktfilename, PATH_MAX-1, fntemplate, pktnum, pkt.stream_index, pkt.pts, pkt.size, (pkt.flags & AV_PKT_FLAG_KEY)?'K':'_');
|
||||
printf(PKTFILESUFF"\n", pktnum, pkt.stream_index, pkt.pts, pkt.size, (pkt.flags & AV_PKT_FLAG_KEY)?'K':'_');
|
||||
snprintf(pktfilename, PATH_MAX - 1, fntemplate, pktnum,
|
||||
pkt.stream_index, pkt.pts, pkt.size,
|
||||
(pkt.flags & AV_PKT_FLAG_KEY) ? 'K' : '_');
|
||||
printf(PKTFILESUFF "\n", pktnum, pkt.stream_index, pkt.pts, pkt.size,
|
||||
(pkt.flags & AV_PKT_FLAG_KEY) ? 'K' : '_');
|
||||
//printf("open(\"%s\")\n", pktfilename);
|
||||
if (!nowrite) {
|
||||
fd = open(pktfilename, O_WRONLY|O_CREAT, 0644);
|
||||
fd = open(pktfilename, O_WRONLY | O_CREAT, 0644);
|
||||
err = write(fd, pkt.data, pkt.size);
|
||||
if (err < 0) {
|
||||
fprintf(stderr, "write: error %d\n", err);
|
||||
@ -120,7 +122,7 @@ int main(int argc, char **argv)
|
||||
avformat_close_input(&fctx);
|
||||
|
||||
while (donotquit)
|
||||
sleep(60);
|
||||
usleep(60 * 1000000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -39,7 +39,8 @@ static void probe(AVProbeData *pd, int type, int p, int size)
|
||||
int score = fmt->read_probe(pd);
|
||||
if (score > score_array[i] && score > AVPROBE_SCORE_MAX / 4) {
|
||||
score_array[i] = score;
|
||||
fprintf(stderr, "Failure of %s probing code with score=%d type=%d p=%X size=%d\n",
|
||||
fprintf(stderr,
|
||||
"Failure of %s probing code with score=%d type=%d p=%X size=%d\n",
|
||||
fmt->name, score, type, p, size);
|
||||
failures++;
|
||||
}
|
||||
@ -75,9 +76,8 @@ int main(void)
|
||||
init_put_bits(&pb, pd.buf, size);
|
||||
switch (type) {
|
||||
case 0:
|
||||
for (i = 0; i < size * 8; i++) {
|
||||
for (i = 0; i < size * 8; i++)
|
||||
put_bits(&pb, 1, (av_lfg_get(&state) & 0xFFFFFFFF) > p << 20);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
for (i = 0; i < size * 8; i++) {
|
||||
@ -89,10 +89,10 @@ int main(void)
|
||||
break;
|
||||
case 2:
|
||||
for (i = 0; i < size * 8; i++) {
|
||||
unsigned int p2 = (p >> (hist*3)) & 7;
|
||||
unsigned int p2 = (p >> (hist * 3)) & 7;
|
||||
unsigned int v = (av_lfg_get(&state) & 0xFFFFFFFF) > p2 << 29;
|
||||
put_bits(&pb, 1, v);
|
||||
hist = (2*hist + v) & 3;
|
||||
hist = (2 * hist + v) & 3;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
@ -100,12 +100,18 @@ int main(void)
|
||||
int c = 0;
|
||||
while (p & 63) {
|
||||
c = (av_lfg_get(&state) & 0xFFFFFFFF) >> 24;
|
||||
if (c >= 'a' && c <= 'z' && (p & 1)) break;
|
||||
else if(c >= 'A' && c <= 'Z' && (p & 2)) break;
|
||||
else if(c >= '0' && c <= '9' && (p & 4)) break;
|
||||
else if(c == ' ' && (p & 8)) break;
|
||||
else if(c == 0 && (p & 16)) break;
|
||||
else if(c == 1 && (p & 32)) break;
|
||||
if (c >= 'a' && c <= 'z' && (p & 1))
|
||||
break;
|
||||
else if (c >= 'A' && c <= 'Z' && (p & 2))
|
||||
break;
|
||||
else if (c >= '0' && c <= '9' && (p & 4))
|
||||
break;
|
||||
else if (c == ' ' && (p & 8))
|
||||
break;
|
||||
else if (c == 0 && (p & 16))
|
||||
break;
|
||||
else if (c == 1 && (p & 32))
|
||||
break;
|
||||
}
|
||||
pd.buf[i] = c;
|
||||
}
|
||||
|
@ -138,7 +138,6 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
start_offset = ftello(infile);
|
||||
} else {
|
||||
|
||||
/* 64-bit special case */
|
||||
if (atom_size == 1) {
|
||||
if (fread(atom_bytes, ATOM_PREAMBLE_SIZE, 1, infile) != 1) {
|
||||
|
@ -23,47 +23,50 @@
|
||||
#include <inttypes.h>
|
||||
|
||||
static uint32_t state;
|
||||
static uint32_t ran(void){
|
||||
return state= state*1664525+1013904223;
|
||||
static uint32_t ran(void)
|
||||
{
|
||||
return state = state * 1664525 + 1013904223;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
FILE *f;
|
||||
int count, maxburst, length;
|
||||
|
||||
if (argc < 5){
|
||||
if (argc < 5) {
|
||||
printf("USAGE: trasher <filename> <count> <maxburst> <seed>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
f= fopen(argv[1], "rb+");
|
||||
if (!f){
|
||||
f = fopen(argv[1], "rb+");
|
||||
if (!f) {
|
||||
perror(argv[1]);
|
||||
return 2;
|
||||
}
|
||||
count= atoi(argv[2]);
|
||||
maxburst= atoi(argv[3]);
|
||||
state= atoi(argv[4]);
|
||||
count = atoi(argv[2]);
|
||||
maxburst = atoi(argv[3]);
|
||||
state = atoi(argv[4]);
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
length= ftell(f);
|
||||
length = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
while(count--){
|
||||
int burst= 1 + ran() * (uint64_t) (abs(maxburst)-1) / UINT32_MAX;
|
||||
int pos= ran() * (uint64_t) length / UINT32_MAX;
|
||||
while (count--) {
|
||||
int burst = 1 + ran() * (uint64_t) (abs(maxburst) - 1) / UINT32_MAX;
|
||||
int pos = ran() * (uint64_t) length / UINT32_MAX;
|
||||
fseek(f, pos, SEEK_SET);
|
||||
|
||||
if(maxburst<0) burst= -maxburst;
|
||||
if (maxburst < 0)
|
||||
burst = -maxburst;
|
||||
|
||||
if(pos + burst > length)
|
||||
if (pos + burst > length)
|
||||
continue;
|
||||
|
||||
while(burst--){
|
||||
int val= ran() * 256ULL / UINT32_MAX;
|
||||
while (burst--) {
|
||||
int val = ran() * 256ULL / UINT32_MAX;
|
||||
|
||||
if(maxburst<0) val=0;
|
||||
if (maxburst < 0)
|
||||
val = 0;
|
||||
|
||||
fwrite(&val, 1, 1, f);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user