mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-28 20:53:54 +02:00
Merge remote-tracking branch 'qatar/master'
* qatar/master: mov: Use defines for sample flags in fragments mov: Use defines for trun flags mov: Use defines for tfhd flags proresenc: force bitrate not to exceed given limit vc1parse: call vc1_init_common(). wma: don't return 0 on invalid packets. asf: prevent packet_size_left from going negative if hdrlen > pktlen. mjpegb: don't return 0 at the end of frame decoding. rtpdec: Identify incorrectly signalled H263 vp8dsp: split long line. aiff: don't skip block_align==0 check on COMM-after-SSND files. dpcm: ignore extra unpaired bytes in stereo streams. mp3on4: require a minimum framesize. mpc7: assign an error level + context to av_log() msg. huffyuv: error out on bit overrun. dct-test: Add the missing ff_ prefix to the altivec functions dct-test: Remove a stray declaration of a nonexistent function movenc: Write the unknown duration as 64 bit fields in ismv movenc: Write track durations with all bits set if duration is unknown Conflicts: libavcodec/dct-test.c libavcodec/wmadec.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
4a519b6e03
@ -54,7 +54,7 @@ void ff_bfin_fdct(DCTELEM *block);
|
||||
|
||||
// ALTIVEC
|
||||
void ff_fdct_altivec(DCTELEM *block);
|
||||
//void idct_altivec(DCTELEM *block);?? no routine
|
||||
//void ff_idct_altivec(DCTELEM *block);?? no routine
|
||||
|
||||
// ARM
|
||||
void ff_j_rev_dct_arm(DCTELEM *data);
|
||||
|
@ -183,6 +183,11 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
|
||||
int stereo = s->channels - 1;
|
||||
int16_t *output_samples;
|
||||
|
||||
if (stereo && (buf_size & 1)) {
|
||||
buf_size--;
|
||||
buf_end--;
|
||||
}
|
||||
|
||||
/* calculate output size */
|
||||
switch(avctx->codec->id) {
|
||||
case CODEC_ID_ROQ_DPCM:
|
||||
@ -320,7 +325,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
|
||||
*got_frame_ptr = 1;
|
||||
*(AVFrame *)data = s->frame;
|
||||
|
||||
return buf_size;
|
||||
return avpkt->size;
|
||||
}
|
||||
|
||||
#define DPCM_DECODER(id_, name_, long_name_) \
|
||||
|
@ -212,7 +212,7 @@ static int read_len_table(uint8_t *dst, GetBitContext *gb){
|
||||
if(repeat==0)
|
||||
repeat= get_bits(gb, 8);
|
||||
//printf("%d %d\n", val, repeat);
|
||||
if(i+repeat > 256) {
|
||||
if(i+repeat > 256 || get_bits_left(gb) < 0) {
|
||||
av_log(NULL, AV_LOG_ERROR, "Error reading huffman table\n");
|
||||
return -1;
|
||||
}
|
||||
|
@ -69,7 +69,7 @@ read_header:
|
||||
if (get_bits_long(&hgb, 32) != MKBETAG('m','j','p','g'))
|
||||
{
|
||||
av_log(avctx, AV_LOG_WARNING, "not mjpeg-b (bad fourcc)\n");
|
||||
return 0;
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
field_size = get_bits_long(&hgb, 32); /* field size */
|
||||
@ -149,7 +149,7 @@ read_header:
|
||||
picture->quality*= FF_QP2LAMBDA;
|
||||
}
|
||||
|
||||
return buf_ptr - buf;
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
AVCodec ff_mjpegb_decoder = {
|
||||
|
@ -298,7 +298,7 @@ static int mpc7_decode_frame(AVCodecContext * avctx, void *data,
|
||||
bits_used = get_bits_count(&gb);
|
||||
bits_avail = buf_size * 8;
|
||||
if (!last_frame && ((bits_avail < bits_used) || (bits_used + 32 <= bits_avail))) {
|
||||
av_log(NULL,0, "Error decoding frame: used %i of %i bits\n", bits_used, bits_avail);
|
||||
av_log(avctx, AV_LOG_ERROR, "Error decoding frame: used %i of %i bits\n", bits_used, bits_avail);
|
||||
return -1;
|
||||
}
|
||||
if(c->frames_to_skip){
|
||||
|
@ -1914,6 +1914,10 @@ static int decode_frame_mp3on4(AVCodecContext *avctx, void *data,
|
||||
m = s->mp3decctx[fr];
|
||||
assert(m != NULL);
|
||||
|
||||
if (fsize < HEADER_SIZE) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Frame size smaller than header size\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
header = (AV_RB32(buf) & 0x000fffff) | s->syncword; // patch header
|
||||
|
||||
if (ff_mpa_check_header(header) < 0) // Bad header, discard block
|
||||
|
@ -139,11 +139,14 @@ struct TrellisNode {
|
||||
int score;
|
||||
};
|
||||
|
||||
#define MAX_STORED_Q 16
|
||||
|
||||
typedef struct ProresContext {
|
||||
AVClass *class;
|
||||
DECLARE_ALIGNED(16, DCTELEM, blocks)[MAX_PLANES][64 * 4 * MAX_MBS_PER_SLICE];
|
||||
DECLARE_ALIGNED(16, uint16_t, emu_buf)[16*16];
|
||||
int16_t quants[16][64];
|
||||
int16_t quants[MAX_STORED_Q][64];
|
||||
int16_t custom_q[64];
|
||||
|
||||
ProresDSPContext dsp;
|
||||
ScanTable scantable;
|
||||
@ -156,6 +159,8 @@ typedef struct ProresContext {
|
||||
int num_planes;
|
||||
int bits_per_mb;
|
||||
|
||||
int frame_size;
|
||||
|
||||
int profile;
|
||||
const struct prores_profile *profile_info;
|
||||
|
||||
@ -348,6 +353,15 @@ static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
|
||||
int slice_width_factor = av_log2(mbs_per_slice);
|
||||
int num_cblocks, pwidth;
|
||||
int plane_factor, is_chroma;
|
||||
uint16_t *qmat;
|
||||
|
||||
if (quant < MAX_STORED_Q) {
|
||||
qmat = ctx->quants[quant];
|
||||
} else {
|
||||
qmat = ctx->custom_q;
|
||||
for (i = 0; i < 64; i++)
|
||||
qmat[i] = ctx->profile_info->quant[i] * quant;
|
||||
}
|
||||
|
||||
for (i = 0; i < ctx->num_planes; i++) {
|
||||
is_chroma = (i == 1 || i == 2);
|
||||
@ -373,7 +387,7 @@ static int encode_slice(AVCodecContext *avctx, const AVFrame *pic,
|
||||
sizes[i] = encode_slice_plane(ctx, pb, src, pic->linesize[i],
|
||||
mbs_per_slice, ctx->blocks[0],
|
||||
num_cblocks, plane_factor,
|
||||
ctx->quants[quant]);
|
||||
qmat);
|
||||
total_size += sizes[i];
|
||||
}
|
||||
return total_size;
|
||||
@ -500,6 +514,8 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
|
||||
int error, bits, bits_limit;
|
||||
int mbs, prev, cur, new_score;
|
||||
int slice_bits[TRELLIS_WIDTH], slice_score[TRELLIS_WIDTH];
|
||||
int overquant;
|
||||
uint16_t *qmat;
|
||||
|
||||
mbs = x + mbs_per_slice;
|
||||
|
||||
@ -526,7 +542,7 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
|
||||
mbs_per_slice, num_cblocks[i]);
|
||||
}
|
||||
|
||||
for (q = min_quant; q <= max_quant; q++) {
|
||||
for (q = min_quant; q < max_quant + 2; q++) {
|
||||
ctx->nodes[trellis_node + q].prev_node = -1;
|
||||
ctx->nodes[trellis_node + q].quant = q;
|
||||
}
|
||||
@ -549,12 +565,43 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
|
||||
slice_bits[q] = bits;
|
||||
slice_score[q] = error;
|
||||
}
|
||||
if (slice_bits[max_quant] <= ctx->bits_per_mb * mbs_per_slice) {
|
||||
slice_bits[max_quant + 1] = slice_bits[max_quant];
|
||||
slice_score[max_quant + 1] = slice_score[max_quant] + 1;
|
||||
overquant = max_quant;
|
||||
} else {
|
||||
for (q = max_quant + 1; q < 128; q++) {
|
||||
bits = 0;
|
||||
error = 0;
|
||||
if (q < MAX_STORED_Q) {
|
||||
qmat = ctx->quants[q];
|
||||
} else {
|
||||
qmat = ctx->custom_q;
|
||||
for (i = 0; i < 64; i++)
|
||||
qmat[i] = ctx->profile_info->quant[i] * q;
|
||||
}
|
||||
for (i = 0; i < ctx->num_planes; i++) {
|
||||
bits += estimate_slice_plane(ctx, &error, i,
|
||||
src, pic->linesize[i],
|
||||
mbs_per_slice,
|
||||
num_cblocks[i], plane_factor[i],
|
||||
qmat);
|
||||
}
|
||||
if (bits <= ctx->bits_per_mb * mbs_per_slice)
|
||||
break;
|
||||
}
|
||||
|
||||
slice_bits[max_quant + 1] = bits;
|
||||
slice_score[max_quant + 1] = error;
|
||||
overquant = q;
|
||||
}
|
||||
ctx->nodes[trellis_node + max_quant + 1].quant = overquant;
|
||||
|
||||
bits_limit = mbs * ctx->bits_per_mb;
|
||||
for (pq = min_quant; pq <= max_quant; pq++) {
|
||||
for (pq = min_quant; pq < max_quant + 2; pq++) {
|
||||
prev = trellis_node - TRELLIS_WIDTH + pq;
|
||||
|
||||
for (q = min_quant; q <= max_quant; q++) {
|
||||
for (q = min_quant; q < max_quant + 2; q++) {
|
||||
cur = trellis_node + q;
|
||||
|
||||
bits = ctx->nodes[prev].bits + slice_bits[q];
|
||||
@ -578,7 +625,7 @@ static int find_slice_quant(AVCodecContext *avctx, const AVFrame *pic,
|
||||
|
||||
error = ctx->nodes[trellis_node + min_quant].score;
|
||||
pq = trellis_node + min_quant;
|
||||
for (q = min_quant + 1; q <= max_quant; q++) {
|
||||
for (q = min_quant + 1; q < max_quant + 2; q++) {
|
||||
if (ctx->nodes[trellis_node + q].score <= error) {
|
||||
error = ctx->nodes[trellis_node + q].score;
|
||||
pq = trellis_node + q;
|
||||
@ -606,8 +653,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,
|
||||
avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;
|
||||
avctx->coded_frame->key_frame = 1;
|
||||
|
||||
pkt_size = ctx->mb_width * ctx->mb_height * 64 * 3 * 12
|
||||
+ ctx->num_slices * 2 + 200 + FF_MIN_BUFFER_SIZE;
|
||||
pkt_size = ctx->frame_size + FF_MIN_BUFFER_SIZE;
|
||||
|
||||
if ((ret = ff_alloc_packet(pkt, pkt_size)) < 0) {
|
||||
av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");
|
||||
@ -762,9 +808,13 @@ static av_cold int encode_init(AVCodecContext *avctx)
|
||||
break;
|
||||
ctx->bits_per_mb = ctx->profile_info->br_tab[i];
|
||||
|
||||
ctx->frame_size = ctx->num_slices * (2 + 2 * ctx->num_planes
|
||||
+ (2 * mps * ctx->bits_per_mb) / 8)
|
||||
+ 200;
|
||||
|
||||
min_quant = ctx->profile_info->min_quant;
|
||||
max_quant = ctx->profile_info->max_quant;
|
||||
for (i = min_quant; i <= max_quant; i++) {
|
||||
for (i = min_quant; i < MAX_STORED_Q; i++) {
|
||||
for (j = 0; j < 64; j++)
|
||||
ctx->quants[i][j] = ctx->profile_info->quant[j] * i;
|
||||
}
|
||||
@ -773,6 +823,8 @@ static av_cold int encode_init(AVCodecContext *avctx)
|
||||
|
||||
av_log(avctx, AV_LOG_DEBUG, "profile %d, %d slices, %d bits per MB\n",
|
||||
ctx->profile, ctx->num_slices, ctx->bits_per_mb);
|
||||
av_log(avctx, AV_LOG_DEBUG, "estimated frame size %d\n",
|
||||
ctx->frame_size);
|
||||
|
||||
ctx->nodes = av_malloc((ctx->slices_width + 1) * TRELLIS_WIDTH
|
||||
* sizeof(*ctx->nodes));
|
||||
@ -780,7 +832,7 @@ static av_cold int encode_init(AVCodecContext *avctx)
|
||||
encode_close(avctx);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
for (i = min_quant; i <= max_quant; i++) {
|
||||
for (i = min_quant; i < max_quant + 2; i++) {
|
||||
ctx->nodes[i].prev_node = -1;
|
||||
ctx->nodes[i].bits = 0;
|
||||
ctx->nodes[i].score = 0;
|
||||
|
@ -447,5 +447,6 @@ int ff_vc1_decode_entry_point(AVCodecContext *avctx, VC1Context *v, GetBitContex
|
||||
|
||||
int ff_vc1_parse_frame_header (VC1Context *v, GetBitContext *gb);
|
||||
int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext *gb);
|
||||
int ff_vc1_init_common(VC1Context *v);
|
||||
|
||||
#endif /* AVCODEC_VC1_H */
|
||||
|
@ -188,7 +188,7 @@ static int vc1_parse_init(AVCodecParserContext *s)
|
||||
{
|
||||
VC1ParseContext *vpc = s->priv_data;
|
||||
vpc->v.s.slice_context_count = 1;
|
||||
return 0;
|
||||
return ff_vc1_init_common(&vpc->v);
|
||||
}
|
||||
|
||||
AVCodecParser ff_vc1_parser = {
|
||||
|
@ -67,7 +67,7 @@ static const int offset_table2[9] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
|
||||
* @param v The VC1Context to initialize
|
||||
* @return Status
|
||||
*/
|
||||
static int vc1_init_common(VC1Context *v)
|
||||
int ff_vc1_init_common(VC1Context *v)
|
||||
{
|
||||
static int done = 0;
|
||||
int i = 0;
|
||||
@ -5274,7 +5274,7 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx)
|
||||
avctx->idct_algo = FF_IDCT_WMV2;
|
||||
}
|
||||
|
||||
if (vc1_init_common(v) < 0)
|
||||
if (ff_vc1_init_common(v) < 0)
|
||||
return -1;
|
||||
ff_vc1dsp_init(&v->vc1dsp);
|
||||
|
||||
|
@ -29,7 +29,9 @@
|
||||
|
||||
#include "dsputil.h"
|
||||
|
||||
typedef void (*vp8_mc_func)(uint8_t *dst/*align 8*/, int dstStride, uint8_t *src/*align 1*/, int srcStride, int h, int x, int y);
|
||||
typedef void (*vp8_mc_func)(uint8_t *dst/*align 8*/, int dstStride,
|
||||
uint8_t *src/*align 1*/, int srcStride,
|
||||
int h, int x, int y);
|
||||
|
||||
typedef struct VP8DSPContext {
|
||||
void (*vp8_luma_dc_wht)(DCTELEM block[4][4][16], DCTELEM dc[16]);
|
||||
|
@ -834,8 +834,12 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data,
|
||||
s->last_superframe_len = 0;
|
||||
return 0;
|
||||
}
|
||||
if (buf_size < s->block_align)
|
||||
return AVERROR(EINVAL);
|
||||
if (buf_size < s->block_align) {
|
||||
av_log(avctx, AV_LOG_ERROR,
|
||||
"Input packet size too small (%d < %d)\n",
|
||||
buf_size, s->block_align);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
if(s->block_align)
|
||||
buf_size = s->block_align;
|
||||
|
||||
|
@ -270,12 +270,12 @@ static int aiff_read_header(AVFormatContext *s)
|
||||
}
|
||||
}
|
||||
|
||||
got_sound:
|
||||
if (!st->codec->block_align) {
|
||||
av_log(s, AV_LOG_ERROR, "could not find COMM tag\n");
|
||||
av_log(s, AV_LOG_ERROR, "could not find COMM tag or invalid block_align value\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
got_sound:
|
||||
/* Now positioned, get the sound data start and end */
|
||||
avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate);
|
||||
st->start_time = 0;
|
||||
|
@ -797,6 +797,13 @@ static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb)
|
||||
asf->packet_segments = 1;
|
||||
asf->packet_segsizetype = 0x80;
|
||||
}
|
||||
if (rsize > packet_length - padsize) {
|
||||
asf->packet_size_left = 0;
|
||||
av_log(s, AV_LOG_ERROR,
|
||||
"invalid packet header length %d for pktlen %d-%d at %"PRId64"\n",
|
||||
rsize, packet_length, padsize, avio_tell(pb));
|
||||
return -1;
|
||||
}
|
||||
asf->packet_size_left = packet_length - padsize - rsize;
|
||||
if (packet_length < asf->hdr.min_pktsize)
|
||||
padsize += asf->hdr.min_pktsize - packet_length;
|
||||
|
@ -162,6 +162,30 @@ void ff_mp4_parse_es_descr(AVIOContext *pb, int *es_id);
|
||||
#define MP4DecSpecificDescrTag 0x05
|
||||
#define MP4SLDescrTag 0x06
|
||||
|
||||
#define MOV_TFHD_BASE_DATA_OFFSET 0x01
|
||||
#define MOV_TFHD_STSD_ID 0x02
|
||||
#define MOV_TFHD_DEFAULT_DURATION 0x08
|
||||
#define MOV_TFHD_DEFAULT_SIZE 0x10
|
||||
#define MOV_TFHD_DEFAULT_FLAGS 0x20
|
||||
#define MOV_TFHD_DURATION_IS_EMPTY 0x010000
|
||||
|
||||
#define MOV_TRUN_DATA_OFFSET 0x01
|
||||
#define MOV_TRUN_FIRST_SAMPLE_FLAGS 0x04
|
||||
#define MOV_TRUN_SAMPLE_DURATION 0x100
|
||||
#define MOV_TRUN_SAMPLE_SIZE 0x200
|
||||
#define MOV_TRUN_SAMPLE_FLAGS 0x400
|
||||
#define MOV_TRUN_SAMPLE_CTS 0x800
|
||||
|
||||
#define MOV_FRAG_SAMPLE_FLAG_DEGRADATION_PRIORITY_MASK 0x0000ffff
|
||||
#define MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC 0x00010000
|
||||
#define MOV_FRAG_SAMPLE_FLAG_PADDING_MASK 0x000e0000
|
||||
#define MOV_FRAG_SAMPLE_FLAG_REDUNDANCY_MASK 0x00300000
|
||||
#define MOV_FRAG_SAMPLE_FLAG_DEPENDED_MASK 0x00c00000
|
||||
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_MASK 0x03000000
|
||||
|
||||
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO 0x02000000
|
||||
#define MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES 0x01000000
|
||||
|
||||
int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb, MOVAtom atom);
|
||||
enum CodecID ff_mov_get_lpcm_codec_id(int bps, int flags);
|
||||
|
||||
|
@ -2257,14 +2257,16 @@ static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
if (flags & 0x01) frag->base_data_offset = avio_rb64(pb);
|
||||
else frag->base_data_offset = frag->moof_offset;
|
||||
if (flags & 0x02) frag->stsd_id = avio_rb32(pb);
|
||||
else frag->stsd_id = trex->stsd_id;
|
||||
frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
|
||||
avio_rb64(pb) : frag->moof_offset;
|
||||
frag->stsd_id = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;
|
||||
|
||||
frag->duration = flags & 0x08 ? avio_rb32(pb) : trex->duration;
|
||||
frag->size = flags & 0x10 ? avio_rb32(pb) : trex->size;
|
||||
frag->flags = flags & 0x20 ? avio_rb32(pb) : trex->flags;
|
||||
frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
|
||||
avio_rb32(pb) : trex->duration;
|
||||
frag->size = flags & MOV_TFHD_DEFAULT_SIZE ?
|
||||
avio_rb32(pb) : trex->size;
|
||||
frag->flags = flags & MOV_TFHD_DEFAULT_FLAGS ?
|
||||
avio_rb32(pb) : trex->flags;
|
||||
av_dlog(c->fc, "frag flags 0x%x\n", frag->flags);
|
||||
return 0;
|
||||
}
|
||||
@ -2353,8 +2355,8 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
return AVERROR(ENOMEM);
|
||||
sc->ctts_data = ctts_data;
|
||||
|
||||
if (flags & 0x001) data_offset = avio_rb32(pb);
|
||||
if (flags & 0x004) first_sample_flags = avio_rb32(pb);
|
||||
if (flags & MOV_TRUN_DATA_OFFSET) data_offset = avio_rb32(pb);
|
||||
if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
|
||||
dts = sc->track_end - sc->time_offset;
|
||||
offset = frag->base_data_offset + data_offset;
|
||||
distance = 0;
|
||||
@ -2365,14 +2367,15 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
unsigned sample_duration = frag->duration;
|
||||
int keyframe;
|
||||
|
||||
if (flags & 0x100) sample_duration = avio_rb32(pb);
|
||||
if (flags & 0x200) sample_size = avio_rb32(pb);
|
||||
if (flags & 0x400) sample_flags = avio_rb32(pb);
|
||||
if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
|
||||
if (flags & MOV_TRUN_SAMPLE_SIZE) sample_size = avio_rb32(pb);
|
||||
if (flags & MOV_TRUN_SAMPLE_FLAGS) sample_flags = avio_rb32(pb);
|
||||
sc->ctts_data[sc->ctts_count].count = 1;
|
||||
sc->ctts_data[sc->ctts_count].duration = (flags & 0x800) ? avio_rb32(pb) : 0;
|
||||
sc->ctts_data[sc->ctts_count].duration = (flags & MOV_TRUN_SAMPLE_CTS) ?
|
||||
avio_rb32(pb) : 0;
|
||||
sc->ctts_count++;
|
||||
if ((keyframe = st->codec->codec_type == AVMEDIA_TYPE_AUDIO ||
|
||||
(flags & 0x004 && !i && !(sample_flags & 0xffff0000)) || sample_flags & 0x2000000))
|
||||
(flags & MOV_TRUN_FIRST_SAMPLE_FLAGS && !i && !(sample_flags & ~MOV_FRAG_SAMPLE_FLAG_DEGRADATION_PRIORITY_MASK)) || sample_flags & MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO))
|
||||
distance = 0;
|
||||
av_add_index_entry(st, offset, dts, sample_size, distance,
|
||||
keyframe ? AVINDEX_KEYFRAME : 0);
|
||||
|
@ -1342,6 +1342,9 @@ static int mov_write_mdhd_tag(AVIOContext *pb, MOVTrack *track)
|
||||
{
|
||||
int version = track->track_duration < INT32_MAX ? 0 : 1;
|
||||
|
||||
if (track->mode == MODE_ISM)
|
||||
version = 1;
|
||||
|
||||
(version == 1) ? avio_wb32(pb, 44) : avio_wb32(pb, 32); /* size */
|
||||
ffio_wfourcc(pb, "mdhd");
|
||||
avio_w8(pb, version);
|
||||
@ -1354,7 +1357,10 @@ static int mov_write_mdhd_tag(AVIOContext *pb, MOVTrack *track)
|
||||
avio_wb32(pb, track->time); /* modification time */
|
||||
}
|
||||
avio_wb32(pb, track->timescale); /* time scale (sample rate for audio) */
|
||||
(version == 1) ? avio_wb64(pb, track->track_duration) : avio_wb32(pb, track->track_duration); /* duration */
|
||||
if (!track->entry)
|
||||
(version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
|
||||
else
|
||||
(version == 1) ? avio_wb64(pb, track->track_duration) : avio_wb32(pb, track->track_duration); /* duration */
|
||||
avio_wb16(pb, track->language); /* language */
|
||||
avio_wb16(pb, 0); /* reserved (quality) */
|
||||
|
||||
@ -1385,6 +1391,9 @@ static int mov_write_tkhd_tag(AVIOContext *pb, MOVTrack *track, AVStream *st)
|
||||
track->timescale, AV_ROUND_UP);
|
||||
int version = duration < INT32_MAX ? 0 : 1;
|
||||
|
||||
if (track->mode == MODE_ISM)
|
||||
version = 1;
|
||||
|
||||
(version == 1) ? avio_wb32(pb, 104) : avio_wb32(pb, 92); /* size */
|
||||
ffio_wfourcc(pb, "tkhd");
|
||||
avio_w8(pb, version);
|
||||
@ -1398,7 +1407,10 @@ static int mov_write_tkhd_tag(AVIOContext *pb, MOVTrack *track, AVStream *st)
|
||||
}
|
||||
avio_wb32(pb, track->track_id); /* track-id */
|
||||
avio_wb32(pb, 0); /* reserved */
|
||||
(version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration);
|
||||
if (!track->entry)
|
||||
(version == 1) ? avio_wb64(pb, UINT64_C(0xffffffffffffffff)) : avio_wb32(pb, 0xffffffff);
|
||||
else
|
||||
(version == 1) ? avio_wb64(pb, duration) : avio_wb32(pb, duration);
|
||||
|
||||
avio_wb32(pb, 0); /* reserved */
|
||||
avio_wb32(pb, 0); /* reserved */
|
||||
@ -2225,19 +2237,19 @@ static int mov_write_tfhd_tag(AVIOContext *pb, MOVTrack *track,
|
||||
int64_t moof_offset)
|
||||
{
|
||||
int64_t pos = avio_tell(pb);
|
||||
/* default-sample-size + default-sample-duration + base-data-offset */
|
||||
uint32_t flags = 0x19;
|
||||
uint32_t flags = MOV_TFHD_DEFAULT_SIZE | MOV_TFHD_DEFAULT_DURATION |
|
||||
MOV_TFHD_BASE_DATA_OFFSET;
|
||||
if (!track->entry) {
|
||||
flags |= 0x010000; /* duration-is-empty */
|
||||
flags |= MOV_TFHD_DURATION_IS_EMPTY;
|
||||
} else {
|
||||
flags |= 0x20; /* default-sample-flags-present */
|
||||
flags |= MOV_TFHD_DEFAULT_FLAGS;
|
||||
}
|
||||
|
||||
/* Don't set a default sample size, the silverlight player refuses
|
||||
* to play files with that set. Don't set a default sample duration,
|
||||
* WMP freaks out if it is set. */
|
||||
if (track->mode == MODE_ISM)
|
||||
flags &= ~0x18;
|
||||
flags &= ~(MOV_TFHD_DEFAULT_SIZE | MOV_TFHD_DEFAULT_DURATION);
|
||||
|
||||
avio_wb32(pb, 0); /* size placeholder */
|
||||
ffio_wfourcc(pb, "tfhd");
|
||||
@ -2245,22 +2257,23 @@ static int mov_write_tfhd_tag(AVIOContext *pb, MOVTrack *track,
|
||||
avio_wb24(pb, flags);
|
||||
|
||||
avio_wb32(pb, track->track_id); /* track-id */
|
||||
if (flags & 0x01)
|
||||
if (flags & MOV_TFHD_BASE_DATA_OFFSET)
|
||||
avio_wb64(pb, moof_offset);
|
||||
if (flags & 0x08) {
|
||||
if (flags & MOV_TFHD_DEFAULT_DURATION) {
|
||||
track->default_duration = track->audio_vbr ? track->enc->frame_size : 1;
|
||||
avio_wb32(pb, track->default_duration);
|
||||
}
|
||||
if (flags & 0x10) {
|
||||
if (flags & MOV_TFHD_DEFAULT_SIZE) {
|
||||
track->default_size = track->entry ? track->cluster[0].size : 1;
|
||||
avio_wb32(pb, track->default_size);
|
||||
} else
|
||||
track->default_size = -1;
|
||||
|
||||
if (flags & 0x20) {
|
||||
if (flags & MOV_TFHD_DEFAULT_FLAGS) {
|
||||
track->default_sample_flags =
|
||||
track->enc->codec_type == AVMEDIA_TYPE_VIDEO ?
|
||||
0x01010000 : 0x02000000;
|
||||
(MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES | MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC) :
|
||||
MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO;
|
||||
avio_wb32(pb, track->default_sample_flags);
|
||||
}
|
||||
|
||||
@ -2269,13 +2282,14 @@ static int mov_write_tfhd_tag(AVIOContext *pb, MOVTrack *track,
|
||||
|
||||
static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry)
|
||||
{
|
||||
return entry->flags & MOV_SYNC_SAMPLE ? 0x02000000 : 0x01010000;
|
||||
return entry->flags & MOV_SYNC_SAMPLE ? MOV_FRAG_SAMPLE_FLAG_DEPENDS_NO :
|
||||
(MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES | MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC);
|
||||
}
|
||||
|
||||
static int mov_write_trun_tag(AVIOContext *pb, MOVTrack *track)
|
||||
{
|
||||
int64_t pos = avio_tell(pb);
|
||||
uint32_t flags = 1; /* data-offset-present */
|
||||
uint32_t flags = MOV_TRUN_DATA_OFFSET;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < track->entry; i++) {
|
||||
@ -2283,16 +2297,16 @@ static int mov_write_trun_tag(AVIOContext *pb, MOVTrack *track)
|
||||
track->track_duration - track->cluster[i].dts + track->start_dts :
|
||||
track->cluster[i + 1].dts - track->cluster[i].dts;
|
||||
if (duration != track->default_duration)
|
||||
flags |= 0x100; /* sample-duration-present */
|
||||
flags |= MOV_TRUN_SAMPLE_DURATION;
|
||||
if (track->cluster[i].size != track->default_size)
|
||||
flags |= 0x200; /* sample-size-present */
|
||||
flags |= MOV_TRUN_SAMPLE_SIZE;
|
||||
if (i > 0 && get_sample_flags(track, &track->cluster[i]) != track->default_sample_flags)
|
||||
flags |= 0x400; /* sample-flags-present */
|
||||
flags |= MOV_TRUN_SAMPLE_FLAGS;
|
||||
}
|
||||
if (!(flags & 0x400))
|
||||
flags |= 0x4; /* first-sample-flags-present */
|
||||
if (!(flags & MOV_TRUN_SAMPLE_FLAGS))
|
||||
flags |= MOV_TRUN_FIRST_SAMPLE_FLAGS;
|
||||
if (track->flags & MOV_TRACK_CTTS)
|
||||
flags |= 0x800; /* sample-composition-time-offsets-present */
|
||||
flags |= MOV_TRUN_SAMPLE_CTS;
|
||||
|
||||
avio_wb32(pb, 0); /* size placeholder */
|
||||
ffio_wfourcc(pb, "trun");
|
||||
@ -2302,20 +2316,20 @@ static int mov_write_trun_tag(AVIOContext *pb, MOVTrack *track)
|
||||
avio_wb32(pb, track->entry); /* sample count */
|
||||
track->moof_size_offset = avio_tell(pb);
|
||||
avio_wb32(pb, 0); /* data offset */
|
||||
if (flags & 0x4) /* first sample flags */
|
||||
if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS)
|
||||
avio_wb32(pb, get_sample_flags(track, &track->cluster[0]));
|
||||
|
||||
for (i = 0; i < track->entry; i++) {
|
||||
int64_t duration = i + 1 == track->entry ?
|
||||
track->track_duration - track->cluster[i].dts + track->start_dts :
|
||||
track->cluster[i + 1].dts - track->cluster[i].dts;
|
||||
if (flags & 0x100)
|
||||
if (flags & MOV_TRUN_SAMPLE_DURATION)
|
||||
avio_wb32(pb, duration);
|
||||
if (flags & 0x200)
|
||||
if (flags & MOV_TRUN_SAMPLE_SIZE)
|
||||
avio_wb32(pb, track->cluster[i].size);
|
||||
if (flags & 0x400)
|
||||
if (flags & MOV_TRUN_SAMPLE_FLAGS)
|
||||
avio_wb32(pb, get_sample_flags(track, &track->cluster[i]));
|
||||
if (flags & 0x800)
|
||||
if (flags & MOV_TRUN_SAMPLE_CTS)
|
||||
avio_wb32(pb, track->cluster[i].cts);
|
||||
}
|
||||
|
||||
|
@ -31,6 +31,10 @@
|
||||
*/
|
||||
int ff_wms_parse_sdp_a_line(AVFormatContext *s, const char *p);
|
||||
|
||||
int ff_h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
|
||||
AVStream *st, AVPacket *pkt, uint32_t *timestamp,
|
||||
const uint8_t *buf, int len, int flags);
|
||||
|
||||
extern RTPDynamicProtocolHandler ff_amr_nb_dynamic_handler;
|
||||
extern RTPDynamicProtocolHandler ff_amr_wb_dynamic_handler;
|
||||
extern RTPDynamicProtocolHandler ff_g726_16_dynamic_handler;
|
||||
|
@ -23,13 +23,9 @@
|
||||
#include "rtpdec_formats.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
|
||||
static int h263_handle_packet(AVFormatContext *ctx,
|
||||
PayloadContext *data,
|
||||
AVStream *st,
|
||||
AVPacket * pkt,
|
||||
uint32_t * timestamp,
|
||||
const uint8_t * buf,
|
||||
int len, int flags)
|
||||
int ff_h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
|
||||
AVStream *st, AVPacket *pkt, uint32_t *timestamp,
|
||||
const uint8_t *buf, int len, int flags)
|
||||
{
|
||||
uint8_t *ptr;
|
||||
uint16_t header;
|
||||
@ -96,12 +92,12 @@ RTPDynamicProtocolHandler ff_h263_1998_dynamic_handler = {
|
||||
.enc_name = "H263-1998",
|
||||
.codec_type = AVMEDIA_TYPE_VIDEO,
|
||||
.codec_id = CODEC_ID_H263,
|
||||
.parse_packet = h263_handle_packet,
|
||||
.parse_packet = ff_h263_handle_packet,
|
||||
};
|
||||
|
||||
RTPDynamicProtocolHandler ff_h263_2000_dynamic_handler = {
|
||||
.enc_name = "H263-2000",
|
||||
.codec_type = AVMEDIA_TYPE_VIDEO,
|
||||
.codec_id = CODEC_ID_H263,
|
||||
.parse_packet = h263_handle_packet,
|
||||
.parse_packet = ff_h263_handle_packet,
|
||||
};
|
||||
|
@ -35,6 +35,7 @@ struct PayloadContext {
|
||||
uint8_t endbyte;
|
||||
int endbyte_bits;
|
||||
uint32_t timestamp;
|
||||
int newformat;
|
||||
};
|
||||
|
||||
static PayloadContext *h263_new_context(void)
|
||||
@ -58,9 +59,14 @@ static int h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
|
||||
AVStream *st, AVPacket *pkt, uint32_t *timestamp,
|
||||
const uint8_t *buf, int len, int flags)
|
||||
{
|
||||
int f, p, i, sbit, ebit; /* Corresponding to header fields in the RFC */
|
||||
/* Corresponding to header fields in the RFC */
|
||||
int f, p, i, sbit, ebit, src, r;
|
||||
int header_size;
|
||||
|
||||
if (data->newformat)
|
||||
return ff_h263_handle_packet(ctx, data, st, pkt, timestamp, buf, len,
|
||||
flags);
|
||||
|
||||
if (data->buf && data->timestamp != *timestamp) {
|
||||
/* Dropping old buffered, unfinished data */
|
||||
uint8_t *p;
|
||||
@ -80,6 +86,7 @@ static int h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
|
||||
/* Mode A */
|
||||
header_size = 4;
|
||||
i = buf[1] & 0x10;
|
||||
r = ((buf[1] & 0x01) << 3) | ((buf[2] & 0xe0) >> 5);
|
||||
} else if (!p) {
|
||||
/* Mode B */
|
||||
header_size = 8;
|
||||
@ -89,6 +96,7 @@ static int h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
|
||||
len, header_size);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
r = buf[3] & 0x03;
|
||||
i = buf[4] & 0x80;
|
||||
} else {
|
||||
/* Mode C */
|
||||
@ -99,10 +107,24 @@ static int h263_handle_packet(AVFormatContext *ctx, PayloadContext *data,
|
||||
len, header_size);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
r = buf[3] & 0x03;
|
||||
i = buf[4] & 0x80;
|
||||
}
|
||||
sbit = (buf[0] >> 3) & 0x7;
|
||||
ebit = buf[0] & 0x7;
|
||||
src = (buf[1] & 0xe0) >> 5;
|
||||
if (!(buf[0] & 0xf8)) { /* Reserved bits in RFC 2429/4629 are zero */
|
||||
if ((src == 0 || src >= 6) && r) {
|
||||
/* Invalid src for this format, and bits that should be zero
|
||||
* according to RFC 2190 aren't zero. */
|
||||
av_log(ctx, AV_LOG_WARNING,
|
||||
"Interpreting H263 RTP data as RFC 2429/4629 even though "
|
||||
"signalled with a static payload type.\n");
|
||||
data->newformat = 1;
|
||||
return ff_h263_handle_packet(ctx, data, st, pkt, timestamp, buf,
|
||||
len, flags);
|
||||
}
|
||||
}
|
||||
|
||||
buf += header_size;
|
||||
len -= header_size;
|
||||
|
@ -1,9 +1,9 @@
|
||||
c4e12d7ed2ab47d43b912eb160a2bea8 *./tests/data/lavf/lavf.ismv
|
||||
312247 ./tests/data/lavf/lavf.ismv
|
||||
eb116b60befadfd5c9118635d81c5a6e *./tests/data/lavf/lavf.ismv
|
||||
312271 ./tests/data/lavf/lavf.ismv
|
||||
./tests/data/lavf/lavf.ismv CRC=0xbcc963fc
|
||||
44c724f5dd12436d283aacc95065ad7f *./tests/data/lavf/lavf.ismv
|
||||
321521 ./tests/data/lavf/lavf.ismv
|
||||
90db70a6f33cf22db9ce242087b5870b *./tests/data/lavf/lavf.ismv
|
||||
321545 ./tests/data/lavf/lavf.ismv
|
||||
./tests/data/lavf/lavf.ismv CRC=0x3998478f
|
||||
c4e12d7ed2ab47d43b912eb160a2bea8 *./tests/data/lavf/lavf.ismv
|
||||
312247 ./tests/data/lavf/lavf.ismv
|
||||
eb116b60befadfd5c9118635d81c5a6e *./tests/data/lavf/lavf.ismv
|
||||
312271 ./tests/data/lavf/lavf.ismv
|
||||
./tests/data/lavf/lavf.ismv CRC=0xbcc963fc
|
||||
|
Loading…
Reference in New Issue
Block a user