Search
j0ke.net Open Build Service
>
Projects
>
multimedia
>
ffmpeg
> ffmpeg_amvpatch.diff
Sign Up
|
Log In
Username
Password
Cancel
Overview
Repositories
Revisions
Requests
Users
Advanced
Attributes
Meta
File ffmpeg_amvpatch.diff of Package ffmpeg (Revision 9)
Currently displaying revision
9
,
show latest
diff -uNr ffmpeg.orig/configure ffmpeg/configure --- ffmpeg.orig/configure 2007-12-25 11:42:45.000000000 +0100 +++ ffmpeg/configure 2007-12-26 19:55:57.000000000 +0100 @@ -88,6 +88,7 @@ echo " --enable-libfaac enable FAAC support via libfaac [default=no]" echo " --enable-libfaad enable FAAD support via libfaad [default=no]" echo " --enable-libfaadbin open libfaad.so.0 at runtime [default=no]" + echo " --enable-libg729a enable G.729A support via libg729a [default=no]" echo " --enable-libgsm enable GSM support via libgsm [default=no]" echo " --enable-libmp3lame enable MP3 encoding via libmp3lame [default=no]" echo " --enable-libnut enable NUT (de)muxing via libnut," @@ -622,6 +623,7 @@ libfaac libfaad libfaadbin + libg729a libgsm libmp3lame libnut @@ -781,6 +783,8 @@ libfaac_encoder_deps="libfaac" libfaad_decoder_deps="libfaad" libfaadbin_decoder_extralibs='$ldl' +g729a_decoder_deps="libg729a" +g729a_encoder_deps="libg729a" libgsm_decoder_deps="libgsm" libgsm_encoder_deps="libgsm" libgsm_ms_decoder_deps="libgsm" @@ -794,6 +798,8 @@ # demuxers / muxers ac3_demuxer_deps="ac3_parser" +act_muxer_deps="g729a_encoder" +act_demuxer_deps="g729a_decoder" audio_beos_demuxer_deps="audio_beos" audio_beos_demuxer_extralibs="-lmedia -lbe" audio_beos_muxer_deps="audio_beos" @@ -1608,6 +1614,7 @@ enabled libdc1394 && require libdc1394 libdc1394/dc1394_control.h dc1394_create_handle -ldc1394_control -lraw1394 enabled libfaac && require2 libfaac "stdint.h faac.h" faacEncGetVersion -lfaac enabled libfaad && require2 libfaad faad.h faacDecOpen -lfaad +enabled libg729a && require libg729a g729a.h g729a_encoder_init -lg729a enabled libgsm && require libgsm gsm.h gsm_create -lgsm enabled libmp3lame && require LAME lame/lame.h lame_init -lmp3lame -lm enabled libnut && require libnut libnut.h nut_demuxer_init -lnut @@ -1868,6 +1875,7 @@ echo "libfaac enabled ${libfaac-no}" echo "libfaad enabled ${libfaad-no}" echo "libfaad dlopened ${libfaadbin-no}" +echo "libg729a enabled ${libg729a-no}" echo "libgsm enabled ${libgsm-no}" echo "libmp3lame enabled ${libmp3lame-no}" echo "libnut enabled ${libnut-no}" diff -uNr ffmpeg.orig/libavcodec/adpcm.c ffmpeg/libavcodec/adpcm.c --- ffmpeg.orig/libavcodec/adpcm.c 2007-11-06 22:51:04.000000000 +0100 +++ ffmpeg/libavcodec/adpcm.c 2007-12-26 20:04:43.000000000 +0100 @@ -149,6 +149,8 @@ typedef struct ADPCMContext { int channel; /* for stereo MOVs, decode left, then decode right, then tell it's decoded */ ADPCMChannelStatus status[6]; + int extra_amv_samples; //number of samples to put into next frame + int samples_written; } ADPCMContext; /* XXX: implement encoding */ @@ -183,6 +185,16 @@ } avctx->frame_size = 512 * (avctx->sample_rate / 11025); break; + case CODEC_ID_ADPCM_IMA_AMV: + if (avctx->channels != 1){ + av_log(avctx, AV_LOG_ERROR, "Only mono sound is supported\n"); + return -1; + } + if (avctx->sample_rate != 22050){ + av_log(avctx, AV_LOG_ERROR, "Only 22050 sample rate is supported\n"); + return -1; + } + break; default: return -1; break; @@ -295,7 +307,7 @@ nodes[0]->step = c->step_index; nodes[0]->sample1 = c->sample1; nodes[0]->sample2 = c->sample2; - if((version == CODEC_ID_ADPCM_IMA_WAV) || (version == CODEC_ID_ADPCM_SWF)) + if((version == CODEC_ID_ADPCM_IMA_WAV) || (version == CODEC_ID_ADPCM_SWF) || (version == CODEC_ID_ADPCM_IMA_AMV)) nodes[0]->sample1 = c->prev_sample; if(version == CODEC_ID_ADPCM_MS) nodes[0]->step = c->idelta; @@ -366,7 +378,7 @@ next_##NAME:; STORE_NODE(ms, FFMAX(16, (AdaptationTable[nibble] * step) >> 8)); } - } else if((version == CODEC_ID_ADPCM_IMA_WAV)|| (version == CODEC_ID_ADPCM_SWF)) { + } else if((version == CODEC_ID_ADPCM_IMA_WAV)|| (version == CODEC_ID_ADPCM_SWF)|| (version == CODEC_ID_ADPCM_IMA_AMV)) { #define LOOP_NODES(NAME, STEP_TABLE, STEP_INDEX)\ const int predictor = nodes[j]->sample1;\ const int div = (sample - predictor) * 4 / STEP_TABLE;\ @@ -1585,7 +1597,7 @@ ADPCM_DECODER(CODEC_ID_ADPCM_EA_R2, adpcm_ea_r2); ADPCM_DECODER(CODEC_ID_ADPCM_EA_R3, adpcm_ea_r3); ADPCM_DECODER(CODEC_ID_ADPCM_EA_XAS, adpcm_ea_xas); -ADPCM_DECODER(CODEC_ID_ADPCM_IMA_AMV, adpcm_ima_amv); +ADPCM_CODEC (CODEC_ID_ADPCM_IMA_AMV, adpcm_ima_amv); ADPCM_DECODER(CODEC_ID_ADPCM_IMA_DK3, adpcm_ima_dk3); ADPCM_DECODER(CODEC_ID_ADPCM_IMA_DK4, adpcm_ima_dk4); ADPCM_DECODER(CODEC_ID_ADPCM_IMA_EA_EACS, adpcm_ima_ea_eacs); diff -uNr ffmpeg.orig/libavcodec/allcodecs.c ffmpeg/libavcodec/allcodecs.c --- ffmpeg.orig/libavcodec/allcodecs.c 2007-12-20 10:57:16.000000000 +0100 +++ ffmpeg/libavcodec/allcodecs.c 2007-12-26 19:55:58.000000000 +0100 @@ -61,7 +61,7 @@ /* video codecs */ REGISTER_DECODER (AASC, aasc); - REGISTER_DECODER (AMV, amv); + REGISTER_ENCDEC (AMV, amv); REGISTER_ENCDEC (ASV1, asv1); REGISTER_ENCDEC (ASV2, asv2); REGISTER_DECODER (AVS, avs); @@ -179,6 +179,7 @@ REGISTER_DECODER (DCA, dca); REGISTER_DECODER (DSICINAUDIO, dsicinaudio); REGISTER_ENCDEC (FLAC, flac); + REGISTER_ENCDEC (G729A, g729a); REGISTER_DECODER (IMC, imc); REGISTER_DECODER (MACE3, mace3); REGISTER_DECODER (MACE6, mace6); @@ -242,7 +243,7 @@ REGISTER_DECODER (ADPCM_EA_R3, adpcm_ea_r3); REGISTER_DECODER (ADPCM_EA_XAS, adpcm_ea_xas); REGISTER_ENCDEC (ADPCM_G726, adpcm_g726); - REGISTER_DECODER (ADPCM_IMA_AMV, adpcm_ima_amv); + REGISTER_ENCDEC (ADPCM_IMA_AMV, adpcm_ima_amv); REGISTER_DECODER (ADPCM_IMA_DK3, adpcm_ima_dk3); REGISTER_DECODER (ADPCM_IMA_DK4, adpcm_ima_dk4); REGISTER_DECODER (ADPCM_IMA_EA_EACS, adpcm_ima_ea_eacs); diff -uNr ffmpeg.orig/libavcodec/avcodec.h ffmpeg/libavcodec/avcodec.h --- ffmpeg.orig/libavcodec/avcodec.h 2007-12-21 17:43:20.000000000 +0100 +++ ffmpeg/libavcodec/avcodec.h 2007-12-26 19:55:58.000000000 +0100 @@ -274,6 +274,7 @@ CODEC_ID_APE, CODEC_ID_NELLYMOSER, CODEC_ID_MUSEPACK8, + CODEC_ID_G729A, /* subtitle codecs */ CODEC_ID_DVD_SUBTITLE= 0x17000, diff -uNr ffmpeg.orig/libavcodec/g729dec.c ffmpeg/libavcodec/g729dec.c --- ffmpeg.orig/libavcodec/g729dec.c 1970-01-01 01:00:00.000000000 +0100 +++ ffmpeg/libavcodec/g729dec.c 2007-12-26 19:55:58.000000000 +0100 @@ -0,0 +1,209 @@ +/* + * G.729 Annex A codec wrapper (around reference ITU's source) + * Copyright (c) 2007 Vladimir Voroshilov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avcodec.h" + +#include "bitstream.h" + +#include <g729a.h> + +typedef struct +{ + unsigned char format; +#ifdef DEBUG_DUMP + FILE* f; + FILE* f2; +#endif + void* priv; +} G729Context; + +#define MAX_FORMATS 2 + +#define MP1 11 + + +#ifdef G729_UNPACKED_LSP +#define VECTOR_SIZE 15 +#define DEF_VECTOR(L0,L1,L2,L3,P1,P0,C1,S1,GA1,GB1,P2,C2,S2,GA2,GB2) {L0,L1,L2,L3,P1,P0,C1,S1,GA1,GB1,P2,C2,S2,GA2,GB2} +#else +#define VECTOR_SIZE 11 +#define DEF_VECTOR(L0,L1,L2,L3,P1,P0,C1,S1,GA1,GB1,P2,C2,S2,GA2,GB2) {(L0+L1),(L2+L3),P1,P0,C1,S1,(GA1+GB1),P2,C2,S2,(GA2+GB2)} +#endif + + +#define DEF_FRAME(frames, L0,L1,L2,L3,P1,P0,C1,S1,GA1,GB1,P2,C2,S2,GA2,GB2) (frames),(frames*(L1+L0+L1+L2+L3+P1+P0+C1+S1+GA1+GB1+P2+C2+S2+GA2+GB2)/8),DEF_VECTOR(L0,L1,L2,L3,P1,P0,C1,S1,GA1,GB1,P2,C2,S2,GA2,GB2) + +static const struct{ + char* name; + int sample_rate; + int frames; + short frame_size; + char vector_bits[VECTOR_SIZE]; + char silence_compression; +} formats[MAX_FORMATS]={ + {"8Kb/s", 8000, DEF_FRAME(1, 1,7,5,5,8,1,13, 4,3,4,5,13, 4,3,4), 0}, +#ifdef G729_SUPPORT_4400 + {"4.4Kb/s", 4400, DEF_FRAME(2, 1,7,5,5,8,1,12, 9,3,4,5,12, 9,3,4), 0}, +#endif //G729_SUPPORT_4400 + { NULL, 0, DEF_FRAME(0,0,0,0,0,0,0, 0, 0,0,0,0, 0, 0,0,0), 0} +}; + +#ifdef CONFIG_ENCODERS +static int ff_g729a_encoder_init(AVCodecContext * avctx) +{ + G729Context *ctx=avctx->priv_data; + + ctx->priv=g729a_encoder_init(); + + if(avctx->channels!=1) + { + av_log(avctx, AV_LOG_ERROR, "Only one channel is suported\n"); + return -1; + } + for(ctx->format=0; formats[ctx->format].name; ctx->format++) + if(formats[ctx->format].sample_rate==avctx->sample_rate) + break; + if(!formats[ctx->format].name){ + av_log(avctx, AV_LOG_ERROR, "Sample rate %d is not supported\n", avctx->sample_rate); + return -1; + } + + avctx->frame_size=formats[ctx->format].frame_size*8; + avctx->block_align=avctx->frame_size; + + avctx->coded_frame = avcodec_alloc_frame(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + avctx->coded_frame->key_frame = 1; + + return 0; +} + +static int ff_g729a_encode_frame(AVCodecContext *avctx, + uint8_t *dst, int buf_size, void *data) +{ + G729Context *ctx=avctx->priv_data; + uint16_t serial[200]; + PutBitContext pb; + int idx=2,i,k; + + g729a_encode_frame(ctx->priv, data, 0/* not used yet*/, serial, buf_size); + + init_put_bits(&pb, dst, buf_size*8); + for(i=0;i<formats[ctx->format].frame_size;i++) + for(k=0; k<8; k++){ + put_bits(&pb, 1, serial[idx++]==0x81?1:0); + } + + return (put_bits_count(&pb)+7)/8; +} +#endif //CONFIG_ENCODERS + +static int ff_g729a_decoder_init(AVCodecContext * avctx) +{ + G729Context *ctx=avctx->priv_data; + + for(ctx->format=0; formats[ctx->format].name; ctx->format++) + if(formats[ctx->format].sample_rate==avctx->sample_rate) + break; + if(!formats[ctx->format].name){ + av_log(avctx, AV_LOG_ERROR, "Sample rate %d is not supported\n", avctx->sample_rate); + return -1; + } + + ctx->priv=g729a_decoder_init(); +#ifdef DEBUG_DUMP +ctx->f=fopen("test2.bit","wb"); +ctx->f2=fopen("test2.raw","wb"); +#endif + + avctx->frame_size=10; + return 0; +} + +static int ff_g729a_close(AVCodecContext *avctx) +{ + G729Context *ctx=avctx->priv_data; +#ifdef DEBUG_DUMP + if(ctx->f) fclose(ctx->f); + if(ctx->f2) fclose(ctx->f2); +#endif + g729a_decoder_uninit(ctx->priv); + ctx->priv=NULL; + return 0; +} + +static int ff_g729a_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + uint8_t *buf, int buf_size) +{ + G729Context *ctx=avctx->priv_data; + GetBitContext gb; + int i,j,k; + int l_frame=formats[ctx->format].frame_size*8; + uint16_t serial[200]; + + init_get_bits(&gb, buf, buf_size); + + *data_size=0; + for(j=0; j<formats[ctx->format].frames; j++){ + int dst=0; + serial[dst++]=0x6b21; + serial[dst++]=80; + + for(i=0;i<FFMIN((200-2)/8, buf_size);i++) + for(k=0; k<8; k++){ + serial[dst++]=get_bits1(&gb)?0x81:0x7f; + } +#ifdef DEBUG_DUMP + fwrite(serial,sizeof(uint16_t),l_frame+2,ctx->f); +#endif + g729a_decode_frame(ctx->priv,serial, 0/*not used yet*/,(short*)data+j*l_frame, l_frame); + *data_size+=2*l_frame; + } +#ifdef DEBUG_DUMP + fwrite(data,1,*data_size,ctx->f2); +#endif + return buf_size; +} + +#ifdef CONFIG_ENCODERS +AVCodec g729a_encoder = { + "g729a", + CODEC_TYPE_AUDIO, + CODEC_ID_G729A, + sizeof(G729Context), + ff_g729a_encoder_init, + ff_g729a_encode_frame, + ff_g729a_close, +}; +#endif //CONFIG_ENCODERS + +AVCodec g729a_decoder = { + "g729a", + CODEC_TYPE_AUDIO, + CODEC_ID_G729A, + sizeof(G729Context), + ff_g729a_decoder_init, + NULL, + ff_g729a_close, + ff_g729a_decode_frame, +}; diff -uNr ffmpeg.orig/libavcodec/Makefile ffmpeg/libavcodec/Makefile --- ffmpeg.orig/libavcodec/Makefile 2007-12-20 10:57:15.000000000 +0100 +++ ffmpeg/libavcodec/Makefile 2007-12-26 19:55:58.000000000 +0100 @@ -81,6 +81,9 @@ OBJS-$(CONFIG_FLV_ENCODER) += mpegvideo_enc.o motion_est.o ratecontrol.o h263.o OBJS-$(CONFIG_FOURXM_DECODER) += 4xm.o OBJS-$(CONFIG_FRAPS_DECODER) += fraps.o huffman.o +OBJS-$(CONFIG_G729A_DECODER) += g729dec.o + + OBJS-$(CONFIG_GIF_DECODER) += gifdec.o lzw.o OBJS-$(CONFIG_GIF_ENCODER) += gif.o OBJS-$(CONFIG_H261_DECODER) += h261dec.o h261.o @@ -273,6 +276,7 @@ OBJS-$(CONFIG_ADPCM_G726_DECODER) += g726.o OBJS-$(CONFIG_ADPCM_G726_ENCODER) += g726.o OBJS-$(CONFIG_ADPCM_IMA_AMV_DECODER) += adpcm.o +OBJS-$(CONFIG_ADPCM_IMA_AMV_ENCODER) += adpcm.o OBJS-$(CONFIG_ADPCM_IMA_DK3_DECODER) += adpcm.o OBJS-$(CONFIG_ADPCM_IMA_DK4_DECODER) += adpcm.o OBJS-$(CONFIG_ADPCM_IMA_EA_EACS_DECODER) += adpcm.o diff -uNr ffmpeg.orig/libavcodec/mjpegenc.c ffmpeg/libavcodec/mjpegenc.c --- ffmpeg.orig/libavcodec/mjpegenc.c 2007-07-24 15:20:30.000000000 +0200 +++ ffmpeg/libavcodec/mjpegenc.c 2007-12-26 19:55:58.000000000 +0100 @@ -200,6 +200,9 @@ put_marker(&s->pb, SOI); + // hack for AMV mjpeg format + if(s->avctx->codec_id == CODEC_ID_AMV) return; + jpeg_put_comments(s); jpeg_table_header(s); @@ -446,6 +449,28 @@ } } +// maximum over s->mjpeg_vsample[i] +#define V_MAX 2 +int amv_encode_picture(AVCodecContext *avctx, + unsigned char *buf, int buf_size, void *data) +{ + + AVFrame* pic=data; + MpegEncContext *s = avctx->priv_data; + int i; + + //CODEC_FLAG_EMU_EDGE have to be cleared + if(s->avctx->flags & CODEC_FLAG_EMU_EDGE) + return -1; + + //picture should be flipped upside-down + for(i=0; i < 3; i++) { + pic->data[i] += (pic->linesize[i] * (s->mjpeg_vsample[i] * (8 * s->mb_height -((s->height/V_MAX)&7)) - 1 )); + pic->linesize[i] *= -1; + } + return MPV_encode_picture(avctx,buf, buf_size, pic); +} + AVCodec mjpeg_encoder = { "mjpeg", CODEC_TYPE_VIDEO, @@ -456,3 +481,14 @@ MPV_encode_end, .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, -1}, }; + +AVCodec amv_encoder = { + "amv", + CODEC_TYPE_VIDEO, + CODEC_ID_AMV, + sizeof(MpegEncContext), + MPV_encode_init, + amv_encode_picture, + MPV_encode_end, + .pix_fmts= (enum PixelFormat[]){PIX_FMT_YUVJ420P, PIX_FMT_YUVJ422P, -1}, +}; diff -uNr ffmpeg.orig/libavcodec/mpegvideo_enc.c ffmpeg/libavcodec/mpegvideo_enc.c --- ffmpeg.orig/libavcodec/mpegvideo_enc.c 2007-11-24 15:05:16.000000000 +0100 +++ ffmpeg/libavcodec/mpegvideo_enc.c 2007-12-26 19:55:58.000000000 +0100 @@ -248,6 +248,7 @@ break; case CODEC_ID_LJPEG: case CODEC_ID_MJPEG: + case CODEC_ID_AMV: if(avctx->pix_fmt != PIX_FMT_YUVJ420P && avctx->pix_fmt != PIX_FMT_YUVJ422P && ((avctx->pix_fmt != PIX_FMT_YUV420P && avctx->pix_fmt != PIX_FMT_YUV422P) || avctx->strict_std_compliance>FF_COMPLIANCE_INOFFICIAL)){ av_log(avctx, AV_LOG_ERROR, "colorspace not supported in jpeg\n"); @@ -488,6 +489,11 @@ if(s->codec_id==CODEC_ID_MJPEG){ s->intra_quant_bias= 1<<(QUANT_BIAS_SHIFT-1); //(a + x/2)/x s->inter_quant_bias= 0; + }else if(s->codec_id==CODEC_ID_AMV){ + s->intra_quant_bias= 0; + s->inter_quant_bias= 0; + s->fixed_qscale = 1; + s->adaptive_quant = 0; }else if(s->mpeg_quant || s->codec_id==CODEC_ID_MPEG1VIDEO || s->codec_id==CODEC_ID_MPEG2VIDEO){ s->intra_quant_bias= 3<<(QUANT_BIAS_SHIFT-3); //(a + x*3/8)/x s->inter_quant_bias= 0; @@ -501,6 +507,8 @@ if(avctx->inter_quant_bias != FF_DEFAULT_QUANT_BIAS) s->inter_quant_bias= avctx->inter_quant_bias; + av_log(avctx, AV_LOG_DEBUG, "intra_quant_bias = %d inter_quant_bias = %d\n",s->intra_quant_bias,s->inter_quant_bias); + avcodec_get_chroma_sub_sample(avctx->pix_fmt, &chroma_h_shift, &chroma_v_shift); if(avctx->codec_id == CODEC_ID_MPEG4 && s->avctx->time_base.den > (1<<16)-1){ @@ -523,6 +531,7 @@ break; case CODEC_ID_LJPEG: case CODEC_ID_MJPEG: + case CODEC_ID_AMV: s->out_format = FMT_MJPEG; s->intra_only = 1; /* force intra only for jpeg */ s->mjpeg_vsample[0] = 2; @@ -1731,6 +1740,7 @@ h263_encode_mb(s, s->block, motion_x, motion_y); break; case CODEC_ID_MJPEG: + case CODEC_ID_AMV: if (ENABLE_MJPEG_ENCODER) ff_mjpeg_encode_mb(s, s->block); break; diff -uNr ffmpeg.orig/libavformat/act.c ffmpeg/libavformat/act.c --- ffmpeg.orig/libavformat/act.c 1970-01-01 01:00:00.000000000 +0100 +++ ffmpeg/libavformat/act.c 2007-12-26 19:55:58.000000000 +0100 @@ -0,0 +1,253 @@ +/* + * ACT file format muxer/demuxer + * Copyright (c) 2007 Vladimir Voroshilov + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "avformat.h" +#include "riff.h" + +#define CHUNK_SIZE 512 +#define RIFF_TAG MKTAG('R','I','F','F') +#define WAVE_TAG MKTAG('W','A','V','E') + +typedef struct{ + uint8_t tag; //??? 0x84 + uint16_t msec; ///< duration msec + uint8_t sec; ///< duration sec + uint32_t minutes; ///< Duration min +} ACTHeader; + +typedef struct{ + int bytes_left_in_chunk; + ACTHeader hdr; + offset_t data; + offset_t riff; + int frames; +} ACTContext; + +#ifdef CONFIG_MUXERS +static int act_write_header(AVFormatContext *s) +{ + ACTContext* ctx = s->priv_data; + ByteIOContext *pb = &s->pb; + AVCodecContext *enc = s->streams[0]->codec; + offset_t tmp; + int i; + + if (enc->codec_id != CODEC_ID_G729A) + return -1; + + ctx->riff=start_tag(pb, "RIFF"); /* magic number */ + put_buffer(pb, "WAVE",4); + tmp=start_tag(pb, "fmt "); + put_le16(pb, 0x01); + put_le16(pb, 0x01); + put_le32(pb, enc->sample_rate); + put_le32(pb, enc->sample_rate*2); + put_le16(pb, 2); + put_le16(pb, 16); + end_tag(pb, tmp); + ctx->data=start_tag(pb, "data"); + tmp=url_ftell(pb); + for(i=0;i<512-tmp;i++) + put_byte(pb, 0); + + ctx->frames=0; + put_flush_packet(pb); + return 0; +} + +static int act_write_packet(AVFormatContext *s, AVPacket *pkt) +{ + ACTContext* ctx = s->priv_data; + uint8_t *data=pkt->data; + int i; + + if(!ctx->bytes_left_in_chunk) + ctx->bytes_left_in_chunk=CHUNK_SIZE; + + put_byte(&s->pb, data[1]); + put_byte(&s->pb, data[3]); + put_byte(&s->pb, data[5]); + put_byte(&s->pb, data[7]); + put_byte(&s->pb, data[9]); + put_byte(&s->pb, data[0]); + put_byte(&s->pb, data[2]); + put_byte(&s->pb, data[4]); + put_byte(&s->pb, data[6]); + put_byte(&s->pb, data[8]); + + ctx->bytes_left_in_chunk-=pkt->size; + + if(ctx->bytes_left_in_chunk<pkt->size) + for(; ctx->bytes_left_in_chunk; ctx->bytes_left_in_chunk--) + put_byte(&s->pb, 0); + + put_flush_packet(&s->pb); + ctx->frames++; + return 0; +} +static int act_write_trailer(AVFormatContext *s) +{ + ACTContext* ctx = s->priv_data; + ByteIOContext *pb = &s->pb; + AVCodecContext *enc = s->streams[0]->codec; + int duration; + offset_t tmp; + + tmp=url_ftell(pb); + tmp%=512; + for(; tmp<512; tmp++) + put_byte(pb, 0); + + end_tag(pb, ctx->data); + end_tag(pb, ctx->riff); + duration=av_rescale(ctx->frames, 1000*enc->frame_size, enc->sample_rate); +av_log(s, AV_LOG_ERROR, "Duration %d\n", duration); + + url_fseek(pb, 256, SEEK_SET); + put_byte(pb, 0x84); + put_le16(pb, duration % 1000); //milliseconds + duration/=1000; + put_byte(pb, duration %60); //seconds + duration/=60; + put_le32(pb, duration); //minutes + + put_flush_packet(pb); + return 0; +} +#endif //CONFIG_MUXERS + +static int act_probe(AVProbeData *p) +{ + ACTHeader* hdr=(ACTHeader*)&p->buf[256]; + + if ((AV_RL32(&p->buf[0]) != RIFF_TAG) || + (AV_RL32(&p->buf[8]) != WAVE_TAG) || + (AV_RL32(&p->buf[16]) != 16)) + return 0; + + if(hdr->tag!=0x84) + return 0; + + return AVPROBE_SCORE_MAX; +} + +static int act_read_header(AVFormatContext *s, + AVFormatParameters *ap) +{ + ACTContext* ctx = s->priv_data; + ByteIOContext *pb = &s->pb; + int size; + AVStream* st; + + st=av_new_stream(s, 0); + if (!st) + return AVERROR(ENOMEM); + url_fskip(pb, 16); + size=get_le32(pb); + get_wav_header(pb, st->codec, size); + + url_fseek(pb, 256, SEEK_SET); + if (get_buffer(pb, (char*)&ctx->hdr, sizeof(ctx->hdr))!=sizeof(ctx->hdr)) + return AVERROR(EIO); + + + st->codec->codec_tag = 0; + st->codec->codec_id=CODEC_ID_G729A; + st->codec->frame_size=10; + + st->duration=(ctx->hdr.minutes*60+ctx->hdr.sec)*100+ctx->hdr.msec/10; + + av_set_pts_info(st, 64, 1, 800); + + if(st->codec->sample_rate!=8000 && st->codec->sample_rate!=4400) + { + av_log(s, AV_LOG_ERROR, "Sample rate %d is not supported\n", st->codec->sample_rate); + return -1; + } + + + ctx->bytes_left_in_chunk=CHUNK_SIZE; + + url_fseek(pb, 512, SEEK_SET); + return 0; +} + + +static int act_read_packet(AVFormatContext *s, + AVPacket *pkt) +{ + ACTContext* ctx = s->priv_data; + ByteIOContext *pb = &s->pb; + uint8_t bFrame[22]; + uint8_t *pkt_buf; + int i, bytes_read; + int frame_size=s->streams[0]->codec->frame_size; + + bytes_read = get_buffer(pb, bFrame, frame_size); + + if(bytes_read != frame_size || av_new_packet(pkt, frame_size)) + return AVERROR(EIO); + + pkt_buf=(uint16_t*)pkt->data; + + pkt_buf[1]=bFrame[0]; + pkt_buf[3]=bFrame[1]; + pkt_buf[5]=bFrame[2]; + pkt_buf[7]=bFrame[3]; + pkt_buf[9]=bFrame[4]; + pkt_buf[0]=bFrame[5]; + pkt_buf[2]=bFrame[6]; + pkt_buf[4]=bFrame[7]; + pkt_buf[6]=bFrame[8]; + pkt_buf[8]=bFrame[9]; + + ctx->bytes_left_in_chunk -= frame_size; + + if(ctx->bytes_left_in_chunk < frame_size) + { + url_fskip(pb, ctx->bytes_left_in_chunk); + ctx->bytes_left_in_chunk=CHUNK_SIZE; + } + + return 0; +} +#ifdef CONFIG_MUXERS +AVOutputFormat act_muxer = { + "act", + "ACT", + "audio/act", + "act", + sizeof(ACTContext), + CODEC_ID_G729A, + CODEC_ID_NONE, + act_write_header, + act_write_packet, + act_write_trailer, +}; +#endif //CONFIG_MUXERS + +AVInputFormat act_demuxer = { + "act", + "ACT Voice file format", + sizeof(ACTContext), + act_probe, + act_read_header, + act_read_packet +}; diff -uNr ffmpeg.orig/libavformat/allformats.c ffmpeg/libavformat/allformats.c --- ffmpeg.orig/libavformat/allformats.c 2007-11-24 15:05:20.000000000 +0100 +++ ffmpeg/libavformat/allformats.c 2007-12-26 19:55:58.000000000 +0100 @@ -52,9 +52,11 @@ /* (de)muxers */ REGISTER_DEMUXER (AAC, aac); REGISTER_MUXDEMUX (AC3, ac3); + REGISTER_MUXDEMUX (ACT, act); REGISTER_MUXER (ADTS, adts); REGISTER_MUXDEMUX (AIFF, aiff); REGISTER_MUXDEMUX (AMR, amr); + REGISTER_MUXER (AMV, amv); REGISTER_DEMUXER (APC, apc); REGISTER_DEMUXER (APE, ape); REGISTER_MUXDEMUX (ASF, asf); diff -uNr ffmpeg.orig/libavformat/amvenc.c ffmpeg/libavformat/amvenc.c --- ffmpeg.orig/libavformat/amvenc.c 1970-01-01 01:00:00.000000000 +0100 +++ ffmpeg/libavformat/amvenc.c 2007-12-26 19:55:58.000000000 +0100 @@ -0,0 +1,422 @@ +/* + * AMV muxer + * Copyright (c) 2000 Fabrice Bellard. + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ +#include "avformat.h" +#include "amv.h" +#include "riff.h" + +/* + * TODO: + * - fill all fields if non streamed (nb_frames for example) + */ + +#ifdef CONFIG_AMV_MUXER + + +typedef struct { + offset_t riff_start, movi_list, odml_list; + offset_t frames_hdr_all, frames_hdr_strm[MAX_STREAMS]; + offset_t hours, minutes, seconds; + int audio_strm_length[MAX_STREAMS]; + int riff_id; + int packet_count[MAX_STREAMS]; + int last_stream_index; +} AMVContext; + +static offset_t avi_start_new_riff(AMVContext *avi, ByteIOContext *pb, + const char* riff_tag, const char* list_tag) +{ + offset_t loff; + + avi->riff_id++; + + avi->riff_start = start_tag(pb, "RIFF"); + put_tag(pb, riff_tag); + loff = start_tag(pb, "LIST"); + put_tag(pb, list_tag); + return loff; +} + +static char* avi_stream2fourcc(char* tag, int index, enum CodecType type) +{ + tag[0] = '0'; + tag[1] = '0' + index; + if (type == CODEC_TYPE_VIDEO) { + tag[2] = 'd'; + tag[3] = 'c'; + } else { + tag[2] = 'w'; + tag[3] = 'b'; + } + tag[4] = '\0'; + return tag; +} + +static int avi_write_counters(AVFormatContext* s, int riff_id) +{ + ByteIOContext *pb = &s->pb; + AMVContext *avi = s->priv_data; + int n, au_byterate, au_ssize, au_scale, nb_frames = 0; + offset_t file_size; + AVCodecContext* stream; + + file_size = url_ftell(pb); + for(n = 0; n < s->nb_streams; n++) { + assert(avi->frames_hdr_strm[n]); + stream = s->streams[n]->codec; + url_fseek(pb, avi->frames_hdr_strm[n], SEEK_SET); + ff_parse_specific_params(stream, &au_byterate, &au_ssize, &au_scale); + if(au_ssize == 0) { + put_le32(pb, avi->packet_count[n]); + } else { + put_le32(pb, avi->audio_strm_length[n] / au_ssize); + } + if(stream->codec_type == CODEC_TYPE_VIDEO) + nb_frames = FFMAX(nb_frames, avi->packet_count[n]); + } + if(riff_id == 1) { + assert(avi->frames_hdr_all); + url_fseek(pb, avi->frames_hdr_all, SEEK_SET); + put_le32(pb, nb_frames); + + // HACK ! + int duration_seconds = nb_frames/s->streams[0]->codec->time_base.den; + assert(avi->seconds); + url_fseek(pb, avi->seconds, SEEK_SET); + put_byte(pb,duration_seconds%60); + assert(avi->minutes); + url_fseek(pb, avi->minutes, SEEK_SET); + put_byte(pb,duration_seconds/60); + assert(avi->hours); + url_fseek(pb, avi->hours, SEEK_SET); + put_le16(pb,duration_seconds/3600); + } + url_fseek(pb, file_size, SEEK_SET); + + return 0; +} + +static int avi_write_header(AVFormatContext *s) +{ + AMVContext *avi = s->priv_data; + ByteIOContext *pb = &s->pb; + int bitrate, n, i, nb_frames, au_byterate, au_ssize, au_scale; + AVCodecContext *stream, *video_enc; + offset_t list1, list2, strh, strf; + + avi->last_stream_index=1; + + /* header list */ + avi->riff_id = 0; + list1 = avi_start_new_riff(avi, pb, "AMV ", "hdrl"); + + /* avi header */ + put_tag(pb, "amvh"); + put_le32(pb, 14 * 4); + bitrate = 0; + + video_enc = NULL; + for(n=0;n<s->nb_streams;n++) { + stream = s->streams[n]->codec; + bitrate += stream->bit_rate; + if (stream->codec_type == CODEC_TYPE_VIDEO) + video_enc = stream; + } + + nb_frames = 0; + + if(video_enc){ + put_le32(pb, (uint32_t)(INT64_C(1000000) * video_enc->time_base.num / video_enc->time_base.den)); + } else { + put_le32(pb, 0); + } + put_le32(pb, bitrate / 8); /* XXX: not quite exact */ + put_le32(pb, 0); /* padding */ + if (url_is_streamed(pb)) + put_le32(pb, AMVF_TRUSTCKTYPE | AMVF_ISINTERLEAVED); /* flags */ + else + put_le32(pb, AMVF_TRUSTCKTYPE | AMVF_HASINDEX | AMVF_ISINTERLEAVED); /* flags */ + avi->frames_hdr_all = url_ftell(pb); /* remember this offset to fill later */ + put_le32(pb, nb_frames); /* nb frames, filled later */ + put_le32(pb, 0); /* initial frame */ + put_le32(pb, s->nb_streams); /* nb streams */ + put_le32(pb, 1024 * 1024); /* suggested buffer size */ + if(video_enc){ + put_le32(pb, video_enc->width); + put_le32(pb, video_enc->height); + } else { + put_le32(pb, 0); + put_le32(pb, 0); + } + + put_le32(pb, video_enc->time_base.den); // edited from AVI: framerate instead of reserved + put_le32(pb, 1); // This is always 1 in a real AMV + put_le32(pb, 0); /* reserved */ + + avi->seconds = url_ftell(pb); /* remember this offset to fill later */ + put_byte(pb,0); + avi->minutes = url_ftell(pb); /* remember this offset to fill later */ + put_byte(pb,0); + avi->hours = url_ftell(pb); /* remember this offset to fill later */ + put_le16(pb, 0); // duration minutes (filled in later) + + /* stream list */ + for(i=0;i<n;i++) { + list2 = start_tag(pb, "LIST"); + put_tag(pb, "strl"); + + stream = s->streams[i]->codec; + + /* stream generic header */ + strh = start_tag(pb, "strh"); + switch(stream->codec_type) { + case CODEC_TYPE_VIDEO: put_tag(pb, "vids"); break; + case CODEC_TYPE_AUDIO: put_tag(pb, "auds"); break; + } + if(stream->codec_type == CODEC_TYPE_VIDEO) + put_le32(pb, stream->codec_tag); + else + put_le32(pb, 1); + put_le32(pb, 0); /* flags */ + put_le16(pb, 0); /* priority */ + put_le16(pb, 0); /* language */ + put_le32(pb, 0); /* initial frame */ + + if(stream->codec_type==CODEC_TYPE_AUDIO && i==1) + { + au_ssize=2; + au_scale=s->streams[0]->time_base.num; + au_byterate=s->streams[0]->time_base.den; + }else + ff_parse_specific_params(stream, &au_byterate, &au_ssize, &au_scale); + + put_le32(pb, au_scale); /* scale */ + put_le32(pb, au_byterate); /* rate */ + av_set_pts_info(s->streams[i], 64, au_scale, au_byterate); + + put_le32(pb, 0); /* start */ + avi->frames_hdr_strm[i] = url_ftell(pb); /* remember this offset to fill later */ + if (url_is_streamed(pb)) + put_le32(pb, AMV_MAX_RIFF_SIZE); /* FIXME: this may be broken, but who cares */ + else + put_le32(pb, 0); /* length, XXX: filled later */ + + /* suggested buffer size */ //FIXME set at the end to largest chunk + if(stream->codec_type == CODEC_TYPE_VIDEO) { + put_le32(pb, 1024 * 1024); + put_le32(pb, -1); /* quality */ + } else if(stream->codec_type == CODEC_TYPE_AUDIO) { + //put_le32(pb, 12 * 1024); + } else + put_le32(pb, 0); + put_le32(pb, au_ssize); /* sample size */ + put_le32(pb, 0); + put_le16(pb, stream->width); + put_le16(pb, stream->height); + end_tag(pb, strh); + + if(stream->codec_type != CODEC_TYPE_DATA){ + strf = start_tag(pb, "strf"); + switch(stream->codec_type) { + case CODEC_TYPE_VIDEO: + put_le32(pb, 0); + put_le32(pb, 0); + put_le32(pb, 0); + put_le32(pb, 0); + put_le32(pb, 0); + put_le32(pb, 0); + put_le32(pb, 0); + put_le32(pb, 0); + put_le32(pb, 0); + break; + case CODEC_TYPE_AUDIO: + if (put_wav_header(pb, stream) < 0) { + av_free(avi); + return -1; + } + put_le32(pb, 0); + break; + default: + return -1; + } + end_tag(pb, strf); + } + + end_tag(pb, list2); + } + + end_tag(pb, list1); + + avi->movi_list = start_tag(pb, "LIST"); + put_tag(pb, "movi"); + + put_flush_packet(pb); + + /* + HACK!!! + Set correct frame_size for audio stream + */ + if(s->nb_streams > 1 && s->streams[1]->codec->codec_type == CODEC_TYPE_AUDIO) { + s->streams[1]->codec->frame_size=av_rescale( + s->streams[1]->codec->sample_rate, + s->streams[0]->codec->time_base.num, + s->streams[0]->codec->time_base.den); + } + + return 0; +} + + +static int avi_write_packet(AVFormatContext *s, AVPacket *pkt) +{ + AMVContext *avi = s->priv_data; + ByteIOContext *pb = &s->pb; + unsigned char tag[5]; + unsigned int flags=0; + const int stream_index= pkt->stream_index; + AVCodecContext *enc= s->streams[stream_index]->codec; + int size= pkt->size; + +// av_log(s, AV_LOG_DEBUG, "%"PRId64" %d %d\n", pkt->dts, avi->packet_count[stream_index], stream_index); + while(enc->block_align==0 && pkt->dts != AV_NOPTS_VALUE && pkt->dts > avi->packet_count[stream_index]){ + AVPacket empty_packet; + + av_init_packet(&empty_packet); + empty_packet.size= 0; + empty_packet.data= NULL; + empty_packet.stream_index= stream_index; + avi_write_packet(s, &empty_packet); +// av_log(s, AV_LOG_DEBUG, "dup %"PRId64" %d\n", pkt->dts, avi->packet_count[stream_index]); + } + avi->packet_count[stream_index]++; + + avi_stream2fourcc(&tag[0], stream_index, enc->codec_type); + if(pkt->flags&PKT_FLAG_KEY) + flags = 0x10; + if (enc->codec_type == CODEC_TYPE_AUDIO) { + avi->audio_strm_length[stream_index] += size; + } + + put_buffer(pb, tag, 4); + put_le32(pb, size); + put_buffer(pb, pkt->data, size); + //Data in AMV files are not aligned by 2 bytes +// if (size & 1) put_byte(pb, 0); + + put_flush_packet(pb); + return 0; +} + +static int avi_write_trailer(AVFormatContext *s) +{ + AMVContext *avi = s->priv_data; + ByteIOContext *pb = &s->pb; + int res = 0; + + if (!url_is_streamed(pb)){ + if (avi->riff_id == 1) { + end_tag(pb, avi->movi_list); + put_tag(pb, "AMV_END_"); // Added by Tom from AMV compatibility + end_tag(pb, avi->riff_start); + } + } + avi_write_counters(s, avi->riff_id); + put_flush_packet(pb); + + return res; +} + +static void amv_queue_packet(AVPacket *pkt, AVPacketList** ppktl){ + AVPacketList* pktl, **next_point; + + pktl = av_mallocz(sizeof(AVPacketList)); + pktl->pkt= *pkt; + +// assert(pkt->destruct != av_destruct_packet); //FIXME + + if(pkt->destruct == av_destruct_packet) + pkt->destruct= NULL; // non shared -> must keep original from being freed + else + av_dup_packet(&pktl->pkt); //shared -> must dup + + next_point = ppktl; + while(*next_point){ + next_point= &(*next_point)->next; + } + pktl->next= *next_point; + *next_point= pktl; +} + +static AVPacket amv_dequeue_packet(AVPacketList** ppktl){ + AVPacketList* pktl; + AVPacket pkt; + + pktl=*ppktl; + *ppktl=pktl->next; + pkt=pktl->pkt; + av_freep(&pktl); + return pkt; +} + +static int amv_interleave_packet(struct AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush) +{ + AVPacketList *pktl; + AMVContext* amv=s->priv_data; + + if(pkt) + amv_queue_packet(pkt,&s->packet_buffer); + + if(s->packet_buffer && s->packet_buffer->pkt.stream_index!=amv->last_stream_index){ + *out=amv_dequeue_packet(&s->packet_buffer); + amv->last_stream_index=out->stream_index; + return 1; + } + pktl= s->packet_buffer; + while(pktl && pktl->next){ + if(pktl->next->pkt.stream_index!=amv->last_stream_index) + break; + pktl=pktl->next; + } + + if(pktl && pktl->next){ + *out=amv_dequeue_packet(&pktl->next); + amv->last_stream_index=out->stream_index; + return 1; + }else{ + av_init_packet(out); + return 0; + } +} + +AVOutputFormat amv_muxer = { + "amv", + "amv format", + "video/amv", + "amv", + sizeof(AMVContext), + CODEC_ID_ADPCM_IMA_AMV, + CODEC_ID_AMV, + avi_write_header, + avi_write_packet, + avi_write_trailer, + .interleave_packet=amv_interleave_packet, + .codec_tag= (const AVCodecTag*[]){codec_bmp_tags, codec_wav_tags, 0}, +}; +#endif //CONFIG_AMV_MUXER diff -uNr ffmpeg.orig/libavformat/amv.h ffmpeg/libavformat/amv.h --- ffmpeg.orig/libavformat/amv.h 1970-01-01 01:00:00.000000000 +0100 +++ ffmpeg/libavformat/amv.h 2007-12-26 19:55:58.000000000 +0100 @@ -0,0 +1,39 @@ +/* + * copyright (c) 2001 Fabrice Bellard + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef FFMPEG_AMV_H +#define FFMPEG_AMV_H + +#include "avcodec.h" + +#define AMVF_HASINDEX 0x00000010 // Index at end of file? +#define AMVF_MUSTUSEINDEX 0x00000020 +#define AMVF_ISINTERLEAVED 0x00000100 +#define AMVF_TRUSTCKTYPE 0x00000800 // Use CKType to find key frames? +#define AMVF_WASCAPTUREFILE 0x00010000 +#define AMVF_COPYRIGHTED 0x00020000 + +#define AMV_MAX_RIFF_SIZE 0x40000000LL +#define AMV_MASTER_INDEX_SIZE 256 + +/* index flags */ +#define AMVIF_INDEX 0x10 + +#endif /* FFMPEG_AMV_H */ diff -uNr ffmpeg.orig/libavformat/Makefile ffmpeg/libavformat/Makefile --- ffmpeg.orig/libavformat/Makefile 2007-11-24 15:05:20.000000000 +0100 +++ ffmpeg/libavformat/Makefile 2007-12-26 19:55:58.000000000 +0100 @@ -13,12 +13,15 @@ # muxers/demuxers OBJS-$(CONFIG_AAC_DEMUXER) += raw.o OBJS-$(CONFIG_AC3_DEMUXER) += raw.o +OBJS-$(CONFIG_ACT_DEMUXER) += act.o +OBJS-$(CONFIG_ACT_MUXER) += act.o OBJS-$(CONFIG_AC3_MUXER) += raw.o OBJS-$(CONFIG_ADTS_MUXER) += adtsenc.o OBJS-$(CONFIG_AIFF_DEMUXER) += aiff.o riff.o raw.o OBJS-$(CONFIG_AIFF_MUXER) += aiff.o riff.o OBJS-$(CONFIG_AMR_DEMUXER) += amr.o OBJS-$(CONFIG_AMR_MUXER) += amr.o +OBJS-$(CONFIG_AMV_MUXER) += amvenc.o OBJS-$(CONFIG_APC_DEMUXER) += apc.o OBJS-$(CONFIG_APE_DEMUXER) += ape.o OBJS-$(CONFIG_ASF_DEMUXER) += asf.o asfcrypt.o riff.o diff -uNr ffmpeg.orig/libavformat/riff.c ffmpeg/libavformat/riff.c --- ffmpeg.orig/libavformat/riff.c 2007-10-27 13:18:05.000000000 +0200 +++ ffmpeg/libavformat/riff.c 2007-12-26 19:55:58.000000000 +0100 @@ -188,6 +188,7 @@ { CODEC_ID_PCM_MULAW, 0x07 }, { CODEC_ID_ADPCM_MS, 0x02 }, { CODEC_ID_ADPCM_IMA_WAV, 0x11 }, + { CODEC_ID_ADPCM_IMA_AMV, 0x01 }, { CODEC_ID_ADPCM_YAMAHA, 0x20 }, { CODEC_ID_ADPCM_G726, 0x45 }, { CODEC_ID_ADPCM_IMA_DK4, 0x61 }, /* rogue format number */